1 /*
2  * Copyright (c) 2021-2022 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 FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_BYTE_BUFFER_OPERATOR_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_BYTE_BUFFER_OPERATOR_H
18 
19 #include <cstdint>
20 #include <map>
21 #include <set>
22 #include <string>
23 #include <vector>
24 
25 #include "base/log/log.h"
26 #include "base/utils/noncopyable.h"
27 
28 namespace OHOS::Ace::Framework {
29 
30 class ByteBufferReader final {
31 public:
ByteBufferReader(const std::vector<uint8_t> & buffer)32     explicit ByteBufferReader(const std::vector<uint8_t>& buffer) : buffer_(buffer) {}
33     ~ByteBufferReader() = default;
34 
ReadData(uint8_t & value)35     bool ReadData(uint8_t& value) const
36     {
37         return ReadValue(value);
38     }
ReadData(int32_t & value)39     bool ReadData(int32_t& value) const
40     {
41         return ReadValue(value);
42     }
ReadData(int64_t & value)43     bool ReadData(int64_t& value) const
44     {
45         return ReadValue(value);
46     }
ReadData(double & value)47     bool ReadData(double& value) const
48     {
49         return ReadValue(value);
50     }
ReadData(std::string & value)51     bool ReadData(std::string& value) const
52     {
53         return ReadArray(value);
54     }
55 
ReadData(std::vector<int8_t> & dst)56     bool ReadData(std::vector<int8_t>& dst) const
57     {
58         return ReadArray(dst);
59     }
ReadData(std::vector<int16_t> & dst)60     bool ReadData(std::vector<int16_t>& dst) const
61     {
62         return ReadArray(dst);
63     }
ReadData(std::vector<int32_t> & dst)64     bool ReadData(std::vector<int32_t>& dst) const
65     {
66         return ReadArray(dst);
67     }
68 
69     bool ReadData(std::map<std::string, std::string>& dst) const;
70     bool ReadData(std::set<std::string>& dst) const;
71 
72 private:
73     template<class T>
ReadValue(T & value)74     bool ReadValue(T& value) const
75     {
76         if (readPos_ + sizeof(T) > buffer_.size()) {
77             LOGW("Exceed buffer size, readPos = %{public}u, buffer size = %{public}zu", readPos_, buffer_.size());
78             return false;
79         }
80         value = *reinterpret_cast<const T*>(buffer_.data() + readPos_);
81         readPos_ += sizeof(T);
82         return true;
83     }
84 
85     template<class T>
ReadArray(T & dst)86     bool ReadArray(T& dst) const
87     {
88         int32_t length = -1;
89         if (!ReadData(length) || length < 0 ||
90             readPos_ + static_cast<uint32_t>(sizeof(typename T::value_type) * length) > buffer_.size()) {
91             LOGW("Could not read array length or array length is invalid");
92             return false;
93         }
94         auto data = reinterpret_cast<const typename T::value_type*>(buffer_.data() + readPos_);
95         dst.assign(data, data + length);
96         readPos_ += static_cast<uint32_t>(sizeof(typename T::value_type) * length);
97         return true;
98     }
99 
100     const std::vector<uint8_t>& buffer_;
101     mutable uint32_t readPos_ = 0;
102 
103     ACE_DISALLOW_COPY_AND_MOVE(ByteBufferReader);
104 };
105 
106 class ByteBufferWriter final {
107 public:
ByteBufferWriter(std::vector<uint8_t> & buffer)108     ByteBufferWriter(std::vector<uint8_t>& buffer) : buffer_(buffer) {}
109     ~ByteBufferWriter() = default;
110 
WriteData(uint8_t value)111     void WriteData(uint8_t value)
112     {
113         WriteValue(value);
114     }
WriteData(int32_t value)115     void WriteData(int32_t value)
116     {
117         WriteValue(value);
118     }
WriteData(int64_t value)119     void WriteData(int64_t value)
120     {
121         WriteValue(value);
122     }
WriteData(double value)123     void WriteData(double value)
124     {
125         WriteValue(value);
126     }
WriteData(const std::string & src)127     void WriteData(const std::string& src)
128     {
129         WriteArray(src);
130     }
131 
WriteData(const std::vector<int8_t> & src)132     void WriteData(const std::vector<int8_t>& src)
133     {
134         WriteArray(src);
135     }
WriteData(const std::vector<int16_t> & src)136     void WriteData(const std::vector<int16_t>& src)
137     {
138         WriteArray(src);
139     }
WriteData(const std::vector<int32_t> & src)140     void WriteData(const std::vector<int32_t>& src)
141     {
142         WriteArray(src);
143     }
144 
145     void WriteData(const std::map<std::string, std::string>& mapValue);
146     void WriteData(const std::set<std::string>& setValue);
147 
148 private:
149     template<class T>
WriteValue(T value)150     void WriteValue(T value)
151     {
152         auto data = reinterpret_cast<uint8_t*>(&value);
153         buffer_.insert(buffer_.end(), data, data + sizeof(T));
154     }
155 
156     template<class T>
WriteArray(const T & array)157     void WriteArray(const T& array)
158     {
159         WriteData(static_cast<int32_t>(array.size()));
160         auto data = reinterpret_cast<const uint8_t*>(array.data());
161         buffer_.insert(buffer_.end(), data, data + sizeof(typename T::value_type) * array.size());
162     }
163 
164     std::vector<uint8_t>& buffer_;
165 
166     ACE_DISALLOW_COPY_AND_MOVE(ByteBufferWriter);
167 };
168 
169 } // namespace OHOS::Ace::Framework
170 
171 #endif // FOUNDATION_ACE_FRAMEWORKS_BRIDGE_CODEC_BYTE_BUFFER_OPERATOR_H
172