55
66package com .vesoft .nebula .driver .graph .decode ;
77
8+ import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .CHUNK_INDEX_START_POSITION_IN_STRING_HEADER ;
9+ import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .CHUNK_OFFSET_START_POSITION_IN_STRING_HEADER ;
810import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .ELEMENT_NUMBER_SIZE_FOR_ANY_VALUE ;
11+ import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .STRING_MAX_VALUE_LENGTH_IN_HEADER ;
12+ import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .STRING_SIZE ;
13+ import static com .vesoft .nebula .driver .graph .decode .struct .SizeConstant .STRING_VALUE_LENGTH_SIZE ;
914
1015import com .google .protobuf .ByteString ;
1116import com .vesoft .nebula .driver .graph .decode .datatype .VectorType ;
1823public class DecodeUtils {
1924 public static final Charset charset = Charsets .UTF_8 ;
2025
26+ /**
27+ * decode binary to int directly from ByteString without creating sub-byteString
28+ *
29+ * @param data binary data
30+ * @param offset offset in the data
31+ * @param order byte order
32+ * @return int value
33+ */
34+ public static int bytesToInt32AtOffset (ByteString data , int offset , ByteOrder order ) {
35+ if (order == ByteOrder .LITTLE_ENDIAN ) {
36+ return (data .byteAt (offset ) & 0xFF )
37+ | ((data .byteAt (offset + 1 ) & 0xFF ) << 8 )
38+ | ((data .byteAt (offset + 2 ) & 0xFF ) << 16 )
39+ | ((data .byteAt (offset + 3 ) & 0xFF ) << 24 );
40+ } else {
41+ return (data .byteAt (offset ) << 24 )
42+ | ((data .byteAt (offset + 1 ) & 0xFF ) << 16 )
43+ | ((data .byteAt (offset + 2 ) & 0xFF ) << 8 )
44+ | (data .byteAt (offset + 3 ) & 0xFF );
45+ }
46+ }
47+
48+ /**
49+ * decode binary to long directly from ByteString without creating sub-byteString
50+ *
51+ * @param data binary data
52+ * @param offset offset in the data
53+ * @param order byte order
54+ * @return long value
55+ */
56+ public static long bytesToInt64AtOffset (ByteString data , int offset , ByteOrder order ) {
57+ if (order == ByteOrder .LITTLE_ENDIAN ) {
58+ return (long ) (data .byteAt (offset ) & 0xFF )
59+ | ((long ) (data .byteAt (offset + 1 ) & 0xFF ) << 8 )
60+ | ((long ) (data .byteAt (offset + 2 ) & 0xFF ) << 16 )
61+ | ((long ) (data .byteAt (offset + 3 ) & 0xFF ) << 24 )
62+ | ((long ) (data .byteAt (offset + 4 ) & 0xFF ) << 32 )
63+ | ((long ) (data .byteAt (offset + 5 ) & 0xFF ) << 40 )
64+ | ((long ) (data .byteAt (offset + 6 ) & 0xFF ) << 48 )
65+ | ((long ) (data .byteAt (offset + 7 ) & 0xFF ) << 56 );
66+ } else {
67+ return ((long ) data .byteAt (offset ) << 56 )
68+ | ((long ) (data .byteAt (offset + 1 ) & 0xFF ) << 48 )
69+ | ((long ) (data .byteAt (offset + 2 ) & 0xFF ) << 40 )
70+ | ((long ) (data .byteAt (offset + 3 ) & 0xFF ) << 32 )
71+ | ((long ) (data .byteAt (offset + 4 ) & 0xFF ) << 24 )
72+ | ((long ) (data .byteAt (offset + 5 ) & 0xFF ) << 16 )
73+ | ((long ) (data .byteAt (offset + 6 ) & 0xFF ) << 8 )
74+ | (data .byteAt (offset + 7 ) & 0xFF );
75+ }
76+ }
77+
2178 /**
2279 * decode binary to byte
2380 *
@@ -38,15 +95,43 @@ public static int bytesToUInt8(ByteString data) {
3895 return data .byteAt (0 ) & 0xFF ;
3996 }
4097
98+ /**
99+ * decode binary to byte at offset
100+ *
101+ * @param data binary data
102+ * @param offset offset in the data
103+ * @return int value
104+ */
105+ public static int bytesToInt8AtOffset (ByteString data , int offset ) {
106+ return data .byteAt (offset );
107+ }
108+
109+ /**
110+ * decode binary to unsigned byte at offset
111+ *
112+ * @param data binary data
113+ * @param offset offset in the data
114+ * @return uint value
115+ */
116+ public static int bytesToUInt8AtOffset (ByteString data , int offset ) {
117+ return data .byteAt (offset ) & 0xFF ;
118+ }
119+
41120 /**
42121 * decode binary to short
43122 *
44123 * @param data binary data
45124 * @return short value
46125 */
47126 public static Short bytesToInt16 (ByteString data , ByteOrder order ) {
48- ByteBuffer buffer = ByteBuffer .wrap (data .toByteArray ());
49- return buffer .order (order ).getShort ();
127+ if (data .size () < 2 ) {
128+ throw new java .nio .BufferUnderflowException ();
129+ }
130+ if (order == ByteOrder .LITTLE_ENDIAN ) {
131+ return (short ) ((data .byteAt (0 ) & 0xFF ) | ((data .byteAt (1 ) & 0xFF ) << 8 ));
132+ } else {
133+ return (short ) ((data .byteAt (0 ) << 8 ) | (data .byteAt (1 ) & 0xFF ));
134+ }
50135 }
51136
52137 /**
@@ -59,15 +144,55 @@ public static int bytesToUInt16(ByteString data, ByteOrder order) {
59144 return bytesToInt16 (data , order ) & 0xFFFF ;
60145 }
61146
147+ /**
148+ * decode binary to unsigned short at offset
149+ *
150+ * @param data binary data
151+ * @param offset offset in the data
152+ * @param order byte order
153+ * @return short value
154+ */
155+ public static int bytesToUInt16AtOffset (ByteString data , int offset , ByteOrder order ) {
156+ return bytesToInt16AtOffset (data , offset , order ) & 0xFFFF ;
157+ }
158+
159+ /**
160+ * decode binary to short at offset
161+ *
162+ * @param data binary data
163+ * @param offset offset in the data
164+ * @param order byte order
165+ * @return short value
166+ */
167+ public static short bytesToInt16AtOffset (ByteString data , int offset , ByteOrder order ) {
168+ if (order == ByteOrder .LITTLE_ENDIAN ) {
169+ return (short ) ((data .byteAt (offset ) & 0xFF ) | ((data .byteAt (offset + 1 ) & 0xFF ) << 8 ));
170+ } else {
171+ return (short ) ((data .byteAt (offset ) << 8 ) | (data .byteAt (offset + 1 ) & 0xFF ));
172+ }
173+ }
174+
62175 /**
63176 * decode binary to int
64177 *
65178 * @param data binary data
66179 * @return int value
67180 */
68181 public static int bytesToInt32 (ByteString data , ByteOrder order ) {
69- ByteBuffer buffer = ByteBuffer .wrap (data .toByteArray ());
70- return buffer .order (order ).getInt ();
182+ if (data .size () < 4 ) {
183+ throw new java .nio .BufferUnderflowException ();
184+ }
185+ if (order == ByteOrder .LITTLE_ENDIAN ) {
186+ return (data .byteAt (0 ) & 0xFF )
187+ | ((data .byteAt (1 ) & 0xFF ) << 8 )
188+ | ((data .byteAt (2 ) & 0xFF ) << 16 )
189+ | ((data .byteAt (3 ) & 0xFF ) << 24 );
190+ } else {
191+ return (data .byteAt (0 ) << 24 )
192+ | ((data .byteAt (1 ) & 0xFF ) << 16 )
193+ | ((data .byteAt (2 ) & 0xFF ) << 8 )
194+ | (data .byteAt (3 ) & 0xFF );
195+ }
71196 }
72197
73198
@@ -81,15 +206,109 @@ public static long bytesToUInt32(ByteString data, ByteOrder order) {
81206 return Integer .toUnsignedLong (bytesToInt32 (data , order ));
82207 }
83208
209+ /**
210+ * decode binary to float at offset
211+ *
212+ * @param data binary data
213+ * @param offset offset in the data
214+ * @param order byte order
215+ * @return float value
216+ */
217+ public static float bytesToFloatAtOffset (ByteString data , int offset , ByteOrder order ) {
218+ int bits = bytesToInt32AtOffset (data , offset , order );
219+ return Float .intBitsToFloat (bits );
220+ }
221+
222+ /**
223+ * decode binary to double at offset
224+ *
225+ * @param data binary data
226+ * @param offset offset in the data
227+ * @param order byte order
228+ * @return double value
229+ */
230+ public static double bytesToDoubleAtOffset (ByteString data , int offset , ByteOrder order ) {
231+ long bits = bytesToInt64AtOffset (data , offset , order );
232+ return Double .longBitsToDouble (bits );
233+ }
234+
235+ /**
236+ * decode binary to bool at offset
237+ *
238+ * @param data binary data
239+ * @param offset offset in the data
240+ * @return Boolean value
241+ */
242+ public static boolean bytesToBoolAtOffset (ByteString data , int offset ) {
243+ return data .byteAt (offset ) == 0x01 ;
244+ }
245+
246+ /**
247+ * decode flat string directly from vector data at specified row
248+ *
249+ * @param vectorData vector data
250+ * @param rowIndex row index
251+ * @param order byte order
252+ * @return String value
253+ */
254+ public static String decodeFlatString (ByteString vectorData , int rowIndex , ByteOrder order ) {
255+ int offset = rowIndex * STRING_SIZE ;
256+
257+ // Read string length
258+ int stringValueLength = bytesToInt32AtOffset (vectorData , offset , order );
259+
260+ if (stringValueLength <= STRING_MAX_VALUE_LENGTH_IN_HEADER ) {
261+ // Short string: data is in the header
262+ int dataOffset = offset + STRING_VALUE_LENGTH_SIZE ;
263+ return vectorData .substring (dataOffset , dataOffset + stringValueLength )
264+ .toString (charset );
265+ }
266+
267+ // Long string: read chunk index and offset
268+ int chunkIndex = bytesToInt32AtOffset (
269+ vectorData ,
270+ offset + CHUNK_INDEX_START_POSITION_IN_STRING_HEADER ,
271+ order );
272+ int chunkOffset = bytesToInt32AtOffset (
273+ vectorData ,
274+ offset + CHUNK_OFFSET_START_POSITION_IN_STRING_HEADER ,
275+ order );
276+
277+ // Note: For flat string, we can't access nested vectors without passing them
278+ // This method is optimized for the common case where the string is short
279+ // For long strings, fallback to the original bytesToString method
280+ return null ;
281+ }
282+
84283 /**
85284 * decode binary to long
86285 *
87286 * @param data binary data
88287 * @return long value
89288 */
90289 public static long bytesToInt64 (ByteString data , ByteOrder order ) {
91- ByteBuffer buffer = ByteBuffer .wrap (data .toByteArray ());
92- return buffer .order (order ).getLong ();
290+ if (data .size () < 8 ) {
291+ throw new java .nio .BufferUnderflowException ();
292+ }
293+ if (order == ByteOrder .LITTLE_ENDIAN ) {
294+ return (long ) (data .byteAt (0 ) & 0xFF )
295+ | ((long ) (data .byteAt (1 ) & 0xFF ) << 8 )
296+ | ((long ) (data .byteAt (2 ) & 0xFF ) << 16 )
297+ | ((long ) (data .byteAt (3 ) & 0xFF ) << 24 )
298+ | ((long ) (data .byteAt (4 ) & 0xFF ) << 32 )
299+ | ((long ) (data .byteAt (5 ) & 0xFF ) << 40 )
300+ | ((long ) (data .byteAt (6 ) & 0xFF ) << 48 )
301+ | ((long ) (data .byteAt (7 ) & 0xFF ) << 56 );
302+ } else {
303+ return ((long ) data .byteAt (0 ) << 56 )
304+ | ((long ) (data .byteAt (1 ) & 0xFF ) << 48 )
305+ | ((long ) (data .byteAt (2 ) & 0xFF ) << 40 )
306+ | ((long ) (data .byteAt (3 ) & 0xFF ) << 32 )
307+ | ((long ) (data .byteAt (4 ) & 0xFF ) << 24 )
308+ | ((long ) (data .byteAt (5 ) & 0xFF ) << 16 )
309+ | ((long ) (data .byteAt (6 ) & 0xFF ) << 8 )
310+ | (data .byteAt (7 ) & 0xFF );
311+ }
93312 }
94313
95314
@@ -100,8 +319,8 @@ public static long bytesToInt64(ByteString data, ByteOrder order) {
100319 * @return float value
101320 */
102321 public static float bytesToFloat (ByteString data , ByteOrder order ) {
103- ByteBuffer buffer = ByteBuffer . wrap (data . toByteArray () );
104- return buffer . order ( order ). getFloat ( );
322+ int bits = bytesToInt32 (data , order );
323+ return Float . intBitsToFloat ( bits );
105324 }
106325
107326 /**
@@ -111,8 +330,8 @@ public static float bytesToFloat(ByteString data, ByteOrder order) {
111330 * @return double value
112331 */
113332 public static double bytesToDouble (ByteString data , ByteOrder order ) {
114- ByteBuffer buffer = ByteBuffer . wrap (data . toByteArray () );
115- return buffer . order ( order ). getDouble ( );
333+ long bits = bytesToInt64 (data , order );
334+ return Double . longBitsToDouble ( bits );
116335 }
117336
118337 /**
0 commit comments