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 16 #ifndef RS_PROFILER_ARCHIVE_H 17 #define RS_PROFILER_ARCHIVE_H 18 19 #include <cstring> 20 #include <filesystem> 21 #include <iostream> 22 #include <sstream> 23 #include <string> 24 #include <vector> 25 26 #include "rs_profiler_utils.h" 27 28 #ifndef REPLAY_TOOL_CLIENT 29 #include <securec.h> 30 31 #include "platform/common/rs_log.h" 32 #else 33 #include "rs_adapt.h" 34 #endif 35 36 namespace OHOS::Rosen { 37 38 class RSB_EXPORT Archive { 39 public: IsReading()40 bool IsReading() const 41 { 42 return isReading_; 43 } 44 45 void Serialize(char& value); 46 void Serialize(float& value); 47 void Serialize(double& value); 48 49 void Serialize(int8_t& value); 50 void Serialize(int16_t& value); 51 void Serialize(int32_t& value); 52 void Serialize(int64_t& value); 53 54 void Serialize(uint8_t& value); 55 void Serialize(uint16_t& value); 56 void Serialize(uint32_t& value); 57 void Serialize(uint64_t& value); 58 59 void Serialize(std::string& value); 60 61 template<typename T> Serialize(std::vector<T> & vector)62 void Serialize(std::vector<T>& vector) 63 { 64 SerializeVectorBase(vector); 65 Serialize(vector.data(), vector.size()); 66 } 67 68 template<typename T> Serialize(std::vector<T> & vector,void (* serializer)(Archive &,T &))69 void Serialize(std::vector<T>& vector, void (*serializer)(Archive&, T&)) 70 { 71 if (!serializer) { 72 return; 73 } 74 75 SerializeVectorBase(vector); 76 for (T& value : vector) { 77 serializer(*this, value); 78 } 79 } 80 81 template<typename T> SerializeNonFlat(std::vector<T> & vector)82 void SerializeNonFlat(std::vector<T>& vector) 83 { 84 SerializeVectorBase(vector); 85 for (T& value : vector) { 86 value.Serialize(*this); 87 } 88 } 89 90 void Serialize(void* data, size_t size); 91 92 protected: Archive(bool reader)93 explicit Archive(bool reader) : isReading_(reader) {} 94 95 virtual ~Archive() = default; 96 97 template<typename T> SerializeVectorBase(std::vector<T> & vector)98 void SerializeVectorBase(std::vector<T>& vector) 99 { 100 size_t size = vector.size(); 101 Serialize(size); 102 103 if (IsReading()) { 104 vector.resize(size); 105 } 106 } 107 108 virtual void Read(void* data, size_t size) = 0; 109 virtual void Write(const void* data, size_t size) = 0; 110 111 private: 112 bool isReading_ = true; 113 }; 114 115 // Data archives 116 template<bool Reader> 117 class DataArchive final : public Archive { 118 public: DataArchive(const std::vector<char> & data)119 explicit DataArchive(const std::vector<char>& data) : Archive(Reader), data_(const_cast<std::vector<char>&>(data)) 120 {} 121 122 protected: Read(void * data,size_t size)123 void Read(void* data, size_t size) override 124 { 125 if ((offset_ + size <= data_.size()) && Utils::Move(data, size, data_.data() + offset_, size)) { 126 offset_ += size; 127 } 128 } 129 Write(const void * data,size_t size)130 void Write(const void* data, size_t size) override 131 { 132 data_.resize(data_.size() + size); 133 if (Utils::Move(data_.data() + offset_, size, data, size)) { 134 offset_ += size; 135 } 136 } 137 138 protected: 139 std::vector<char>& data_; 140 size_t offset_ = 0; 141 }; 142 143 using DataReader = DataArchive<true>; 144 using DataWriter = DataArchive<false>; 145 146 // File archives 147 template<bool Reader> 148 class FileArchive final : public Archive { 149 public: FileArchive(FILE * file)150 explicit FileArchive(FILE* file) : Archive(Reader), file_(file), external_(true) {} 151 FileArchive(const std::string & path)152 explicit FileArchive(const std::string& path) : Archive(Reader) 153 { 154 file_ = Utils::FileOpen(path, Reader ? "rb" : "wb"); 155 if (!file_) { 156 RS_LOGE("FileArchive: File %s cannot be opened for %s", path.data(), // NOLINT 157 (Reader ? "reading" : "writing")); 158 } 159 } 160 ~FileArchive()161 ~FileArchive() override 162 { 163 if (!external_) { 164 Utils::FileClose(file_); 165 } 166 } 167 168 protected: Read(void * data,size_t size)169 void Read(void* data, size_t size) override 170 { 171 Utils::FileRead(file_, data, size); 172 } 173 Write(const void * data,size_t size)174 void Write(const void* data, size_t size) override 175 { 176 Utils::FileWrite(file_, data, size); 177 } 178 179 protected: 180 FILE* file_ = nullptr; 181 bool external_ = false; 182 }; 183 184 using FileReader = FileArchive<true>; 185 using FileWriter = FileArchive<false>; 186 187 // Stream archive 188 template<bool Reader> 189 class StringStreamArchive final : public Archive { 190 public: StringStreamArchive(const std::stringstream & stream)191 explicit StringStreamArchive(const std::stringstream& stream) 192 : Archive(Reader), stream_(const_cast<std::stringstream&>(stream)) 193 {} 194 195 protected: Read(void * data,size_t size)196 void Read(void* data, size_t size) override 197 { 198 stream_.read(reinterpret_cast<char*>(data), size); 199 } 200 Write(const void * data,size_t size)201 void Write(const void* data, size_t size) override 202 { 203 stream_.write(reinterpret_cast<const char*>(data), size); 204 } 205 206 private: 207 std::stringstream& stream_; 208 }; 209 210 using StringStreamReader = StringStreamArchive<true>; 211 using StringStreamWriter = StringStreamArchive<false>; 212 213 } // namespace OHOS::Rosen 214 215 #endif // RS_PROFILER_ARCHIVE_H