MCPcopy Create free account
hub / github.com/apecloud/myduckserver / encodeJsonArray

Function encodeJsonArray

binlogreplication/binlog_json_serialization.go:82–132  ·  view source on GitHub ↗

encodeJsonArray encodes the specified |jsonArray| into MySQL's internal JSON encoding and returns the type ID indicating whether this is a small or large array, the encoded array data, and any error encountered. The |largeEncoding| param controls whether this function will use the small array encodi

(jsonArray []any, largeEncoding bool)

Source from the content-addressed store, hash-verified

80// - Size: 2 bytes for small encoding, otherwise 4; total size of the encoded array (everything but the Type ID)
81// - Value Entries: 1 per value; 1 byte for type ID, variable sized offset (or inlined literal value)
82// - Values: 1 per value; encoded value bytes
83func encodeJsonArray(jsonArray []any, largeEncoding bool) (typeId byte, encodedArray []byte, err error) {
84 if !largeEncoding && len(jsonArray) > int(maxOffsetSize) {
85 return 0, nil, fmt.Errorf(
86 "too many elements in JSON array (%d) to serialize in small array encoding", len(jsonArray))
87 }
88
89 var valueEntriesBuffer []byte
90 var valuesBuffer []byte
91 nextValuesOffset := calculateInitialArrayValuesOffset(len(jsonArray), largeEncoding)
92
93 for _, element := range jsonArray {
94 typeId, encodedValue, err := encodeJsonValue(element)
95 if err != nil {
96 return 0, nil, err
97 }
98
99 // Literals can be inlined in the value-entries section
100 if typeId == jsonTypeLiteral {
101 valueEntriesBuffer = append(valueEntriesBuffer, typeId)
102 if len(encodedValue) != 1 {
103 return 0, nil, fmt.Errorf("unexpected buffer length")
104 }
105 valueEntriesBuffer = appendForEncoding(valueEntriesBuffer, uint32(encodedValue[0]), largeEncoding)
106 } else {
107 if !largeEncoding && nextValuesOffset > maxOffsetSize-uint32(len(encodedValue)) {
108 return 0, nil, fmt.Errorf("offset too large for small array encoding")
109 }
110
111 valueEntriesBuffer = append(valueEntriesBuffer, typeId)
112 valueEntriesBuffer = appendForEncoding(valueEntriesBuffer, nextValuesOffset, largeEncoding)
113 valuesBuffer = append(valuesBuffer, encodedValue...)
114 nextValuesOffset += uint32(len(encodedValue))
115 }
116 }
117
118 // element count (uint16 for small arrays)
119 encodedArray = appendForEncoding(encodedArray, uint32(len(jsonArray)), largeEncoding)
120
121 // Grab the total size of the array data from the next offset position pointing to the end of the values buffer
122 arrayPayloadLength := nextValuesOffset
123
124 encodedArray = appendForEncoding(encodedArray, arrayPayloadLength, largeEncoding)
125 encodedArray = append(encodedArray, valueEntriesBuffer...)
126 encodedArray = append(encodedArray, valuesBuffer...)
127
128 if !largeEncoding {
129 return jsonTypeSmallArray, encodedArray, nil
130 } else {
131 return jsonTypeLargeArray, encodedArray, nil
132 }
133}
134
135// encodeJsonObject encodes the specified |jsonObject| into MySQL's internal JSON encoding and returns

Callers 1

encodeJsonValueFunction · 0.85

Calls 3

encodeJsonValueFunction · 0.85
appendForEncodingFunction · 0.85

Tested by

no test coverage detected