Skip to content

Commit

Permalink
fix(android): support sparse array for call ui function
Browse files Browse the repository at this point in the history
  • Loading branch information
siguangli2018 authored and zealotchen0 committed Aug 2, 2023
1 parent 3f28b9e commit 0b06be7
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static com.tencent.renderer.NativeRenderException.ExceptionCode.DESERIALIZE_NOT_SUPPORTED_ERR;
import static com.tencent.renderer.NativeRenderException.ExceptionCode.DESERIALIZE_READ_LENGTH_ERR;

import com.tencent.mtt.hippy.exception.UnexpectedException;
import com.tencent.mtt.hippy.serialization.PrimitiveSerializationTag;
import com.tencent.mtt.hippy.serialization.exception.DataCloneOutOfRangeException;
import com.tencent.mtt.hippy.serialization.PrimitiveValueDeserializer;
Expand Down Expand Up @@ -77,6 +78,8 @@ protected Object readValue(byte tag, StringLocation location, Object relatedKey)
return readMap();
case SerializationTag.BEGIN_DENSE_ARRAY:
return readDenseArray();
case SerializationTag.BEGIN_SPARSE_JS_ARRAY:
return readSparseArray();
default:
throw createUnsupportedTagException(tag);
}
Expand Down Expand Up @@ -195,6 +198,61 @@ private List<Object> readDenseArray() {
return array;
}


/**
* Reads Spare Array from buffer.
*
* <h2>Note</h2>
* Sparse arrays will be serialized as an object-like manner. Normally, it should be representable
* as {@link ArrayList}, but in order to be compatible with the previous serialization implement,
* we use {@link ArrayList} to express sparse arrays. <br/> When a hole is encountered, null is
* used to fill it.
* @return array
*/
private List<Object> readSparseArray() {
long length = reader.getVarint();
List<Object> array = new ArrayList<>();
assignId(array);
byte tag;
int read = 0;
while ((tag = readTag()) != SerializationTag.END_SPARSE_JS_ARRAY) {
read++;
Object key = readValue(tag, StringLocation.SPARSE_ARRAY_KEY, null);
Object value = readValue(StringLocation.SPARSE_ARRAY_ITEM, key);
int index = -1;
if (key instanceof Number) {
index = ((Number) key).intValue();
} else if (key instanceof String) {
try {
index = Integer.parseInt((String) key);
} catch (NumberFormatException ignored) {
// ignore not parsable string
}
}
if (index >= 0) {
int spaceNeeded = (index + 1) - array.size();
if (spaceNeeded
== 1) { // Fast path, item are ordered in general ECMAScript(VM) implementation
array.add(value);
} else { // Slow path, universal
for (int i = 0; i < spaceNeeded; i++) {
array.add(null);
}
array.set(index, value);
}
}
}
int expected = (int) reader.getVarint();
if (read != expected) {
throw new UnexpectedException("unexpected number of properties");
}
long length2 = reader.getVarint();
if (length != length2) {
throw new AssertionError("length ambiguity");
}
return array;
}

@Override
protected Object getHole() {
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ public interface SerializationTag {
byte END_OBJECT = (byte) '{';
byte BEGIN_DENSE_ARRAY = (byte) 'A';
byte END_DENSE_ARRAY = (byte) '$';
byte BEGIN_SPARSE_JS_ARRAY = (byte) 'a'; // kBeginSparseJSArray
byte END_SPARSE_JS_ARRAY = (byte) '@'; // kEndSparseJSArray
}

0 comments on commit 0b06be7

Please sign in to comment.