xref: /developtools/hdc/src/common/decompress.cpp (revision cc290419)
1/*
2 * Copyright (C) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include "decompress.h"
16
17#include <sstream>
18#include <fstream>
19#include <optional>
20#include <iostream>
21
22namespace Hdc {
23bool Decompress::DecompressToLocal(std::string decPath)
24{
25    if (!CheckPath(decPath)) {
26        return false;
27    }
28    uint8_t buff[HEADER_LEN];
29    std::ifstream inFile(tarPath);
30    std::optional<Entry> entry = std::nullopt;
31    while (true) {
32        inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
33        auto readcnt = inFile.gcount();
34        if (readcnt == 0) {
35            break;
36        }
37        if (inFile.fail() || readcnt != HEADER_LEN) {
38            WRITE_LOG(LOG_FATAL, "read file error");
39            break;
40        }
41        entry = Entry(buff, HEADER_LEN);
42        if (!entry.value().CopyPayload(decPath, inFile)) {
43            entry = std::nullopt;
44            break;
45        }
46        entry = std::nullopt;
47        continue;
48    }
49    inFile.close();
50    return true;
51}
52
53bool Decompress::CheckPath(std::string decPath)
54{
55    uv_fs_t req;
56    int rc = uv_fs_lstat(nullptr, &req, tarPath.c_str(), nullptr);
57    uv_fs_req_cleanup(&req);
58    if (rc != 0 || !(req.statbuf.st_mode & S_IFREG)) {
59        WRITE_LOG(LOG_FATAL, "%s not exist, or not file", tarPath.c_str());
60        return false;
61    }
62    auto fileSize = req.statbuf.st_size;
63    if (fileSize == 0 || fileSize % HEADER_LEN != 0) {
64        WRITE_LOG(LOG_FATAL, "file is not tar %s", tarPath.c_str());
65        return false;
66    }
67    rc = uv_fs_lstat(nullptr, &req, decPath.c_str(), nullptr);
68    uv_fs_req_cleanup(&req);
69    if (rc == 0) {
70        if (req.statbuf.st_mode & S_IFREG) {
71            WRITE_LOG(LOG_FATAL, "path is exist, and path not dir %s", decPath.c_str());
72            return false;
73        }
74    } else {
75        std::string estr;
76        bool b = Base::TryCreateDirectory(decPath, estr);
77        if (!b) {
78            WRITE_LOG(LOG_FATAL, "mkdir failed decPath:%s estr:%s", decPath.c_str(), estr.c_str());
79            return false;
80        }
81    }
82    return true;
83}
84}