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 RENDER_PROFILER_APPLICATION 29 #include <securec.h> 30 31 #include "rs_profiler_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 HRPE("FileArchive: Cannot open '%s' for %s", path.data(), (Reader ? "reading" : "writing")); 157 } 158 } 159 ~FileArchive()160 ~FileArchive() override 161 { 162 if (!external_) { 163 Utils::FileClose(file_); 164 } 165 } 166 167 protected: Read(void * data,size_t size)168 void Read(void* data, size_t size) override 169 { 170 Utils::FileRead(file_, data, size); 171 } 172 Write(const void * data,size_t size)173 void Write(const void* data, size_t size) override 174 { 175 Utils::FileWrite(file_, data, size); 176 } 177 178 protected: 179 FILE* file_ = nullptr; 180 bool external_ = false; 181 }; 182 183 using FileReader = FileArchive<true>; 184 using FileWriter = FileArchive<false>; 185 186 // Stream archive 187 template<bool Reader> 188 class StringStreamArchive final : public Archive { 189 public: StringStreamArchive(const std::stringstream & stream)190 explicit StringStreamArchive(const std::stringstream& stream) 191 : Archive(Reader), stream_(const_cast<std::stringstream&>(stream)) 192 {} 193 194 protected: Read(void * data,size_t size)195 void Read(void* data, size_t size) override 196 { 197 stream_.read(reinterpret_cast<char*>(data), size); 198 } 199 Write(const void * data,size_t size)200 void Write(const void* data, size_t size) override 201 { 202 stream_.write(reinterpret_cast<const char*>(data), size); 203 } 204 205 private: 206 std::stringstream& stream_; 207 }; 208 209 using StringStreamReader = StringStreamArchive<true>; 210 using StringStreamWriter = StringStreamArchive<false>; 211 212 } // namespace OHOS::Rosen 213 214 #endif // RS_PROFILER_ARCHIVE_H