diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt
new file mode 100644
index 00000000000..f88cb5572ef
--- /dev/null
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/MapBufferSoLoader.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.facebook.react.common.mapbuffer
+
+import com.facebook.react.bridge.ReactMarker
+import com.facebook.react.bridge.ReactMarkerConstants
+import com.facebook.soloader.SoLoader
+import com.facebook.systrace.Systrace
+
+object MapBufferSoLoader {
+ @Volatile private var didInit = false
+
+ @JvmStatic
+ fun staticInit() {
+ if (didInit) {
+ return
+ }
+ didInit = true
+
+ Systrace.beginSection(
+ Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
+ "ReadableMapBufferSoLoader.staticInit::load:mapbufferjni")
+ ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_START)
+ SoLoader.loadLibrary("mapbufferjni")
+ ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END)
+ Systrace.endSection(Systrace.TRACE_TAG_REACT_JAVA_BRIDGE)
+ }
+}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java
deleted file mode 100644
index 4115ccc8923..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-package com.facebook.react.common.mapbuffer;
-
-import androidx.annotation.Nullable;
-import com.facebook.jni.HybridData;
-import com.facebook.proguard.annotations.DoNotStrip;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.Iterator;
-
-/**
- * TODO T83483191: add documentation.
- *
- *
NOTE: {@link ReadableMapBuffer} is NOT thread safe.
- */
-public class ReadableMapBuffer implements Iterable {
-
- static {
- ReadableMapBufferSoLoader.staticInit();
- }
-
- /**
- * Data types supported by MapBuffer. Keep in sync with definition in `MapBuffer.h`, as enum
- * serialization relies on correct order.
- */
- public enum DataType {
- BOOL,
- INT,
- DOUBLE,
- STRING,
- MAP;
- }
-
- // Value used to verify if the data is serialized with LittleEndian order.
- private static final int ALIGNMENT = 0xFE;
-
- // 8 bytes = 2 (alignment) + 2 (count) + 4 (size)
- private static final int HEADER_SIZE = 8;
-
- // 10 bytes = 2 (key) + 2 (type) + 8 (value)
- private static final int BUCKET_SIZE = 12;
-
- // 2 bytes = 2 (key)
- private static final int TYPE_OFFSET = 2;
-
- // 4 bytes = 2 (key) + 2 (type)
- private static final int VALUE_OFFSET = 4;
-
- private static final int INT_SIZE = 4;
-
- @Nullable ByteBuffer mBuffer = null;
-
- // Amount of items serialized on the ByteBuffer
- private int mCount = 0;
-
- @DoNotStrip
- private ReadableMapBuffer(HybridData hybridData) {
- mHybridData = hybridData;
- }
-
- private ReadableMapBuffer(ByteBuffer buffer) {
- mBuffer = buffer;
- readHeader();
- }
-
- private native ByteBuffer importByteBuffer();
-
- @SuppressWarnings("unused")
- @DoNotStrip
- @Nullable
- private HybridData mHybridData;
-
- private static int getKeyOffsetForBucketIndex(int bucketIndex) {
- return HEADER_SIZE + BUCKET_SIZE * bucketIndex;
- }
-
- // returns the relative offset of the first byte of dynamic data
- private int getOffsetForDynamicData() {
- // TODO T83483191: check if there's dynamic data?
- return getKeyOffsetForBucketIndex(mCount);
- }
-
- /**
- * @param key Key to search for
- * @return the "bucket index" for a key or -1 if not found. It uses a binary search algorithm
- * (log(n))
- */
- private int getBucketIndexForKey(int key) {
- importByteBufferAndReadHeader();
- int lo = 0;
- int hi = getCount() - 1;
- while (lo <= hi) {
- final int mid = (lo + hi) >>> 1;
- final int midVal = readUnsignedShort(getKeyOffsetForBucketIndex(mid));
- if (midVal < key) {
- lo = mid + 1;
- } else if (midVal > key) {
- hi = mid - 1;
- } else {
- return mid;
- }
- }
- return -1;
- }
-
- private DataType readDataType(int bucketIndex) {
- int value = readUnsignedShort(getKeyOffsetForBucketIndex(bucketIndex) + TYPE_OFFSET);
- return DataType.values()[value];
- }
-
- private int getTypedValueOffsetForKey(int key, DataType expected) {
- int bucketIndex = getBucketIndexForKey(key);
- if (bucketIndex == -1) {
- throw new IllegalArgumentException("Key not found: " + key);
- }
-
- DataType dataType = readDataType(bucketIndex);
- if (dataType != expected) {
- throw new IllegalStateException(
- "Expected "
- + expected
- + " for key: "
- + key
- + " found "
- + dataType.toString()
- + " instead.");
- }
-
- return getKeyOffsetForBucketIndex(bucketIndex) + VALUE_OFFSET;
- }
-
- private int readUnsignedShort(int bufferPosition) {
- return mBuffer.getShort(bufferPosition) & 0xFFFF;
- }
-
- private double readDoubleValue(int bufferPosition) {
- return mBuffer.getDouble(bufferPosition);
- }
-
- private int readIntValue(int bufferPosition) {
- return mBuffer.getInt(bufferPosition);
- }
-
- private boolean readBooleanValue(int bufferPosition) {
- return readIntValue(bufferPosition) == 1;
- }
-
- private String readStringValue(int bufferPosition) {
- int offset = getOffsetForDynamicData() + mBuffer.getInt(bufferPosition);
-
- int sizeOfString = mBuffer.getInt(offset);
- byte[] result = new byte[sizeOfString];
-
- int stringOffset = offset + INT_SIZE;
-
- mBuffer.position(stringOffset);
- mBuffer.get(result, 0, sizeOfString);
-
- return new String(result);
- }
-
- private ReadableMapBuffer readMapBufferValue(int position) {
- int offset = getOffsetForDynamicData() + mBuffer.getInt(position);
-
- int sizeMapBuffer = mBuffer.getInt(offset);
- byte[] buffer = new byte[sizeMapBuffer];
-
- int bufferOffset = offset + INT_SIZE;
-
- mBuffer.position(bufferOffset);
- mBuffer.get(buffer, 0, sizeMapBuffer);
-
- return new ReadableMapBuffer(ByteBuffer.wrap(buffer));
- }
-
- private void readHeader() {
- // byte order
- short storedAlignment = mBuffer.getShort();
- if (storedAlignment != ALIGNMENT) {
- mBuffer.order(ByteOrder.LITTLE_ENDIAN);
- }
- // count
- mCount = readUnsignedShort(mBuffer.position());
- }
-
- /**
- * Binary search of the key inside the mapBuffer (log(n)).
- *
- * @param key Key to search for
- * @return true if and only if the Key received as a parameter is stored in the MapBuffer.
- */
- public boolean hasKey(int key) {
- // TODO T83483191: Add tests
- return getBucketIndexForKey(key) != -1;
- }
-
- @Nullable
- public DataType getType(int key) {
- int bucketIndex = getBucketIndexForKey(key);
-
- if (bucketIndex == -1) {
- throw new IllegalArgumentException("Key not found: " + key);
- }
-
- return readDataType(bucketIndex);
- }
-
- /** @return amount of elements stored into the MapBuffer */
- public int getCount() {
- importByteBufferAndReadHeader();
- return mCount;
- }
-
- /**
- * @param key {@link int} representing the key
- * @return return the int associated to the Key received as a parameter.
- */
- public int getInt(int key) {
- return readIntValue(getTypedValueOffsetForKey(key, DataType.INT));
- }
-
- /**
- * @param key {@link int} representing the key
- * @return return the double associated to the Key received as a parameter.
- */
- public double getDouble(int key) {
- return readDoubleValue(getTypedValueOffsetForKey(key, DataType.DOUBLE));
- }
-
- /**
- * @param key {@link int} representing the key
- * @return return the int associated to the Key received as a parameter.
- */
- public String getString(int key) {
- return readStringValue(getTypedValueOffsetForKey(key, DataType.STRING));
- }
-
- public boolean getBoolean(int key) {
- return readBooleanValue(getTypedValueOffsetForKey(key, DataType.BOOL));
- }
-
- /**
- * @param key {@link int} representing the key
- * @return return the int associated to the Key received as a parameter.
- */
- public ReadableMapBuffer getMapBuffer(int key) {
- return readMapBufferValue(getTypedValueOffsetForKey(key, DataType.MAP));
- }
-
- /**
- * Import ByteBuffer from C++, read the header and move the current cursor at the start of the
- * payload.
- */
- private ByteBuffer importByteBufferAndReadHeader() {
- if (mBuffer != null) {
- return mBuffer;
- }
-
- // mBuffer = importByteBufferAllocateDirect();
- mBuffer = importByteBuffer();
-
- readHeader();
- return mBuffer;
- }
-
- private void assertKeyExists(int key, int bucketIndex) {
- int storedKey = readUnsignedShort(getKeyOffsetForBucketIndex(bucketIndex));
- if (storedKey != key) {
- throw new IllegalStateException(
- "Stored key doesn't match parameter - expected: " + key + " - found: " + storedKey);
- }
- }
-
- @Override
- public int hashCode() {
- ByteBuffer byteBuffer = importByteBufferAndReadHeader();
- byteBuffer.rewind();
- return byteBuffer.hashCode();
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof ReadableMapBuffer)) {
- return false;
- }
-
- ReadableMapBuffer other = (ReadableMapBuffer) obj;
- ByteBuffer thisByteBuffer = importByteBufferAndReadHeader();
- ByteBuffer otherByteBuffer = other.importByteBufferAndReadHeader();
- if (thisByteBuffer == otherByteBuffer) {
- return true;
- }
- thisByteBuffer.rewind();
- otherByteBuffer.rewind();
- return thisByteBuffer.equals(otherByteBuffer);
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder("{");
- for (MapBufferEntry entry : this) {
- int key = entry.getKey();
- builder.append(key);
- builder.append('=');
- switch (entry.getType()) {
- case BOOL:
- builder.append(entry.getBoolean());
- break;
- case INT:
- builder.append(entry.getInt());
- break;
- case DOUBLE:
- builder.append(entry.getDouble());
- break;
- case STRING:
- builder.append(entry.getString());
- break;
- case MAP:
- builder.append(entry.getReadableMapBuffer().toString());
- break;
- }
- builder.append(',');
- }
- builder.append('}');
- return builder.toString();
- }
-
- /** @return an {@link Iterator} for the entries of this MapBuffer. */
- @Override
- public Iterator iterator() {
- return new Iterator() {
- int current = 0;
- final int last = getCount() - 1;
-
- @Override
- public boolean hasNext() {
- return current <= last;
- }
-
- @Override
- public MapBufferEntry next() {
- return new MapBufferEntry(getKeyOffsetForBucketIndex(current++));
- }
- };
- }
-
- /** This class represents an Entry of the {@link ReadableMapBuffer} class. */
- public class MapBufferEntry {
- private final int mBucketOffset;
-
- private MapBufferEntry(int position) {
- mBucketOffset = position;
- }
-
- private void assertType(DataType expected) {
- DataType dataType = getType();
- if (expected != dataType) {
- throw new IllegalStateException(
- "Expected "
- + expected
- + " for key: "
- + getKey()
- + " found "
- + dataType.toString()
- + " instead.");
- }
- }
-
- /** @return a {@link short} that represents the key of this {@link MapBufferEntry}. */
- public int getKey() {
- return readUnsignedShort(mBucketOffset);
- }
-
- public DataType getType() {
- return DataType.values()[readUnsignedShort(mBucketOffset + TYPE_OFFSET)];
- }
-
- /** @return the double value that is stored in this {@link MapBufferEntry}. */
- public double getDouble() {
- // TODO T83483191 Extend serialization of MapBuffer to return null if there's no value
- // stored in this MapBufferEntry.
- assertType(DataType.DOUBLE);
- return readDoubleValue(mBucketOffset + VALUE_OFFSET);
- }
-
- /** @return the int value that is stored in this {@link MapBufferEntry}. */
- public int getInt() {
- assertType(DataType.INT);
- return readIntValue(mBucketOffset + VALUE_OFFSET);
- }
-
- /** @return the boolean value that is stored in this {@link MapBufferEntry}. */
- public boolean getBoolean() {
- assertType(DataType.BOOL);
- return readBooleanValue(mBucketOffset + VALUE_OFFSET);
- }
-
- /** @return the String value that is stored in this {@link MapBufferEntry}. */
- public String getString() {
- assertType(DataType.STRING);
- return readStringValue(mBucketOffset + VALUE_OFFSET);
- }
-
- /**
- * @return the {@link ReadableMapBuffer} value that is stored in this {@link MapBufferEntry}.
- */
- public ReadableMapBuffer getReadableMapBuffer() {
- assertType(DataType.MAP);
- return readMapBufferValue(mBucketOffset + VALUE_OFFSET);
- }
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt
new file mode 100644
index 00000000000..c3143431d7a
--- /dev/null
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBuffer.kt
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+package com.facebook.react.common.mapbuffer
+
+import com.facebook.jni.HybridData
+import com.facebook.proguard.annotations.DoNotStrip
+import com.facebook.react.common.mapbuffer.MapBuffer.Companion.KEY_RANGE
+import java.lang.StringBuilder
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import javax.annotation.concurrent.NotThreadSafe
+
+/**
+ * Read-only implementation of the [MapBuffer], imported from C++ environment. Use
+ * ` to create it.
+ *
+ * See [MapBuffer] documentation for more details
+ */
+@NotThreadSafe
+@DoNotStrip
+class ReadableMapBuffer : MapBuffer {
+
+ // Hybrid data must be kept in the `mHybridData` field for fbjni to work
+ @field:DoNotStrip private val mHybridData: HybridData?
+
+ // Byte data of the mapBuffer
+ private val buffer: ByteBuffer
+ // Amount of items serialized on the ByteBuffer
+ override var count = 0
+ private set
+
+ @DoNotStrip
+ private constructor(hybridData: HybridData) {
+ this.mHybridData = hybridData
+ this.buffer = importByteBuffer()
+ readHeader()
+ }
+
+ private constructor(buffer: ByteBuffer) {
+ this.mHybridData = null
+ this.buffer = buffer
+ readHeader()
+ }
+
+ private external fun importByteBuffer(): ByteBuffer
+
+ private fun readHeader() {
+ // byte order
+ val storedAlignment = buffer.short
+ if (storedAlignment.toInt() != ALIGNMENT) {
+ buffer.order(ByteOrder.LITTLE_ENDIAN)
+ }
+ // count
+ count = readUnsignedShort(buffer.position()).toInt()
+ }
+
+ // returns the relative offset of the first byte of dynamic data
+ private val offsetForDynamicData: Int
+ get() = getKeyOffsetForBucketIndex(count)
+
+ /**
+ * @param key Key to search for
+ * @return the "bucket index" for a key or -1 if not found. It uses a binary search algorithm
+ * (log(n))
+ */
+ private fun getBucketIndexForKey(intKey: Int): Int {
+ if (intKey !in KEY_RANGE) {
+ return -1
+ }
+ val key = intKey.toUShort()
+
+ var lo = 0
+ var hi = count - 1
+ while (lo <= hi) {
+ val mid = lo + hi ushr 1
+ val midVal = readUnsignedShort(getKeyOffsetForBucketIndex(mid))
+ when {
+ midVal < key -> lo = mid + 1
+ midVal > key -> hi = mid - 1
+ else -> return mid
+ }
+ }
+ return -1
+ }
+
+ private fun readDataType(bucketIndex: Int): MapBuffer.DataType {
+ val value = readUnsignedShort(getKeyOffsetForBucketIndex(bucketIndex) + TYPE_OFFSET).toInt()
+ return MapBuffer.DataType.values()[value]
+ }
+
+ private fun getTypedValueOffsetForKey(key: Int, expected: MapBuffer.DataType): Int {
+ val bucketIndex = getBucketIndexForKey(key)
+ require(bucketIndex != -1) { "Key not found: $key" }
+ val dataType = readDataType(bucketIndex)
+ check(!(dataType !== expected)) { "Expected $expected for key: $key, found $dataType instead." }
+ return getKeyOffsetForBucketIndex(bucketIndex) + VALUE_OFFSET
+ }
+
+ private fun readUnsignedShort(bufferPosition: Int): UShort {
+ return buffer.getShort(bufferPosition).toUShort()
+ }
+
+ private fun readDoubleValue(bufferPosition: Int): Double {
+ return buffer.getDouble(bufferPosition)
+ }
+
+ private fun readIntValue(bufferPosition: Int): Int {
+ return buffer.getInt(bufferPosition)
+ }
+
+ private fun readBooleanValue(bufferPosition: Int): Boolean {
+ return readIntValue(bufferPosition) == 1
+ }
+
+ private fun readStringValue(bufferPosition: Int): String {
+ val offset = offsetForDynamicData + buffer.getInt(bufferPosition)
+ val sizeOfString = buffer.getInt(offset)
+ val result = ByteArray(sizeOfString)
+ val stringOffset = offset + Int.SIZE_BYTES
+ buffer.position(stringOffset)
+ buffer[result, 0, sizeOfString]
+ return String(result)
+ }
+
+ private fun readMapBufferValue(position: Int): ReadableMapBuffer {
+ val offset = offsetForDynamicData + buffer.getInt(position)
+ val sizeMapBuffer = buffer.getInt(offset)
+ val newBuffer = ByteArray(sizeMapBuffer)
+ val bufferOffset = offset + Int.SIZE_BYTES
+ buffer.position(bufferOffset)
+ buffer[newBuffer, 0, sizeMapBuffer]
+ return ReadableMapBuffer(ByteBuffer.wrap(newBuffer))
+ }
+
+ private fun getKeyOffsetForBucketIndex(bucketIndex: Int): Int {
+ return HEADER_SIZE + BUCKET_SIZE * bucketIndex
+ }
+
+ override fun contains(key: Int): Boolean {
+ // TODO T83483191: Add tests
+ return getBucketIndexForKey(key) != -1
+ }
+
+ override fun getKeyOffset(key: Int): Int = getBucketIndexForKey(key)
+
+ override fun entryAt(offset: Int): MapBuffer.Entry =
+ MapBufferEntry(getKeyOffsetForBucketIndex(offset))
+
+ override fun getType(key: Int): MapBuffer.DataType {
+ val bucketIndex = getBucketIndexForKey(key)
+ require(bucketIndex != -1) { "Key not found: $key" }
+ return readDataType(bucketIndex)
+ }
+
+ override fun getInt(key: Int): Int =
+ readIntValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.INT))
+
+ override fun getDouble(key: Int): Double =
+ readDoubleValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.DOUBLE))
+
+ override fun getString(key: Int): String =
+ readStringValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.STRING))
+
+ override fun getBoolean(key: Int): Boolean =
+ readBooleanValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.BOOL))
+
+ override fun getMapBuffer(key: Int): ReadableMapBuffer =
+ readMapBufferValue(getTypedValueOffsetForKey(key, MapBuffer.DataType.MAP))
+
+ override fun hashCode(): Int {
+ buffer.rewind()
+ return buffer.hashCode()
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (other !is ReadableMapBuffer) {
+ return false
+ }
+ val thisByteBuffer = buffer
+ val otherByteBuffer = other.buffer
+ if (thisByteBuffer === otherByteBuffer) {
+ return true
+ }
+ thisByteBuffer.rewind()
+ otherByteBuffer.rewind()
+ return thisByteBuffer == otherByteBuffer
+ }
+
+ override fun toString(): String {
+ val builder = StringBuilder("{")
+ for (entry in this) {
+ val key = entry.key
+ builder.append(key)
+ builder.append('=')
+ when (entry.type) {
+ MapBuffer.DataType.BOOL -> builder.append(entry.booleanValue)
+ MapBuffer.DataType.INT -> builder.append(entry.intValue)
+ MapBuffer.DataType.DOUBLE -> builder.append(entry.doubleValue)
+ MapBuffer.DataType.STRING -> builder.append(entry.stringValue)
+ MapBuffer.DataType.MAP -> builder.append(entry.mapBufferValue.toString())
+ }
+ builder.append(',')
+ }
+ builder.append('}')
+ return builder.toString()
+ }
+
+ override fun iterator(): Iterator {
+ return object : Iterator {
+ var current = 0
+ val last = count - 1
+
+ override fun hasNext(): Boolean {
+ return current <= last
+ }
+
+ override fun next(): MapBuffer.Entry {
+ return MapBufferEntry(getKeyOffsetForBucketIndex(current++))
+ }
+ }
+ }
+
+ private inner class MapBufferEntry(private val bucketOffset: Int) : MapBuffer.Entry {
+ private fun assertType(expected: MapBuffer.DataType) {
+ val dataType = type
+ check(!(expected !== dataType)) {
+ ("Expected " +
+ expected +
+ " for key: " +
+ key +
+ " found " +
+ dataType.toString() +
+ " instead.")
+ }
+ }
+
+ override val key: Int
+ get() = readUnsignedShort(bucketOffset).toInt()
+ override val type: MapBuffer.DataType
+ get() = MapBuffer.DataType.values()[readUnsignedShort(bucketOffset + TYPE_OFFSET).toInt()]
+
+ override val doubleValue: Double
+ get() {
+ assertType(MapBuffer.DataType.DOUBLE)
+ return readDoubleValue(bucketOffset + VALUE_OFFSET)
+ }
+
+ override val intValue: Int
+ get() {
+ assertType(MapBuffer.DataType.INT)
+ return readIntValue(bucketOffset + VALUE_OFFSET)
+ }
+
+ override val booleanValue: Boolean
+ get() {
+ assertType(MapBuffer.DataType.BOOL)
+ return readBooleanValue(bucketOffset + VALUE_OFFSET)
+ }
+
+ override val stringValue: String
+ get() {
+ assertType(MapBuffer.DataType.STRING)
+ return readStringValue(bucketOffset + VALUE_OFFSET)
+ }
+
+ override val mapBufferValue: MapBuffer
+ get() {
+ assertType(MapBuffer.DataType.MAP)
+ return readMapBufferValue(bucketOffset + VALUE_OFFSET)
+ }
+ }
+
+ companion object {
+ // Value used to verify if the data is serialized with LittleEndian order.
+ private const val ALIGNMENT = 0xFE
+
+ // 8 bytes = 2 (alignment) + 2 (count) + 4 (size)
+ private const val HEADER_SIZE = 8
+
+ // 10 bytes = 2 (key) + 2 (type) + 8 (value)
+ private const val BUCKET_SIZE = 12
+
+ // 2 bytes = 2 (key)
+ private const val TYPE_OFFSET = 2
+
+ // 4 bytes = 2 (key) + 2 (type)
+ private const val VALUE_OFFSET = 4
+
+ init {
+ MapBufferSoLoader.staticInit()
+ }
+ }
+}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBufferSoLoader.java b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBufferSoLoader.java
deleted file mode 100644
index b03ef0f8b06..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/ReadableMapBufferSoLoader.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-package com.facebook.react.common.mapbuffer;
-
-import static com.facebook.systrace.Systrace.TRACE_TAG_REACT_JAVA_BRIDGE;
-
-import com.facebook.react.bridge.ReactMarker;
-import com.facebook.react.bridge.ReactMarkerConstants;
-import com.facebook.soloader.SoLoader;
-import com.facebook.systrace.Systrace;
-
-public class ReadableMapBufferSoLoader {
- private static volatile boolean sDidInit = false;
-
- public static void staticInit() {
- if (sDidInit) {
- return;
- }
- Systrace.beginSection(
- Systrace.TRACE_TAG_REACT_JAVA_BRIDGE,
- "ReadableMapBufferSoLoader.staticInit::load:mapbufferjni");
- ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_START);
- SoLoader.loadLibrary("mapbufferjni");
- ReactMarker.logMarker(ReactMarkerConstants.LOAD_REACT_NATIVE_MAPBUFFER_SO_FILE_END);
- Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE);
- sDidInit = true;
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt
index 81656037c3a..7cc67f9e070 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt
+++ b/ReactAndroid/src/main/java/com/facebook/react/common/mapbuffer/WritableMapBuffer.kt
@@ -164,7 +164,7 @@ class WritableMapBuffer : MapBuffer {
companion object {
init {
- ReadableMapBufferSoLoader.staticInit()
+ MapBufferSoLoader.staticInit()
}
}
}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK
index ecdd934d07c..28be0c856ba 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK
+++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK
@@ -14,6 +14,7 @@ rn_android_library(
"pfh:ReactNative_CommonInfrastructurePlaceholde",
"supermodule:xplat/default/public.react_native.infra",
],
+ language = "KOTLIN",
provided_deps = [
react_native_dep("third-party/android/androidx:annotation"),
react_native_dep("third-party/android/androidx:core"),
@@ -21,6 +22,7 @@ rn_android_library(
react_native_dep("third-party/android/androidx:legacy-support-core-ui"),
react_native_dep("third-party/android/androidx:legacy-support-core-utils"),
],
+ pure_kotlin = False,
required_for_source_only_abi = True,
visibility = [
"PUBLIC",
diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java
index 1dfe46d75f4..b381aec1667 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java
@@ -11,7 +11,7 @@ import androidx.annotation.NonNull;
import com.facebook.react.bridge.JSIModuleProvider;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.UIManager;
-import com.facebook.react.common.mapbuffer.ReadableMapBufferSoLoader;
+import com.facebook.react.common.mapbuffer.MapBufferSoLoader;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.fabric.events.EventBeatManager;
import com.facebook.react.uimanager.ViewManagerRegistry;
@@ -46,7 +46,7 @@ public class FabricJSIModuleProvider implements JSIModuleProvider {
final Binding binding = new Binding();
if (ReactFeatureFlags.isMapBufferSerializationEnabled()) {
- ReadableMapBufferSoLoader.staticInit();
+ MapBufferSoLoader.staticInit();
}
binding.register(
diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java
index 74305bfacbb..30ebf9dc040 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java
@@ -23,7 +23,7 @@ import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.RetryableMountingLayerException;
import com.facebook.react.bridge.UiThreadUtil;
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
+import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.fabric.FabricUIManager;
import com.facebook.react.fabric.events.EventEmitterWrapper;
import com.facebook.react.fabric.mounting.mountitems.MountItem;
@@ -396,9 +396,9 @@ public class MountingManager {
public long measureMapBuffer(
@NonNull ReactContext context,
@NonNull String componentName,
- @NonNull ReadableMapBuffer localData,
- @NonNull ReadableMapBuffer props,
- @Nullable ReadableMapBuffer state,
+ @NonNull MapBuffer localData,
+ @NonNull MapBuffer props,
+ @Nullable MapBuffer state,
float width,
@NonNull YogaMeasureMode widthMode,
float height,
diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java
index 3a0879c98a5..34019c73636 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewManager.java
@@ -15,7 +15,7 @@ import com.facebook.react.bridge.BaseJavaModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
+import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.touch.JSResponderHandler;
import com.facebook.react.touch.ReactInterceptingViewGroup;
import com.facebook.react.uimanager.annotations.ReactProp;
@@ -333,9 +333,9 @@ public abstract class ViewManager
* ViewManager
*
* @param context {@link com.facebook.react.bridge.ReactContext} used for the view.
- * @param localData {@link ReadableMapBuffer} containing "local data" defined in C++
- * @param props {@link ReadableMapBuffer} containing JS props
- * @param state {@link ReadableMapBuffer} containing state defined in C++
+ * @param localData {@link MapBuffer} containing "local data" defined in C++
+ * @param props {@link MapBuffer} containing JS props
+ * @param state {@link MapBuffer} containing state defined in C++
* @param width width of the view (usually zero)
* @param widthMode widthMode used during calculation of layout
* @param height height of the view (usually zero)
@@ -353,10 +353,10 @@ public abstract class ViewManager
*/
public long measure(
Context context,
- ReadableMapBuffer localData,
- ReadableMapBuffer props,
+ MapBuffer localData,
+ MapBuffer props,
// TODO(T114731225): review whether state parameter is needed
- @Nullable ReadableMapBuffer state,
+ @Nullable MapBuffer state,
float width,
YogaMeasureMode widthMode,
float height,
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK
index d9bf82ff8e7..b011038126d 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK
@@ -9,6 +9,8 @@ rn_android_library(
"pfh:ReactNative_CommonInfrastructurePlaceholde",
"supermodule:xplat/default/public.react_native.infra",
],
+ language = "KOTLIN",
+ pure_kotlin = False,
required_for_source_only_abi = True,
visibility = [
"PUBLIC",
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
index 6aad6e761e3..b26cefbceab 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java
@@ -15,7 +15,7 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.common.annotations.VisibleForTesting;
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
+import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.IViewManagerWithChildren;
@@ -112,7 +112,7 @@ public class ReactTextViewManager
}
if (ReactFeatureFlags.isMapBufferSerializationEnabled()) {
- ReadableMapBuffer stateMapBuffer = stateWrapper.getStateDataMapBuffer();
+ MapBuffer stateMapBuffer = stateWrapper.getStateDataMapBuffer();
if (stateMapBuffer != null) {
return getReactTextUpdate(view, props, stateMapBuffer);
}
@@ -142,11 +142,10 @@ public class ReactTextViewManager
TextAttributeProps.getJustificationMode(props));
}
- private Object getReactTextUpdate(
- ReactTextView view, ReactStylesDiffMap props, ReadableMapBuffer state) {
+ private Object getReactTextUpdate(ReactTextView view, ReactStylesDiffMap props, MapBuffer state) {
- ReadableMapBuffer attributedString = state.getMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING);
- ReadableMapBuffer paragraphAttributes = state.getMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES);
+ MapBuffer attributedString = state.getMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING);
+ MapBuffer paragraphAttributes = state.getMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES);
Spannable spanned =
TextLayoutManagerMapBuffer.getOrCreateSpannableForText(
view.getContext(), attributedString, mReactTextViewManagerCallback);
@@ -205,9 +204,9 @@ public class ReactTextViewManager
@Override
public long measure(
Context context,
- ReadableMapBuffer localData,
- ReadableMapBuffer props,
- @Nullable ReadableMapBuffer state,
+ MapBuffer localData,
+ MapBuffer props,
+ @Nullable MapBuffer state,
float width,
YogaMeasureMode widthMode,
float height,
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java
index e3f15b9ebe6..8706e70b102 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextAttributeProps.java
@@ -16,7 +16,7 @@ import androidx.annotation.Nullable;
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
+import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactAccessibilityDelegate;
import com.facebook.react.uimanager.ReactStylesDiffMap;
@@ -137,51 +137,48 @@ public class TextAttributeProps {
private TextAttributeProps() {}
- /**
- * Build a TextAttributeProps using data from the {@link ReadableMapBuffer} received as a
- * parameter.
- */
- public static TextAttributeProps fromReadableMapBuffer(ReadableMapBuffer props) {
+ /** Build a TextAttributeProps using data from the {@link MapBuffer} received as a parameter. */
+ public static TextAttributeProps fromMapBuffer(MapBuffer props) {
TextAttributeProps result = new TextAttributeProps();
// TODO T83483191: Review constants that are not being set!
- Iterator iterator = props.iterator();
+ Iterator iterator = props.iterator();
while (iterator.hasNext()) {
- ReadableMapBuffer.MapBufferEntry entry = iterator.next();
+ MapBuffer.Entry entry = iterator.next();
switch (entry.getKey()) {
case TA_KEY_FOREGROUND_COLOR:
- result.setColor(entry.getInt());
+ result.setColor(entry.getIntValue());
break;
case TA_KEY_BACKGROUND_COLOR:
- result.setBackgroundColor(entry.getInt());
+ result.setBackgroundColor(entry.getIntValue());
break;
case TA_KEY_OPACITY:
break;
case TA_KEY_FONT_FAMILY:
- result.setFontFamily(entry.getString());
+ result.setFontFamily(entry.getStringValue());
break;
case TA_KEY_FONT_SIZE:
- result.setFontSize((float) entry.getDouble());
+ result.setFontSize((float) entry.getDoubleValue());
break;
case TA_KEY_FONT_SIZE_MULTIPLIER:
break;
case TA_KEY_FONT_WEIGHT:
- result.setFontWeight(entry.getString());
+ result.setFontWeight(entry.getStringValue());
break;
case TA_KEY_FONT_STYLE:
- result.setFontStyle(entry.getString());
+ result.setFontStyle(entry.getStringValue());
break;
case TA_KEY_FONT_VARIANT:
- result.setFontVariant(entry.getReadableMapBuffer());
+ result.setFontVariant(entry.getMapBufferValue());
break;
case TA_KEY_ALLOW_FONT_SCALING:
- result.setAllowFontScaling(entry.getBoolean());
+ result.setAllowFontScaling(entry.getBooleanValue());
break;
case TA_KEY_LETTER_SPACING:
- result.setLetterSpacing((float) entry.getDouble());
+ result.setLetterSpacing((float) entry.getDoubleValue());
break;
case TA_KEY_LINE_HEIGHT:
- result.setLineHeight((float) entry.getDouble());
+ result.setLineHeight((float) entry.getDoubleValue());
break;
case TA_KEY_ALIGNMENT:
break;
@@ -190,23 +187,23 @@ public class TextAttributeProps {
case TA_KEY_TEXT_DECORATION_COLOR:
break;
case TA_KEY_TEXT_DECORATION_LINE:
- result.setTextDecorationLine(entry.getString());
+ result.setTextDecorationLine(entry.getStringValue());
break;
case TA_KEY_TEXT_DECORATION_STYLE:
break;
case TA_KEY_TEXT_SHADOW_RADIUS:
- result.setTextShadowRadius((float) entry.getDouble());
+ result.setTextShadowRadius((float) entry.getDoubleValue());
break;
case TA_KEY_TEXT_SHADOW_COLOR:
- result.setTextShadowColor(entry.getInt());
+ result.setTextShadowColor(entry.getIntValue());
break;
case TA_KEY_IS_HIGHLIGHTED:
break;
case TA_KEY_LAYOUT_DIRECTION:
- result.setLayoutDirection(entry.getString());
+ result.setLayoutDirection(entry.getStringValue());
break;
case TA_KEY_ACCESSIBILITY_ROLE:
- result.setAccessibilityRole(entry.getString());
+ result.setAccessibilityRole(entry.getStringValue());
break;
}
}
@@ -419,17 +416,17 @@ public class TextAttributeProps {
mFontFeatureSettings = ReactTypefaceUtils.parseFontVariant(fontVariant);
}
- private void setFontVariant(@Nullable ReadableMapBuffer fontVariant) {
+ private void setFontVariant(@Nullable MapBuffer fontVariant) {
if (fontVariant == null || fontVariant.getCount() == 0) {
mFontFeatureSettings = null;
return;
}
List features = new ArrayList<>();
- Iterator iterator = fontVariant.iterator();
+ Iterator iterator = fontVariant.iterator();
while (iterator.hasNext()) {
- ReadableMapBuffer.MapBufferEntry entry = iterator.next();
- String value = entry.getString();
+ MapBuffer.Entry entry = iterator.next();
+ String value = entry.getStringValue();
if (value != null) {
switch (value) {
case "small-caps":
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java
index 81b8af845dc..bf59c915de0 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManagerMapBuffer.java
@@ -28,7 +28,7 @@ import com.facebook.react.bridge.ReactNoCrashSoftException;
import com.facebook.react.bridge.ReactSoftExceptionLogger;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.common.build.ReactBuildConfig;
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer;
+import com.facebook.react.common.mapbuffer.MapBuffer;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.yoga.YogaConstants;
import com.facebook.yoga.YogaMeasureMode;
@@ -78,7 +78,7 @@ public class TextLayoutManagerMapBuffer {
private static final Object sSpannableCacheLock = new Object();
private static final boolean DEFAULT_INCLUDE_FONT_PADDING = true;
- private static final LruCache sSpannableCache =
+ private static final LruCache sSpannableCache =
new LruCache<>(spannableCacheSize);
private static final ConcurrentHashMap sTagToSpannableCache =
new ConcurrentHashMap<>();
@@ -97,39 +97,36 @@ public class TextLayoutManagerMapBuffer {
sTagToSpannableCache.remove(reactTag);
}
- public static boolean isRTL(ReadableMapBuffer attributedString) {
- ReadableMapBuffer fragments = attributedString.getMapBuffer(AS_KEY_FRAGMENTS);
+ public static boolean isRTL(MapBuffer attributedString) {
+ MapBuffer fragments = attributedString.getMapBuffer(AS_KEY_FRAGMENTS);
if (fragments.getCount() == 0) {
return false;
}
- ReadableMapBuffer fragment = fragments.getMapBuffer((short) 0);
- ReadableMapBuffer textAttributes = fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES);
+ MapBuffer fragment = fragments.getMapBuffer((short) 0);
+ MapBuffer textAttributes = fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES);
return TextAttributeProps.getLayoutDirection(
textAttributes.getString(TextAttributeProps.TA_KEY_LAYOUT_DIRECTION))
== LayoutDirection.RTL;
}
private static void buildSpannableFromFragment(
- Context context,
- ReadableMapBuffer fragments,
- SpannableStringBuilder sb,
- List ops) {
+ Context context, MapBuffer fragments, SpannableStringBuilder sb, List ops) {
for (int i = 0, length = fragments.getCount(); i < length; i++) {
- ReadableMapBuffer fragment = fragments.getMapBuffer(i);
+ MapBuffer fragment = fragments.getMapBuffer(i);
int start = sb.length();
TextAttributeProps textAttributes =
- TextAttributeProps.fromReadableMapBuffer(fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES));
+ TextAttributeProps.fromMapBuffer(fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES));
sb.append(
TextTransform.apply(fragment.getString(FR_KEY_STRING), textAttributes.mTextTransform));
int end = sb.length();
int reactTag =
- fragment.hasKey(FR_KEY_REACT_TAG) ? fragment.getInt(FR_KEY_REACT_TAG) : View.NO_ID;
- if (fragment.hasKey(FR_KEY_IS_ATTACHMENT) && fragment.getBoolean(FR_KEY_IS_ATTACHMENT)) {
+ fragment.contains(FR_KEY_REACT_TAG) ? fragment.getInt(FR_KEY_REACT_TAG) : View.NO_ID;
+ if (fragment.contains(FR_KEY_IS_ATTACHMENT) && fragment.getBoolean(FR_KEY_IS_ATTACHMENT)) {
float width = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_WIDTH));
float height = PixelUtil.toPixelFromSP(fragment.getDouble(FR_KEY_HEIGHT));
ops.add(
@@ -203,7 +200,7 @@ public class TextLayoutManagerMapBuffer {
// public because both ReactTextViewManager and ReactTextInputManager need to use this
public static Spannable getOrCreateSpannableForText(
Context context,
- ReadableMapBuffer attributedString,
+ MapBuffer attributedString,
@Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) {
Spannable preparedSpannableText;
@@ -228,7 +225,7 @@ public class TextLayoutManagerMapBuffer {
private static Spannable createSpannableFromAttributedString(
Context context,
- ReadableMapBuffer attributedString,
+ MapBuffer attributedString,
@Nullable ReactTextViewManagerCallback reactTextViewManagerCallback) {
SpannableStringBuilder sb = new SpannableStringBuilder();
@@ -351,8 +348,8 @@ public class TextLayoutManagerMapBuffer {
public static long measureText(
Context context,
- ReadableMapBuffer attributedString,
- ReadableMapBuffer paragraphAttributes,
+ MapBuffer attributedString,
+ MapBuffer paragraphAttributes,
float width,
YogaMeasureMode widthYogaMeasureMode,
float height,
@@ -363,7 +360,7 @@ public class TextLayoutManagerMapBuffer {
// TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic)
TextPaint textPaint = sTextPaintInstance;
Spannable text;
- if (attributedString.hasKey(AS_KEY_CACHE_ID)) {
+ if (attributedString.contains(AS_KEY_CACHE_ID)) {
int cacheId = attributedString.getInt(AS_KEY_CACHE_ID);
if (ENABLE_MEASURE_LOGGING) {
FLog.e(TAG, "Get cached spannable for cacheId[" + cacheId + "]");
@@ -387,7 +384,7 @@ public class TextLayoutManagerMapBuffer {
TextAttributeProps.getTextBreakStrategy(
paragraphAttributes.getString(PA_KEY_TEXT_BREAK_STRATEGY));
boolean includeFontPadding =
- paragraphAttributes.hasKey(PA_KEY_INCLUDE_FONT_PADDING)
+ paragraphAttributes.contains(PA_KEY_INCLUDE_FONT_PADDING)
? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING)
: DEFAULT_INCLUDE_FONT_PADDING;
int hyphenationFrequency =
@@ -415,7 +412,7 @@ public class TextLayoutManagerMapBuffer {
hyphenationFrequency);
int maximumNumberOfLines =
- paragraphAttributes.hasKey(PA_KEY_MAX_NUMBER_OF_LINES)
+ paragraphAttributes.contains(PA_KEY_MAX_NUMBER_OF_LINES)
? paragraphAttributes.getInt(PA_KEY_MAX_NUMBER_OF_LINES)
: UNSET;
@@ -554,8 +551,8 @@ public class TextLayoutManagerMapBuffer {
public static WritableArray measureLines(
@NonNull Context context,
- ReadableMapBuffer attributedString,
- ReadableMapBuffer paragraphAttributes,
+ MapBuffer attributedString,
+ MapBuffer paragraphAttributes,
float width) {
TextPaint textPaint = sTextPaintInstance;
@@ -566,7 +563,7 @@ public class TextLayoutManagerMapBuffer {
TextAttributeProps.getTextBreakStrategy(
paragraphAttributes.getString(PA_KEY_TEXT_BREAK_STRATEGY));
boolean includeFontPadding =
- paragraphAttributes.hasKey(PA_KEY_INCLUDE_FONT_PADDING)
+ paragraphAttributes.contains(PA_KEY_INCLUDE_FONT_PADDING)
? paragraphAttributes.getBoolean(PA_KEY_INCLUDE_FONT_PADDING)
: DEFAULT_INCLUDE_FONT_PADDING;
int hyphenationFrequency =
diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt
index 11a281778c8..5ee668497e6 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt
+++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactMapBufferPropSetter.kt
@@ -14,7 +14,7 @@ import com.facebook.react.bridge.DynamicFromObject
import com.facebook.react.bridge.JavaOnlyArray
import com.facebook.react.bridge.JavaOnlyMap
import com.facebook.react.bridge.ReadableMap
-import com.facebook.react.common.mapbuffer.ReadableMapBuffer
+import com.facebook.react.common.mapbuffer.MapBuffer
import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.PointerEvents
@@ -97,134 +97,131 @@ object ReactMapBufferPropSetter {
private const val UNDEF_COLOR = Int.MAX_VALUE
- fun setProps(view: ReactViewGroup, viewManager: ReactViewManager, props: ReadableMapBuffer) {
+ fun setProps(view: ReactViewGroup, viewManager: ReactViewManager, props: MapBuffer) {
for (entry in props) {
when (entry.key) {
VP_ACCESSIBILITY_ACTIONS -> {
- viewManager.accessibilityActions(view, entry.readableMapBuffer)
+ viewManager.accessibilityActions(view, entry.mapBufferValue)
}
VP_ACCESSIBILITY_HINT -> {
- viewManager.setAccessibilityHint(view, entry.string.takeIf { it.isNotEmpty() })
+ viewManager.setAccessibilityHint(view, entry.stringValue.takeIf { it.isNotEmpty() })
}
VP_ACCESSIBILITY_LABEL -> {
- viewManager.setAccessibilityLabel(view, entry.string.takeIf { it.isNotEmpty() })
+ viewManager.setAccessibilityLabel(view, entry.stringValue.takeIf { it.isNotEmpty() })
}
VP_ACCESSIBILITY_LABELLED_BY -> {
- viewManager.accessibilityLabelledBy(view, entry.readableMapBuffer)
+ viewManager.accessibilityLabelledBy(view, entry.mapBufferValue)
}
VP_ACCESSIBILITY_LIVE_REGION -> {
- view.accessibilityLiveRegion(entry.int)
+ view.accessibilityLiveRegion(entry.intValue)
}
VP_ACCESSIBILITY_ROLE -> {
- viewManager.setAccessibilityRole(view, entry.string.takeIf { it.isNotEmpty() })
+ viewManager.setAccessibilityRole(view, entry.stringValue.takeIf { it.isNotEmpty() })
}
VP_ACCESSIBILITY_STATE -> {
- viewManager.accessibilityState(view, entry.readableMapBuffer)
+ viewManager.accessibilityState(view, entry.mapBufferValue)
}
VP_ACCESSIBILITY_VALUE -> {
- viewManager.accessibilityValue(view, entry.string)
+ viewManager.accessibilityValue(view, entry.stringValue)
}
VP_ACCESSIBLE -> {
- viewManager.setAccessible(view, entry.boolean)
+ viewManager.setAccessible(view, entry.booleanValue)
}
VP_BACKFACE_VISIBILITY -> {
- viewManager.backfaceVisibility(view, entry.int)
+ viewManager.backfaceVisibility(view, entry.intValue)
}
VP_BG_COLOR -> {
// TODO: color for some reason can be object in Java but not in C++
- viewManager.backgroundColor(view, entry.int)
+ viewManager.backgroundColor(view, entry.intValue)
}
VP_BORDER_COLOR -> {
- viewManager.borderColor(view, entry.readableMapBuffer)
+ viewManager.borderColor(view, entry.mapBufferValue)
}
VP_BORDER_RADII -> {
- viewManager.borderRadius(view, entry.readableMapBuffer)
+ viewManager.borderRadius(view, entry.mapBufferValue)
}
VP_BORDER_STYLE -> {
- viewManager.borderStyle(view, entry.int)
+ viewManager.borderStyle(view, entry.intValue)
}
VP_ELEVATION -> {
- viewManager.setElevation(view, entry.double.toFloat())
+ viewManager.setElevation(view, entry.doubleValue.toFloat())
}
VP_FOCUSABLE -> {
- viewManager.setFocusable(view, entry.boolean)
+ viewManager.setFocusable(view, entry.booleanValue)
}
VP_HAS_TV_FOCUS -> {
- viewManager.setTVPreferredFocus(view, entry.boolean)
+ viewManager.setTVPreferredFocus(view, entry.booleanValue)
}
VP_HIT_SLOP -> {
- view.hitSlop(entry.readableMapBuffer)
+ view.hitSlop(entry.mapBufferValue)
}
VP_IMPORTANT_FOR_ACCESSIBILITY -> {
- view.importantForAccessibility(entry.int)
+ view.importantForAccessibility(entry.intValue)
}
VP_NATIVE_BACKGROUND -> {
- viewManager.nativeBackground(view, entry.readableMapBuffer)
+ viewManager.nativeBackground(view, entry.mapBufferValue)
}
VP_NATIVE_FOREGROUND -> {
- viewManager.nativeForeground(view, entry.readableMapBuffer)
+ viewManager.nativeForeground(view, entry.mapBufferValue)
}
VP_NATIVE_ID -> {
- viewManager.setNativeId(view, entry.string.takeIf { it.isNotEmpty() })
+ viewManager.setNativeId(view, entry.stringValue.takeIf { it.isNotEmpty() })
}
VP_OFFSCREEN_ALPHA_COMPOSITING -> {
- viewManager.setNeedsOffscreenAlphaCompositing(view, entry.boolean)
+ viewManager.setNeedsOffscreenAlphaCompositing(view, entry.booleanValue)
}
VP_OPACITY -> {
- viewManager.setOpacity(view, entry.double.toFloat())
+ viewManager.setOpacity(view, entry.doubleValue.toFloat())
}
VP_POINTER_EVENTS -> {
- view.pointerEvents(entry.int)
+ view.pointerEvents(entry.intValue)
}
VP_POINTER_ENTER -> {
- viewManager.setPointerEnter(view, entry.boolean)
+ viewManager.setPointerEnter(view, entry.booleanValue)
}
VP_POINTER_LEAVE -> {
- viewManager.setPointerLeave(view, entry.boolean)
+ viewManager.setPointerLeave(view, entry.booleanValue)
}
VP_POINTER_MOVE -> {
- viewManager.setPointerMove(view, entry.boolean)
+ viewManager.setPointerMove(view, entry.booleanValue)
}
VP_REMOVE_CLIPPED_SUBVIEW -> {
- viewManager.setRemoveClippedSubviews(view, entry.boolean)
+ viewManager.setRemoveClippedSubviews(view, entry.booleanValue)
}
VP_RENDER_TO_HARDWARE_TEXTURE -> {
- viewManager.setRenderToHardwareTexture(view, entry.boolean)
+ viewManager.setRenderToHardwareTexture(view, entry.booleanValue)
}
VP_SHADOW_COLOR -> {
// TODO: color for some reason can be object in Java but not in C++
- viewManager.shadowColor(view, entry.int)
+ viewManager.shadowColor(view, entry.intValue)
}
VP_TEST_ID -> {
- viewManager.setTestId(view, entry.string.takeIf { it.isNotEmpty() })
+ viewManager.setTestId(view, entry.stringValue.takeIf { it.isNotEmpty() })
}
VP_TRANSFORM -> {
- viewManager.transform(view, entry.readableMapBuffer)
+ viewManager.transform(view, entry.mapBufferValue)
}
VP_ZINDEX -> {
- viewManager.setZIndex(view, entry.int.toFloat())
+ viewManager.setZIndex(view, entry.intValue.toFloat())
}
YG_BORDER_WIDTH -> {
- viewManager.borderWidth(view, entry.readableMapBuffer)
+ viewManager.borderWidth(view, entry.mapBufferValue)
}
YG_OVERFLOW -> {
- viewManager.overflow(view, entry.int)
+ viewManager.overflow(view, entry.intValue)
}
}
}
}
- private fun ReactViewManager.accessibilityActions(
- view: ReactViewGroup,
- mapBuffer: ReadableMapBuffer
- ) {
+ private fun ReactViewManager.accessibilityActions(view: ReactViewGroup, mapBuffer: MapBuffer) {
val actions = mutableListOf()
for (entry in mapBuffer) {
val map = JavaOnlyMap()
- val action = entry.readableMapBuffer
+ val action = entry.mapBufferValue
if (action != null) {
map.putString("name", action.getString(ACCESSIBILITY_ACTION_NAME))
- if (action.hasKey(ACCESSIBILITY_ACTION_LABEL)) {
+ if (action.contains(ACCESSIBILITY_ACTION_LABEL)) {
map.putString("label", action.getString(ACCESSIBILITY_ACTION_LABEL))
}
}
@@ -245,7 +242,7 @@ object ReactMapBufferPropSetter {
ViewCompat.setAccessibilityLiveRegion(this, mode)
}
- private fun ReactViewManager.accessibilityState(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.accessibilityState(view: ReactViewGroup, value: MapBuffer) {
val accessibilityState = JavaOnlyMap()
accessibilityState.putBoolean("selected", value.getBoolean(ACCESSIBILITY_STATE_SELECTED))
accessibilityState.putBoolean("busy", value.getBoolean(ACCESSIBILITY_STATE_BUSY))
@@ -273,17 +270,14 @@ object ReactMapBufferPropSetter {
setAccessibilityValue(view, map)
}
- private fun ReactViewManager.accessibilityLabelledBy(
- view: ReactViewGroup,
- value: ReadableMapBuffer
- ) {
+ private fun ReactViewManager.accessibilityLabelledBy(view: ReactViewGroup, value: MapBuffer) {
val converted =
if (value.count == 0) {
DynamicFromObject(null)
} else {
val array = JavaOnlyArray()
for (label in value) {
- array.pushString(label.string)
+ array.pushString(label.stringValue)
}
DynamicFromObject(array)
}
@@ -306,7 +300,7 @@ object ReactMapBufferPropSetter {
setBackgroundColor(view, color)
}
- private fun ReactViewManager.borderColor(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.borderColor(view: ReactViewGroup, value: MapBuffer) {
for (entry in value) {
val index =
when (val key = entry.key) {
@@ -319,12 +313,12 @@ object ReactMapBufferPropSetter {
EDGE_END -> 6
else -> throw IllegalArgumentException("Unknown key for border color: $key")
}
- val colorValue = entry.int
+ val colorValue = entry.intValue
setBorderColor(view, index, colorValue.takeIf { it != -1 })
}
}
- private fun ReactViewManager.borderRadius(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.borderRadius(view: ReactViewGroup, value: MapBuffer) {
for (entry in value) {
val index =
when (val key = entry.key) {
@@ -339,7 +333,7 @@ object ReactMapBufferPropSetter {
CORNER_BOTTOM_END -> 8
else -> throw IllegalArgumentException("Unknown key for border style: $key")
}
- val borderRadius = entry.double
+ val borderRadius = entry.doubleValue
if (!borderRadius.isNaN()) {
setBorderRadius(view, index, borderRadius.toFloat())
}
@@ -357,7 +351,7 @@ object ReactMapBufferPropSetter {
setBorderStyle(view, stringValue)
}
- private fun ReactViewGroup.hitSlop(value: ReadableMapBuffer) {
+ private fun ReactViewGroup.hitSlop(value: MapBuffer) {
val rect =
Rect(
PixelUtil.toPixelFromDIP(value.getDouble(EDGE_LEFT)).toInt(),
@@ -392,15 +386,15 @@ object ReactMapBufferPropSetter {
setPointerEvents(pointerEvents)
}
- private fun ReactViewManager.transform(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.transform(view: ReactViewGroup, value: MapBuffer) {
val list = JavaOnlyArray()
for (entry in value) {
- list.pushDouble(entry.double)
+ list.pushDouble(entry.doubleValue)
}
setTransform(view, list)
}
- private fun ReactViewManager.borderWidth(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.borderWidth(view: ReactViewGroup, value: MapBuffer) {
for (entry in value) {
val index =
when (val key = entry.key) {
@@ -413,7 +407,7 @@ object ReactMapBufferPropSetter {
EDGE_END -> 6
else -> throw IllegalArgumentException("Unknown key for border width: $key")
}
- val borderWidth = entry.double
+ val borderWidth = entry.doubleValue
if (!borderWidth.isNaN()) {
setBorderWidth(view, index, borderWidth.toFloat())
}
@@ -437,15 +431,15 @@ object ReactMapBufferPropSetter {
setShadowColor(view, color)
}
- private fun ReactViewManager.nativeBackground(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.nativeBackground(view: ReactViewGroup, value: MapBuffer) {
setNativeBackground(view, value.toJsDrawableDescription())
}
- private fun ReactViewManager.nativeForeground(view: ReactViewGroup, value: ReadableMapBuffer) {
+ private fun ReactViewManager.nativeForeground(view: ReactViewGroup, value: MapBuffer) {
setNativeForeground(view, value.toJsDrawableDescription())
}
- private fun ReadableMapBuffer.toJsDrawableDescription(): ReadableMap? {
+ private fun MapBuffer.toJsDrawableDescription(): ReadableMap? {
if (count == 0) {
return null
}
@@ -459,11 +453,11 @@ object ReactMapBufferPropSetter {
}
1 -> {
result.putString("type", "RippleAndroid")
- if (hasKey(NATIVE_DRAWABLE_COLOR)) {
+ if (contains(NATIVE_DRAWABLE_COLOR)) {
result.putInt("color", getInt(NATIVE_DRAWABLE_COLOR))
}
result.putBoolean("borderless", getBoolean(NATIVE_DRAWABLE_BORDERLESS))
- if (hasKey(NATIVE_DRAWABLE_RIPPLE_RADIUS)) {
+ if (contains(NATIVE_DRAWABLE_RIPPLE_RADIUS)) {
result.putDouble("rippleRadius", getDouble(NATIVE_DRAWABLE_RIPPLE_RADIUS))
}
}