106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License.
506f6ba60Sopenharmony_ci * You may obtain a copy of the License at
606f6ba60Sopenharmony_ci *
706f6ba60Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
806f6ba60Sopenharmony_ci *
906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and
1306f6ba60Sopenharmony_ci * limitations under the License.
1406f6ba60Sopenharmony_ci */
1506f6ba60Sopenharmony_ci#include <memory>
1606f6ba60Sopenharmony_ci
1706f6ba60Sopenharmony_ci#include "trace_file_reader.h"
1806f6ba60Sopenharmony_ci#include "common.h"
1906f6ba60Sopenharmony_ci#include "logging.h"
2006f6ba60Sopenharmony_ci
2106f6ba60Sopenharmony_ciusing CharPtr = std::unique_ptr<char>::pointer;
2206f6ba60Sopenharmony_ci
2306f6ba60Sopenharmony_ciTraceFileReader::~TraceFileReader()
2406f6ba60Sopenharmony_ci{
2506f6ba60Sopenharmony_ci    if (stream_.is_open()) {
2606f6ba60Sopenharmony_ci        stream_.close();
2706f6ba60Sopenharmony_ci    }
2806f6ba60Sopenharmony_ci}
2906f6ba60Sopenharmony_ci
3006f6ba60Sopenharmony_ciTraceFileHeader TraceFileReader::GetHeader() const
3106f6ba60Sopenharmony_ci{
3206f6ba60Sopenharmony_ci    return header_;
3306f6ba60Sopenharmony_ci}
3406f6ba60Sopenharmony_ci
3506f6ba60Sopenharmony_cibool TraceFileReader::ValidateHeader()
3606f6ba60Sopenharmony_ci{
3706f6ba60Sopenharmony_ci    return helper_.Validate(header_);
3806f6ba60Sopenharmony_ci}
3906f6ba60Sopenharmony_ci
4006f6ba60Sopenharmony_cibool TraceFileReader::Open(const std::string& path)
4106f6ba60Sopenharmony_ci{
4206f6ba60Sopenharmony_ci    auto retFile = COMMON::CheckNotExistsFilePath(path);
4306f6ba60Sopenharmony_ci    if (!retFile.first) {
4406f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "check file path %s fail", path.c_str());
4506f6ba60Sopenharmony_ci        return false;
4606f6ba60Sopenharmony_ci    }
4706f6ba60Sopenharmony_ci    std::string realPath = retFile.second;
4806f6ba60Sopenharmony_ci    stream_.open(realPath, std::ios_base::in | std::ios_base::binary);
4906f6ba60Sopenharmony_ci    CHECK_TRUE(stream_.is_open(), false, "open %s failed, %d!", realPath.c_str(), errno);
5006f6ba60Sopenharmony_ci
5106f6ba60Sopenharmony_ci    stream_.read(reinterpret_cast<CharPtr>(&header_), sizeof(header_));
5206f6ba60Sopenharmony_ci    CHECK_TRUE(stream_, false, "read header from %s failed!", realPath.c_str());
5306f6ba60Sopenharmony_ci
5406f6ba60Sopenharmony_ci    path_ = realPath;
5506f6ba60Sopenharmony_ci    return true;
5606f6ba60Sopenharmony_ci}
5706f6ba60Sopenharmony_ci
5806f6ba60Sopenharmony_cistatic size_t GetReadPos(std::ifstream& stream)
5906f6ba60Sopenharmony_ci{
6006f6ba60Sopenharmony_ci    return static_cast<size_t>(stream.tellg());
6106f6ba60Sopenharmony_ci}
6206f6ba60Sopenharmony_ci
6306f6ba60Sopenharmony_cilong TraceFileReader::Read(MessageLite& message)
6406f6ba60Sopenharmony_ci{
6506f6ba60Sopenharmony_ci    CHECK_TRUE(stream_.is_open(), 0, "binary file %s not open or open failed!", path_.c_str());
6606f6ba60Sopenharmony_ci    CHECK_TRUE(!stream_.eof(), 0, "no more data in file %s stream", path_.c_str());
6706f6ba60Sopenharmony_ci
6806f6ba60Sopenharmony_ci    uint32_t msgLen = 0;
6906f6ba60Sopenharmony_ci    size_t offset = GetReadPos(stream_);
7006f6ba60Sopenharmony_ci    stream_.read(reinterpret_cast<CharPtr>(&msgLen), sizeof(msgLen));
7106f6ba60Sopenharmony_ci    RETURN_IF(stream_.eof(), 0, "read file end");
7206f6ba60Sopenharmony_ci    CHECK_TRUE(msgLen > 0, 0, "read in file %s msg length: %d", path_.c_str(), msgLen);
7306f6ba60Sopenharmony_ci    CHECK_TRUE(stream_, 0, "read msg length from %s (offset %zu) failed, or no more data!", path_.c_str(), offset);
7406f6ba60Sopenharmony_ci    CHECK_TRUE(helper_.AddSegment(reinterpret_cast<uint8_t*>(&msgLen), sizeof(msgLen)),
7506f6ba60Sopenharmony_ci        0, "Add payload for message length failed!");
7606f6ba60Sopenharmony_ci
7706f6ba60Sopenharmony_ci    std::vector<char> msgData(msgLen);
7806f6ba60Sopenharmony_ci    offset = GetReadPos(stream_);
7906f6ba60Sopenharmony_ci    stream_.read(msgData.data(), msgData.size());
8006f6ba60Sopenharmony_ci    RETURN_IF(stream_.eof(), 0, "read file end");
8106f6ba60Sopenharmony_ci    CHECK_TRUE(stream_, 0, "read msg bytes from %s (offset %zu) failed!", path_.c_str(), offset);
8206f6ba60Sopenharmony_ci    CHECK_TRUE(helper_.AddSegment(reinterpret_cast<uint8_t*>(msgData.data()), msgData.size()),
8306f6ba60Sopenharmony_ci        0, "Add payload for message bytes failed!");
8406f6ba60Sopenharmony_ci
8506f6ba60Sopenharmony_ci    CHECK_TRUE(message.ParseFromArray(msgData.data(), msgData.size()), 0, "ParseFromArray failed!");
8606f6ba60Sopenharmony_ci    return sizeof(msgLen) + msgData.size();
8706f6ba60Sopenharmony_ci}
8806f6ba60Sopenharmony_ci
8906f6ba60Sopenharmony_cilong TraceFileReader::ReadLen()
9006f6ba60Sopenharmony_ci{
9106f6ba60Sopenharmony_ci    CHECK_TRUE(stream_.is_open(), 0, "binary file %s not open or open failed!", path_.c_str());
9206f6ba60Sopenharmony_ci    CHECK_TRUE(!stream_.eof(), 0, "no more data in file %s stream", path_.c_str());
9306f6ba60Sopenharmony_ci
9406f6ba60Sopenharmony_ci    uint32_t dataLen = 0;
9506f6ba60Sopenharmony_ci    stream_.read(reinterpret_cast<CharPtr>(&dataLen), sizeof(dataLen));
9606f6ba60Sopenharmony_ci    RETURN_IF(stream_.eof(), 0, "read file end");
9706f6ba60Sopenharmony_ci    CHECK_TRUE(dataLen > 0, 0, "read in file %s data length: %d", path_.c_str(), dataLen);
9806f6ba60Sopenharmony_ci    CHECK_TRUE(stream_, 0, "read data length from file %s (offset %zu) failed!", path_.c_str(), GetReadPos(stream_));
9906f6ba60Sopenharmony_ci    CHECK_TRUE(helper_.AddSegment(reinterpret_cast<uint8_t*>(&dataLen), sizeof(dataLen)),
10006f6ba60Sopenharmony_ci        0, "Add payload for data length failed!");
10106f6ba60Sopenharmony_ci    return dataLen;
10206f6ba60Sopenharmony_ci}
10306f6ba60Sopenharmony_ci
10406f6ba60Sopenharmony_cibool TraceFileReader::ReadData(uint8_t buffer[], uint32_t bufferSize)
10506f6ba60Sopenharmony_ci{
10606f6ba60Sopenharmony_ci    CHECK_TRUE(stream_.is_open(), false, "binary file %s not open or open failed!", path_.c_str());
10706f6ba60Sopenharmony_ci    CHECK_TRUE(!stream_.eof(), false, "no more data in file %s stream", path_.c_str());
10806f6ba60Sopenharmony_ci
10906f6ba60Sopenharmony_ci    stream_.read(reinterpret_cast<CharPtr>(buffer), bufferSize);
11006f6ba60Sopenharmony_ci    RETURN_IF(stream_.eof(), false, "read file end. read data bytes from %s failed! (offset %zu)",
11106f6ba60Sopenharmony_ci              path_.c_str(), GetReadPos(stream_));
11206f6ba60Sopenharmony_ci    CHECK_TRUE(stream_, false, "read data bytes from %s (offset %zu) failed!", path_.c_str(), GetReadPos(stream_));
11306f6ba60Sopenharmony_ci    CHECK_TRUE(helper_.AddSegment(buffer, bufferSize), false, "Add payload for data bytes failed!");
11406f6ba60Sopenharmony_ci    return true;
11506f6ba60Sopenharmony_ci}
116