Skip to content

Commit 57ed0fb

Browse files
ryanlntnfacebook-github-bot
authored andcommitted
MapBuffer long support (#43030)
Summary: This adds support for 64 bit integer (long) values to MapBuffer. Per the wide gamut color [RFC](react-native-community/discussions-and-proposals#738) Android encodes wide gamut colors as long values so we need to update MapBuffer to support 64 bit integers as well. ## Changelog: [ANDROID] [ADDED] - Add 64 bit integer (long) value support to MapBuffer Pull Request resolved: #43030 Test Plan: I've added a test to the MapBuffer test suite. This new API is otherwise currently unused but will be used in subsequent PRs as part of wide gamut color support changes. Reviewed By: mdvacca Differential Revision: D53881809 Pulled By: NickGerleman fbshipit-source-id: 39c20b93493a2609db9f66426640ef5e97d6e1a8
1 parent 8317325 commit 57ed0fb

File tree

9 files changed

+96
-2
lines changed

9 files changed

+96
-2
lines changed

packages/react-native/ReactAndroid/api/ReactAndroid.api

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,7 @@ public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer :
17931793
public abstract fun getDouble (I)D
17941794
public abstract fun getInt (I)I
17951795
public abstract fun getKeyOffset (I)I
1796+
public abstract fun getLong (I)J
17961797
public abstract fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/MapBuffer;
17971798
public abstract fun getMapBufferList (I)Ljava/util/List;
17981799
public abstract fun getString (I)Ljava/lang/String;
@@ -1806,6 +1807,7 @@ public final class com/facebook/react/common/mapbuffer/MapBuffer$DataType : java
18061807
public static final field BOOL Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18071808
public static final field DOUBLE Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18081809
public static final field INT Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
1810+
public static final field LONG Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18091811
public static final field MAP Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18101812
public static final field STRING Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18111813
public static fun valueOf (Ljava/lang/String;)Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
@@ -1817,6 +1819,7 @@ public abstract interface class com/facebook/react/common/mapbuffer/MapBuffer$En
18171819
public abstract fun getDoubleValue ()D
18181820
public abstract fun getIntValue ()I
18191821
public abstract fun getKey ()I
1822+
public abstract fun getLongValue ()J
18201823
public abstract fun getMapBufferValue ()Lcom/facebook/react/common/mapbuffer/MapBuffer;
18211824
public abstract fun getStringValue ()Ljava/lang/String;
18221825
public abstract fun getType ()Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
@@ -1837,6 +1840,7 @@ public final class com/facebook/react/common/mapbuffer/ReadableMapBuffer : com/f
18371840
public fun getDouble (I)D
18381841
public fun getInt (I)I
18391842
public fun getKeyOffset (I)I
1843+
public fun getLong (I)J
18401844
public synthetic fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/MapBuffer;
18411845
public fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/ReadableMapBuffer;
18421846
public fun getMapBufferList (I)Ljava/util/List;
@@ -1859,13 +1863,15 @@ public final class com/facebook/react/common/mapbuffer/WritableMapBuffer : com/f
18591863
public fun getDouble (I)D
18601864
public fun getInt (I)I
18611865
public fun getKeyOffset (I)I
1866+
public fun getLong (I)J
18621867
public fun getMapBuffer (I)Lcom/facebook/react/common/mapbuffer/MapBuffer;
18631868
public fun getMapBufferList (I)Ljava/util/List;
18641869
public fun getString (I)Ljava/lang/String;
18651870
public fun getType (I)Lcom/facebook/react/common/mapbuffer/MapBuffer$DataType;
18661871
public fun iterator ()Ljava/util/Iterator;
18671872
public final fun put (ID)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
18681873
public final fun put (II)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
1874+
public final fun put (IJ)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
18691875
public final fun put (ILcom/facebook/react/common/mapbuffer/MapBuffer;)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
18701876
public final fun put (ILjava/lang/String;)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;
18711877
public final fun put (IZ)Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBuffer.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ public interface MapBuffer : Iterable<MapBuffer.Entry> {
4444
INT,
4545
DOUBLE,
4646
STRING,
47-
MAP
47+
MAP,
48+
LONG
4849
}
4950

5051
/**
@@ -109,6 +110,16 @@ public interface MapBuffer : Iterable<MapBuffer.Entry> {
109110
*/
110111
public fun getInt(key: Int): Int
111112

113+
/**
114+
* Provides parsed [Long] value if the entry for given key exists with [DataType.LONG] type
115+
*
116+
* @param key key to lookup [Long] value for
117+
* @return value associated with the requested key
118+
* @throws IllegalArgumentException if the key doesn't exist
119+
* @throws IllegalStateException if the data type doesn't match
120+
*/
121+
public fun getLong(key: Int): Long
122+
112123
/**
113124
* Provides parsed [Double] value if the entry for given key exists with [DataType.DOUBLE] type
114125
*
@@ -175,6 +186,13 @@ public interface MapBuffer : Iterable<MapBuffer.Entry> {
175186
*/
176187
public val intValue: Int
177188

189+
/**
190+
* Entry value represented as [Long]
191+
*
192+
* @throws IllegalStateException if the data type doesn't match [DataType.LONG]
193+
*/
194+
public val longValue: Long
195+
178196
/**
179197
* Entry value represented as [Double]
180198
*

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,10 @@ public class ReadableMapBuffer : MapBuffer {
115115
return buffer.getInt(bufferPosition)
116116
}
117117

118+
private fun readLongValue(bufferPosition: Int): Long {
119+
return buffer.getLong(bufferPosition)
120+
}
121+
118122
private fun readBooleanValue(bufferPosition: Int): Boolean {
119123
return readIntValue(bufferPosition) == 1
120124
}
@@ -180,6 +184,9 @@ public class ReadableMapBuffer : MapBuffer {
180184
override fun getInt(key: Int): Int =
181185
readIntValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.INT))
182186

187+
override fun getLong(key: Int): Long =
188+
readLongValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.LONG))
189+
183190
override fun getDouble(key: Int): Double =
184191
readDoubleValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.DOUBLE))
185192

@@ -223,6 +230,7 @@ public class ReadableMapBuffer : MapBuffer {
223230
when (entry.type) {
224231
MapBuffer.DataType.BOOL -> builder.append(entry.booleanValue)
225232
MapBuffer.DataType.INT -> builder.append(entry.intValue)
233+
MapBuffer.DataType.LONG -> builder.append(entry.longValue)
226234
MapBuffer.DataType.DOUBLE -> builder.append(entry.doubleValue)
227235
MapBuffer.DataType.STRING -> builder.append(entry.stringValue)
228236
MapBuffer.DataType.MAP -> builder.append(entry.mapBufferValue.toString())
@@ -280,6 +288,12 @@ public class ReadableMapBuffer : MapBuffer {
280288
return readIntValue(bucketOffset + VALUE_OFFSET)
281289
}
282290

291+
override val longValue: Long
292+
get() {
293+
assertType(MapBuffer.DataType.LONG)
294+
return readLongValue(bucketOffset + VALUE_OFFSET)
295+
}
296+
283297
override val booleanValue: Boolean
284298
get() {
285299
assertType(MapBuffer.DataType.BOOL)

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ public class WritableMapBuffer : MapBuffer {
4848
*/
4949
public fun put(key: Int, value: Int): WritableMapBuffer = putInternal(key, value)
5050

51+
/**
52+
* Adds a long value for given key to the MapBuffer.
53+
*
54+
* @param key entry key
55+
* @param value entry value
56+
* @throws IllegalArgumentException if key is out of [UShort] range
57+
*/
58+
public fun put(key: Int, value: Long): WritableMapBuffer = putInternal(key, value)
59+
5160
/**
5261
* Adds a double value for given key to the MapBuffer.
5362
*
@@ -107,6 +116,8 @@ public class WritableMapBuffer : MapBuffer {
107116

108117
override fun getInt(key: Int): Int = verifyValue(key, values.get(key))
109118

119+
override fun getLong(key: Int): Long = verifyValue(key, values.get(key))
120+
110121
override fun getDouble(key: Int): Double = verifyValue(key, values.get(key))
111122

112123
override fun getString(key: Int): String = verifyValue(key, values.get(key))
@@ -128,6 +139,7 @@ public class WritableMapBuffer : MapBuffer {
128139
return when (val value = this) {
129140
is Boolean -> DataType.BOOL
130141
is Int -> DataType.INT
142+
is Long -> DataType.LONG
131143
is Double -> DataType.DOUBLE
132144
is String -> DataType.STRING
133145
is MapBuffer -> DataType.MAP
@@ -153,6 +165,9 @@ public class WritableMapBuffer : MapBuffer {
153165
override val intValue: Int
154166
get() = verifyValue(key, values.valueAt(index))
155167

168+
override val longValue: Long
169+
get() = verifyValue(key, values.valueAt(index))
170+
156171
override val doubleValue: Double
157172
get() = verifyValue(key, values.valueAt(index))
158173

packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ int32_t MapBuffer::getInt(Key key) const {
6161
bytes_.data() + valueOffset(bucketIndex));
6262
}
6363

64+
int64_t MapBuffer::getLong(Key key) const {
65+
auto bucketIndex = getKeyBucket(key);
66+
react_native_assert(bucketIndex != -1 && "Key not found in MapBuffer");
67+
68+
return *reinterpret_cast<const int64_t*>(
69+
bytes_.data() + valueOffset(bucketIndex));
70+
}
71+
6472
bool MapBuffer::getBool(Key key) const {
6573
return getInt(key) != 0;
6674
}

packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class MapBuffer {
104104
Double = 2,
105105
String = 3,
106106
Map = 4,
107+
Long = 5,
107108
};
108109

109110
explicit MapBuffer(std::vector<uint8_t> data);
@@ -118,6 +119,8 @@ class MapBuffer {
118119

119120
int32_t getInt(MapBuffer::Key key) const;
120121

122+
int64_t getLong(MapBuffer::Key key) const;
123+
121124
bool getBool(MapBuffer::Key key) const;
122125

123126
double getDouble(MapBuffer::Key key) const;

packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ using namespace facebook::react;
1313
namespace facebook::react {
1414

1515
constexpr uint32_t INT_SIZE = sizeof(uint32_t);
16+
constexpr uint32_t LONG_SIZE = sizeof(uint64_t);
1617
constexpr uint32_t DOUBLE_SIZE = sizeof(double);
1718
constexpr uint32_t MAX_BUCKET_VALUE_SIZE = sizeof(uint64_t);
1819

@@ -76,6 +77,14 @@ void MapBufferBuilder::putInt(MapBuffer::Key key, int32_t value) {
7677
INT_SIZE);
7778
}
7879

80+
void MapBufferBuilder::putLong(MapBuffer::Key key, int64_t value) {
81+
storeKeyValue(
82+
key,
83+
MapBuffer::DataType::Long,
84+
reinterpret_cast<const uint8_t*>(&value),
85+
LONG_SIZE);
86+
}
87+
7988
void MapBufferBuilder::putString(MapBuffer::Key key, const std::string& value) {
8089
auto strSize = value.size();
8190
const char* strData = value.data();

packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class MapBufferBuilder {
2727

2828
void putInt(MapBuffer::Key key, int32_t value);
2929

30-
// TODO: Support 64 bit integers
30+
void putLong(MapBuffer::Key key, int64_t value);
3131

3232
void putBool(MapBuffer::Key key, bool value);
3333

packages/react-native/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8+
#include <limits>
89
#include <memory>
910
#include <vector>
1011

@@ -27,6 +28,26 @@ TEST(MapBufferTest, testSimpleIntMap) {
2728
EXPECT_EQ(map.getInt(1), 4321);
2829
}
2930

31+
TEST(MapBufferTest, testSimpleLongMap) {
32+
auto builder = MapBufferBuilder();
33+
34+
int64_t minInt64 = std::numeric_limits<int64_t>::min();
35+
int64_t maxInt64 = std::numeric_limits<int64_t>::max();
36+
37+
builder.putLong(0, minInt64);
38+
builder.putLong(1, maxInt64);
39+
builder.putLong(2, 1125899906842623LL);
40+
builder.putLong(3, -1125899906842623LL);
41+
42+
auto map = builder.build();
43+
44+
EXPECT_EQ(map.count(), 4);
45+
EXPECT_EQ(map.getLong(0), minInt64);
46+
EXPECT_EQ(map.getLong(1), maxInt64);
47+
EXPECT_EQ(map.getLong(2), 1125899906842623LL);
48+
EXPECT_EQ(map.getLong(3), -1125899906842623LL);
49+
}
50+
3051
TEST(MapBufferTest, testMapBufferExtension) {
3152
// 26 = 2 buckets: 2*10 + 6 sizeof(header)
3253
int initialSize = 26;

0 commit comments

Comments
 (0)