• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 LIBPANDABASE_UTILS_BIT_MEMORY_STREAM_H
17 #define LIBPANDABASE_UTILS_BIT_MEMORY_STREAM_H
18 
19 #include "utils/bit_memory_region.h"
20 #include "utils/bit_utils.h"
21 
22 #include <array>
23 #include <ios>
24 
25 namespace panda {
26 
27 template <typename Container>
28 class BitMemoryStreamOut {
29 public:
BitMemoryStreamOut(Container * data)30     explicit BitMemoryStreamOut(Container *data) : BitMemoryStreamOut(data, 0) {}
BitMemoryStreamOut(Container * data,size_t offset)31     BitMemoryStreamOut(Container *data, size_t offset) : data_(data), offset_(offset) {}
32 
EnsureSpace(size_t length)33     void EnsureSpace(size_t length)
34     {
35         data_->resize(RoundUp(BitsToBytesRoundUp(offset_ + length), sizeof(uint32_t)));
36     }
37 
Write(size_t value,size_t length)38     void Write(size_t value, size_t length)
39     {
40         if (length != 0) {
41             ASSERT(length <= (sizeof(value) * BITS_PER_BYTE));
42             EnsureSpace(length);
43             BitMemoryRegion region(data_->data(), offset_, length);
44             region.Write(value, 0, length);
45             offset_ += length;
46         }
47     }
48 
Write(uint32_t * ptr,size_t payload_length,size_t length)49     void Write(uint32_t *ptr, size_t payload_length, size_t length)
50     {
51         ASSERT(payload_length <= length);
52         if (payload_length != 0) {
53             static constexpr size_t bits_per_word = BITS_PER_UINT32;
54             EnsureSpace(length);
55             BitMemoryRegion region(data_->data(), offset_, length);
56             size_t i = 0;
57             for (; i < payload_length / bits_per_word; i++) {
58                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
59                 region.Write(ptr[i], i * bits_per_word, bits_per_word);
60             }
61             size_t remaining_size = payload_length % bits_per_word;
62             if (remaining_size != 0) {
63                 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
64                 region.Write(ptr[i], i * bits_per_word, payload_length % bits_per_word);
65             }
66         }
67         offset_ += length;
68     }
69 
70     virtual ~BitMemoryStreamOut() = default;
71 
72     NO_COPY_SEMANTIC(BitMemoryStreamOut);
73     NO_MOVE_SEMANTIC(BitMemoryStreamOut);
74 
75 private:
76     Container *data_ {nullptr};
77     size_t offset_ {0};
78 };
79 
80 class BitMemoryStreamIn : private BitMemoryRegion<const uint8_t> {
81 public:
82     using BitMemoryRegion::BitMemoryRegion;
83 
BitMemoryStreamIn(const uint8_t * data)84     explicit BitMemoryStreamIn(const uint8_t *data)
85         : BitMemoryRegion<const uint8_t>(data, std::numeric_limits<uint32_t>::max())
86     {
87     }
88 
89     template <typename T>
Read(size_t length)90     T Read(size_t length)
91     {
92         ASSERT(length <= (sizeof(T) * BITS_PER_BYTE));
93         T res = BitMemoryRegion::Read<T>(0, length);
94         Advance(length);
95         return res;
96     }
97 
ReadRegion(size_t length)98     BitMemoryRegion ReadRegion(size_t length)
99     {
100         auto res = Subregion(0, length);
101         Advance(length);
102         return res;
103     }
104 
105     ~BitMemoryStreamIn() override = default;
106 
107     NO_COPY_SEMANTIC(BitMemoryStreamIn);
108     NO_MOVE_SEMANTIC(BitMemoryStreamIn);
109 };
110 
111 }  // namespace panda
112 
113 #endif  // LIBPANDABASE_UTILS_BIT_MEMORY_STREAM_H
114