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