| | 1 | | using System; |
| | 2 | | using System.Collections.Generic; |
| | 3 | | using KernelCommunication; |
| | 4 | |
|
| | 5 | | namespace DCL.CRDT |
| | 6 | | { |
| | 7 | | // Deserialize CRDT binary messages (BigEndian) |
| | 8 | | public static class CRDTDeserializer |
| | 9 | | { |
| 1 | 10 | | internal static readonly CRDTComponentMessageHeader componentHeader = new CRDTComponentMessageHeader(); |
| | 11 | |
|
| | 12 | | public static IEnumerator<object> DeserializeBatch(ReadOnlyMemory<byte> memory) |
| | 13 | | { |
| 8 | 14 | | int position = 0; |
| | 15 | |
|
| 17 | 16 | | while (position < memory.Length) |
| | 17 | | { |
| 11 | 18 | | int messageLength = ByteUtils.ReadInt32(memory.Span, position); |
| 11 | 19 | | position += 4; |
| | 20 | |
|
| 11 | 21 | | CrdtMessageType messageType = (CrdtMessageType)ByteUtils.ReadInt32(memory.Span, position); |
| 11 | 22 | | position += 4; |
| | 23 | |
|
| 11 | 24 | | if (messageLength <= CrdtConstants.MESSAGE_HEADER_LENGTH) |
| | 25 | | { |
| | 26 | | continue; |
| | 27 | | } |
| | 28 | |
|
| | 29 | | switch (messageType) |
| | 30 | | { |
| | 31 | | case CrdtMessageType.PUT_COMPONENT: |
| | 32 | | case CrdtMessageType.DELETE_COMPONENT: |
| 10 | 33 | | yield return DeserializeSingle(memory, messageType, ref position); |
| 8 | 34 | | break; |
| | 35 | | default: |
| 1 | 36 | | position += messageLength - CrdtConstants.MESSAGE_HEADER_LENGTH; |
| | 37 | | break; |
| | 38 | | } |
| | 39 | | } |
| 6 | 40 | | } |
| | 41 | |
|
| | 42 | | public static CRDTMessage DeserializeSingle(ReadOnlyMemory<byte> memory, CrdtMessageType messageType, ref int me |
| | 43 | | { |
| 12 | 44 | | ReadOnlySpan<byte> memorySpan = memory.Span; |
| | 45 | |
|
| 12 | 46 | | componentHeader.entityId = ByteUtils.ReadInt32(memorySpan, memoryPosition); |
| 12 | 47 | | memoryPosition += 4; |
| 12 | 48 | | componentHeader.componentClassId = ByteUtils.ReadInt32(memorySpan, memoryPosition); |
| 12 | 49 | | memoryPosition += 4; |
| 12 | 50 | | componentHeader.timestamp = ByteUtils.ReadInt64(memorySpan, memoryPosition); |
| 12 | 51 | | memoryPosition += 8; |
| 12 | 52 | | componentHeader.dataLength = ByteUtils.ReadInt32(memorySpan, memoryPosition); |
| 12 | 53 | | memoryPosition += 4; |
| | 54 | |
|
| 12 | 55 | | byte[] data = null; |
| 12 | 56 | | if (componentHeader.dataLength > 0 && messageType != CrdtMessageType.DELETE_COMPONENT) |
| | 57 | | { |
| 9 | 58 | | data = memorySpan.Slice(memoryPosition, componentHeader.dataLength).ToArray(); |
| 9 | 59 | | } |
| 3 | 60 | | else if (messageType == CrdtMessageType.PUT_COMPONENT) |
| | 61 | | { |
| 2 | 62 | | data = new byte[0]; |
| | 63 | | } |
| 12 | 64 | | memoryPosition += componentHeader.dataLength; |
| | 65 | |
|
| 12 | 66 | | return new CRDTMessage() |
| | 67 | | { |
| | 68 | | key1 = componentHeader.entityId, |
| | 69 | | key2 = componentHeader.componentClassId, |
| | 70 | | timestamp = componentHeader.timestamp, |
| | 71 | | data = data |
| | 72 | | }; |
| | 73 | | } |
| | 74 | | } |
| | 75 | | } |