1
+ /*
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ #include " MapBuffer.h"
9
+
10
+ using namespace facebook ::react;
11
+
12
+ namespace facebook {
13
+ namespace react {
14
+
15
+ // TODO T83483191: Extend MapBuffer C++ implementation to support basic random
16
+ // access
17
+ MapBuffer::MapBuffer (std::vector<uint8_t > data) : bytes_(std::move(data)) {
18
+ count_ = 0 ;
19
+ memcpy (
20
+ reinterpret_cast <uint8_t *>(&count_),
21
+ bytes_.data () + HEADER_COUNT_OFFSET,
22
+ UINT16_SIZE);
23
+
24
+ // TODO T83483191: extract memcpy calls into an inline function to simplify
25
+ // the code
26
+ uint32_t dataSize;
27
+ memcpy (
28
+ reinterpret_cast <uint8_t *>(&dataSize),
29
+ reinterpret_cast <const uint8_t *>(bytes_.data () + HEADER_BUFFER_SIZE_OFFSET),
30
+ INT_SIZE);
31
+
32
+ if (dataSize != bytes_.size ()) {
33
+ LOG (ERROR) << " Error: Data size does not match, expected " << dataSize
34
+ << " found: " << bytes_.size ();
35
+ abort ();
36
+ }
37
+ }
38
+
39
+ int32_t MapBuffer::getInt (Key key) const {
40
+ int32_t value = 0 ;
41
+ memcpy (
42
+ reinterpret_cast <uint8_t *>(&value),
43
+ reinterpret_cast <const uint8_t *>(bytes_.data () + getValueOffset (key)),
44
+ INT_SIZE);
45
+ return value;
46
+ }
47
+
48
+ bool MapBuffer::getBool (Key key) const {
49
+ return getInt (key) != 0 ;
50
+ }
51
+
52
+ double MapBuffer::getDouble (Key key) const {
53
+ // TODO T83483191: extract this code into a "template method" and reuse it for
54
+ // other types
55
+ double value = 0 ;
56
+ memcpy (
57
+ reinterpret_cast <uint8_t *>(&value),
58
+ reinterpret_cast <const uint8_t *>(bytes_.data () + getValueOffset (key)),
59
+ DOUBLE_SIZE);
60
+ return value;
61
+ }
62
+
63
+ int32_t MapBuffer::getDynamicDataOffset () const {
64
+ // The begininig of dynamic data can be calculated as the offset of the next
65
+ // key in the map
66
+ return getKeyOffset (count_);
67
+ }
68
+
69
+ std::string MapBuffer::getString (Key key) const {
70
+ // TODO T83483191:Add checks to verify that offsets are under the boundaries
71
+ // of the map buffer
72
+ int32_t dynamicDataOffset = getDynamicDataOffset ();
73
+ int32_t stringLength = 0 ;
74
+ int32_t offset = getInt (key);
75
+ memcpy (
76
+ reinterpret_cast <uint8_t *>(&stringLength),
77
+ reinterpret_cast <const uint8_t *>(bytes_.data () + dynamicDataOffset + offset),
78
+ INT_SIZE);
79
+
80
+ char *value = new char [stringLength];
81
+
82
+ memcpy (
83
+ reinterpret_cast <char *>(value),
84
+ reinterpret_cast <const uint8_t *>(bytes_.data () + dynamicDataOffset + offset + INT_SIZE),
85
+ stringLength);
86
+
87
+ return std::string (value, 0 , stringLength);
88
+ }
89
+
90
+ MapBuffer MapBuffer::getMapBuffer (Key key) const {
91
+ // TODO T83483191: Add checks to verify that offsets are under the boundaries
92
+ // of the map buffer
93
+ int32_t dynamicDataOffset = getDynamicDataOffset ();
94
+
95
+ int32_t mapBufferLength = 0 ;
96
+ int32_t offset = getInt (key);
97
+ memcpy (
98
+ reinterpret_cast <uint8_t *>(&mapBufferLength),
99
+ reinterpret_cast <const uint8_t *>(bytes_.data () + dynamicDataOffset + offset),
100
+ INT_SIZE);
101
+
102
+ std::vector<uint8_t > value (mapBufferLength);
103
+
104
+ memcpy (
105
+ value.data (),
106
+ bytes_.data () + dynamicDataOffset + offset + INT_SIZE,
107
+ mapBufferLength);
108
+
109
+ return MapBuffer (std::move (value));
110
+ }
111
+
112
+ bool MapBuffer::isNull (Key key) const {
113
+ return getInt (key) == NULL_VALUE;
114
+ }
115
+
116
+ int32_t MapBuffer::getBufferSize () const {
117
+ return bytes_.size ();
118
+ }
119
+
120
+ void MapBuffer::copy (uint8_t *output) const {
121
+ memcpy (output, bytes_.data (), bytes_.size ());
122
+ }
123
+
124
+ uint16_t MapBuffer::getCount () const {
125
+ uint16_t size = 0 ;
126
+
127
+ memcpy (
128
+ reinterpret_cast <uint8_t *>(&size),
129
+ bytes_.data () + HEADER_COUNT_OFFSET,
130
+ UINT16_SIZE);
131
+
132
+ return size;
133
+ }
134
+
135
+
136
+ } // namespace react
137
+ } // namespace facebook
0 commit comments