/
Table.java
322 lines (297 loc) · 11.2 KB
/
Table.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/// @cond FLATBUFFERS_INTERNAL
/**
* All tables in the generated code derive from this class, and add their own accessors.
*/
public class Table {
/** Used to hold the position of the `bb` buffer. */
protected int bb_pos;
/** The underlying ByteBuffer to hold the data of the Table. */
protected ByteBuffer bb;
/** Used to hold the vtable position. */
private int vtable_start;
/** Used to hold the vtable size. */
private int vtable_size;
Utf8 utf8 = Utf8.getDefault();
/**
* Get the underlying ByteBuffer.
*
* @return Returns the Table's ByteBuffer.
*/
public ByteBuffer getByteBuffer() { return bb; }
/**
* Look up a field in the vtable.
*
* @param vtable_offset An `int` offset to the vtable in the Table's ByteBuffer.
* @return Returns an offset into the object, or `0` if the field is not present.
*/
protected int __offset(int vtable_offset) {
return vtable_offset < vtable_size ? bb.getShort(vtable_start + vtable_offset) : 0;
}
protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
int vtable = bb.capacity() - offset;
return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
}
/**
* Retrieve a relative offset.
*
* @param offset An `int` index into the Table's ByteBuffer containing the relative offset.
* @return Returns the relative offset stored at `offset`.
*/
protected int __indirect(int offset) {
return offset + bb.getInt(offset);
}
/**
* Retrieve a relative offset.
*
* @param offset An `int` index into a ByteBuffer containing the relative offset.
* @param bb from which the relative offset will be retrieved.
* @return Returns the relative offset stored at `offset`.
*/
protected static int __indirect(int offset, ByteBuffer bb) {
return offset + bb.getInt(offset);
}
/**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
*
* This allocates a new string and converts to wide chars upon each access,
* which is not very efficient. Instead, each FlatBuffer string also comes with an
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
* assuming your Java program can handle UTF-8 data directly.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
*/
protected String __string(int offset) {
return __string(offset, bb, utf8);
}
/**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
*
* This allocates a new string and converts to wide chars upon each access,
* which is not very efficient. Instead, each FlatBuffer string also comes with an
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
* assuming your Java program can handle UTF-8 data directly.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to read a string at given offset.
* @param utf8 decoder that creates a Java `String` from UTF-8 characters.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
*/
protected static String __string(int offset, ByteBuffer bb, Utf8 utf8) {
offset += bb.getInt(offset);
int length = bb.getInt(offset);
return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
}
/**
* Get the length of a vector.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @return Returns the length of the vector whose offset is stored at `offset`.
*/
protected int __vector_len(int offset) {
offset += bb_pos;
offset += bb.getInt(offset);
return bb.getInt(offset);
}
/**
* Get the start data of a vector.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @return Returns the start of the vector data whose offset is stored at `offset`.
*/
protected int __vector(int offset) {
offset += bb_pos;
return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length
}
/**
* Get a whole vector as a ByteBuffer.
*
* This is efficient, since it only allocates a new {@link ByteBuffer} object,
* but does not actually copy the data, it still refers to the same bytes
* as the original ByteBuffer. Also useful with nested FlatBuffers, etc.
*
* @param vector_offset The position of the vector in the byte buffer
* @param elem_size The size of each element in the array
* @return The {@link ByteBuffer} for the array
*/
protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) {
int o = __offset(vector_offset);
if (o == 0) return null;
ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN);
int vectorstart = __vector(o);
bb.position(vectorstart);
bb.limit(vectorstart + __vector_len(o) * elem_size);
return bb;
}
/**
* Initialize vector as a ByteBuffer.
*
* This is more efficient than using duplicate, since it doesn't copy the data
* nor allocattes a new {@link ByteBuffer}, creating no garbage to be collected.
*
* @param bb The {@link ByteBuffer} for the array
* @param vector_offset The position of the vector in the byte buffer
* @param elem_size The size of each element in the array
* @return The {@link ByteBuffer} for the array
*/
protected ByteBuffer __vector_in_bytebuffer(ByteBuffer bb, int vector_offset, int elem_size) {
int o = this.__offset(vector_offset);
if (o == 0) return null;
int vectorstart = __vector(o);
bb.rewind();
bb.limit(vectorstart + __vector_len(o) * elem_size);
bb.position(vectorstart);
return bb;
}
/**
* Initialize any Table-derived type to point to the union at the given `offset`.
*
* @param t A `Table`-derived type that should point to the union at `offset`.
* @param offset An `int` index into the Table's ByteBuffer.
* @return Returns the Table that points to the union at `offset`.
*/
protected Table __union(Table t, int offset) {
return __union(t, offset, bb);
}
/**
* Initialize any Table-derived type to point to the union at the given `offset`.
*
* @param t A `Table`-derived type that should point to the union at `offset`.
* @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to initialize the object Table-derived type.
* @return Returns the Table that points to the union at `offset`.
*/
protected static Table __union(Table t, int offset, ByteBuffer bb) {
t.__reset(__indirect(offset, bb), bb);
return t;
}
/**
* Check if a {@link ByteBuffer} contains a file identifier.
*
* @param bb A {@code ByteBuffer} to check if it contains the identifier
* `ident`.
* @param ident A `String` identifier of the FlatBuffer file.
* @return True if the buffer contains the file identifier
*/
protected static boolean __has_identifier(ByteBuffer bb, String ident) {
if (ident.length() != FILE_IDENTIFIER_LENGTH)
throw new AssertionError("FlatBuffers: file identifier must be length " +
FILE_IDENTIFIER_LENGTH);
for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) {
if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false;
}
return true;
}
/**
* Sort tables by the key.
*
* @param offsets An 'int' indexes of the tables into the bb.
* @param bb A {@code ByteBuffer} to get the tables.
*/
protected void sortTables(int[] offsets, final ByteBuffer bb) {
Integer[] off = new Integer[offsets.length];
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
public int compare(Integer o1, Integer o2) {
return keysCompare(o1, o2, bb);
}
});
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
}
/**
* Compare two tables by the key.
*
* @param o1 An 'Integer' index of the first key into the bb.
* @param o2 An 'Integer' index of the second key into the bb.
* @param bb A {@code ByteBuffer} to get the keys.
*/
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
/**
* Compare two strings in the buffer.
*
* @param offset_1 An 'int' index of the first string into the bb.
* @param offset_2 An 'int' index of the second string into the bb.
* @param bb A {@code ByteBuffer} to get the strings.
*/
protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) {
offset_1 += bb.getInt(offset_1);
offset_2 += bb.getInt(offset_2);
int len_1 = bb.getInt(offset_1);
int len_2 = bb.getInt(offset_2);
int startPos_1 = offset_1 + SIZEOF_INT;
int startPos_2 = offset_2 + SIZEOF_INT;
int len = Math.min(len_1, len_2);
for(int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
return bb.get(i + startPos_1) - bb.get(i + startPos_2);
}
return len_1 - len_2;
}
/**
* Compare string from the buffer with the 'String' object.
*
* @param offset_1 An 'int' index of the first string into the bb.
* @param key Second string as a byte array.
* @param bb A {@code ByteBuffer} to get the first string.
*/
protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) {
offset_1 += bb.getInt(offset_1);
int len_1 = bb.getInt(offset_1);
int len_2 = key.length;
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
int len = Math.min(len_1, len_2);
for (int i = 0; i < len; i++) {
if (bb.get(i + startPos_1) != key[i])
return bb.get(i + startPos_1) - key[i];
}
return len_1 - len_2;
}
/**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references.
*/
protected void __reset(int _i, ByteBuffer _bb) {
bb = _bb;
if (bb != null) {
bb_pos = _i;
vtable_start = bb_pos - bb.getInt(bb_pos);
vtable_size = bb.getShort(vtable_start);
} else {
bb_pos = 0;
vtable_start = 0;
vtable_size = 0;
}
}
/**
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
* again to a {@code ByteBuffer}.
*/
public void __reset() {
__reset(0, null);
}
}
/// @endcond