126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen/* 226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * Copyright 2014 Google Inc. All rights reserved. 326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * 426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * Licensed under the Apache License, Version 2.0 (the "License"); 526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * you may not use this file except in compliance with the License. 626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * You may obtain a copy of the License at 726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * 826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * http://www.apache.org/licenses/LICENSE-2.0 926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * 1026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * Unless required by applicable law or agreed to in writing, software 1126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * distributed under the License is distributed on an "AS IS" BASIS, 1226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * See the License for the specific language governing permissions and 1426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen * limitations under the License. 1526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen */ 1626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 17c01c77a7f2d4e01b3fc21bf85b1c5427a00911d5Wouter van Oortmerssenpackage com.google.flatbuffers; 1826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 19c01c77a7f2d4e01b3fc21bf85b1c5427a00911d5Wouter van Oortmerssenimport static com.google.flatbuffers.Constants.*; 2026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssenimport java.nio.ByteBuffer; 214d3db99283199ffd8d5fdbe84933444d25b980f4pjulienimport java.nio.ByteOrder; 22286587d1516376f24072f9c88b1d68e46b01e642pjulienimport java.nio.CharBuffer; 23286587d1516376f24072f9c88b1d68e46b01e642pjulienimport java.nio.charset.CharacterCodingException; 24286587d1516376f24072f9c88b1d68e46b01e642pjulienimport java.nio.charset.Charset; 25286587d1516376f24072f9c88b1d68e46b01e642pjulienimport java.nio.charset.CharsetDecoder; 26286587d1516376f24072f9c88b1d68e46b01e642pjulienimport java.nio.charset.CoderResult; 2726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 2869a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara/// @cond FLATBUFFERS_INTERNAL 2969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara 3069a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara/** 3169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * All tables in the generated code derive from this class, and add their own accessors. 3269a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 33e14bc1d9ac8091426235f9db9d7acb645f043d48bmlpublic class Table { 34286587d1516376f24072f9c88b1d68e46b01e642pjulien private final static ThreadLocal<CharsetDecoder> UTF8_DECODER = new ThreadLocal<CharsetDecoder>() { 35286587d1516376f24072f9c88b1d68e46b01e642pjulien @Override 36286587d1516376f24072f9c88b1d68e46b01e642pjulien protected CharsetDecoder initialValue() { 37286587d1516376f24072f9c88b1d68e46b01e642pjulien return Charset.forName("UTF-8").newDecoder(); 38286587d1516376f24072f9c88b1d68e46b01e642pjulien } 39286587d1516376f24072f9c88b1d68e46b01e642pjulien }; 40e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() { 41e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen @Override 42e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen protected Charset initialValue() { 43e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen return Charset.forName("UTF-8"); 44e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen } 45e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen }; 46286587d1516376f24072f9c88b1d68e46b01e642pjulien private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>(); 4769a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** Used to hold the position of the `bb` buffer. */ 4826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected int bb_pos; 4969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** The underlying ByteBuffer to hold the data of the Table. */ 5026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected ByteBuffer bb; 5126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 5269a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 5369a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Get the underlying ByteBuffer. 5469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 5569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns the Table's ByteBuffer. 5669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 57fbe085601b418d476e87bcaba6a968c99b3f0a00Wouter van Oortmerssen public ByteBuffer getByteBuffer() { return bb; } 58fbe085601b418d476e87bcaba6a968c99b3f0a00Wouter van Oortmerssen 5969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 6069a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Look up a field in the vtable. 6169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 6269a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param vtable_offset An `int` offset to the vtable in the Table's ByteBuffer. 6369a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns an offset into the object, or `0` if the field is not present. 6469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 658fdced4e1141a98fb37e952058874423702347caTGIshib protected int __offset(int vtable_offset) { 668fdced4e1141a98fb37e952058874423702347caTGIshib int vtable = bb_pos - bb.getInt(bb_pos); 678fdced4e1141a98fb37e952058874423702347caTGIshib return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0; 688fdced4e1141a98fb37e952058874423702347caTGIshib } 69dc7f5bc0d80730ef45b368be90ac1208c1394707TGIshib 708fdced4e1141a98fb37e952058874423702347caTGIshib protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) { 71625c9898754a491a1c195743eafdb22908e4102cAlex Wasserman int vtable = bb.capacity() - offset; 728fdced4e1141a98fb37e952058874423702347caTGIshib return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable; 7326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 7426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 7569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 7669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Retrieve a relative offset. 7769a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 7869a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param offset An `int` index into the Table's ByteBuffer containing the relative offset. 7969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns the relative offset stored at `offset`. 8069a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 8126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected int __indirect(int offset) { 8226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen return offset + bb.getInt(offset); 8326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 84e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen 859f16090f901c30f872422f60db21a0370dde8bbfTGIshib protected static int __indirect(int offset, ByteBuffer bb) { 869f16090f901c30f872422f60db21a0370dde8bbfTGIshib return offset + bb.getInt(offset); 879f16090f901c30f872422f60db21a0370dde8bbfTGIshib } 8826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 8969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 9069a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Create a Java `String` from UTF-8 data stored inside the FlatBuffer. 9169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 9269a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * This allocates a new string and converts to wide chars upon each access, 9369a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * which is not very efficient. Instead, each FlatBuffer string also comes with an 9469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * accessor based on __vector_as_bytebuffer below, which is much more efficient, 9569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * assuming your Java program can handle UTF-8 data directly. 9669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 9769a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param offset An `int` index into the Table's ByteBuffer. 9869a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`. 9969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 10026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected String __string(int offset) { 101286587d1516376f24072f9c88b1d68e46b01e642pjulien CharsetDecoder decoder = UTF8_DECODER.get(); 102286587d1516376f24072f9c88b1d68e46b01e642pjulien decoder.reset(); 103286587d1516376f24072f9c88b1d68e46b01e642pjulien 1048fdced4e1141a98fb37e952058874423702347caTGIshib offset += bb.getInt(offset); 1058fdced4e1141a98fb37e952058874423702347caTGIshib ByteBuffer src = bb.duplicate().order(ByteOrder.LITTLE_ENDIAN); 106286587d1516376f24072f9c88b1d68e46b01e642pjulien int length = src.getInt(offset); 107286587d1516376f24072f9c88b1d68e46b01e642pjulien src.position(offset + SIZEOF_INT); 108286587d1516376f24072f9c88b1d68e46b01e642pjulien src.limit(offset + SIZEOF_INT + length); 109286587d1516376f24072f9c88b1d68e46b01e642pjulien 110286587d1516376f24072f9c88b1d68e46b01e642pjulien int required = (int)((float)length * decoder.maxCharsPerByte()); 111286587d1516376f24072f9c88b1d68e46b01e642pjulien CharBuffer dst = CHAR_BUFFER.get(); 112286587d1516376f24072f9c88b1d68e46b01e642pjulien if (dst == null || dst.capacity() < required) { 1139fb87f813b77f4dbb96ae8fa9420f5f77b247489pjulien dst = CharBuffer.allocate(required); 114286587d1516376f24072f9c88b1d68e46b01e642pjulien CHAR_BUFFER.set(dst); 115450759481286a467b24778ee9f3e5d0c530a035aWouter van Oortmerssen } 116286587d1516376f24072f9c88b1d68e46b01e642pjulien 117286587d1516376f24072f9c88b1d68e46b01e642pjulien dst.clear(); 118286587d1516376f24072f9c88b1d68e46b01e642pjulien 119286587d1516376f24072f9c88b1d68e46b01e642pjulien try { 120286587d1516376f24072f9c88b1d68e46b01e642pjulien CoderResult cr = decoder.decode(src, dst, true); 121286587d1516376f24072f9c88b1d68e46b01e642pjulien if (!cr.isUnderflow()) { 122286587d1516376f24072f9c88b1d68e46b01e642pjulien cr.throwException(); 123286587d1516376f24072f9c88b1d68e46b01e642pjulien } 124286587d1516376f24072f9c88b1d68e46b01e642pjulien } catch (CharacterCodingException x) { 125286587d1516376f24072f9c88b1d68e46b01e642pjulien throw new Error(x); 126286587d1516376f24072f9c88b1d68e46b01e642pjulien } 127286587d1516376f24072f9c88b1d68e46b01e642pjulien 128286587d1516376f24072f9c88b1d68e46b01e642pjulien return dst.flip().toString(); 12926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 13026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 13169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 13269a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Get the length of a vector. 13369a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 13469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param offset An `int` index into the Table's ByteBuffer. 13569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns the length of the vector whose offset is stored at `offset`. 13669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 13726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected int __vector_len(int offset) { 13826a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen offset += bb_pos; 13926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen offset += bb.getInt(offset); 14026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen return bb.getInt(offset); 14126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 14226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 14369a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 14469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Get the start data of a vector. 14569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 14669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param offset An `int` index into the Table's ByteBuffer. 14769a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns the start of the vector data whose offset is stored at `offset`. 14869a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 14926a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected int __vector(int offset) { 15026a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen offset += bb_pos; 15126a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen return offset + bb.getInt(offset) + SIZEOF_INT; // data starts after the length 15226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 15326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen 15469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 15569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Get a whole vector as a ByteBuffer. 15669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 157fdfaf233616a001f36717586917a12638b55d716pjulien * This is efficient, since it only allocates a new {@link ByteBuffer} object, 158fdfaf233616a001f36717586917a12638b55d716pjulien * but does not actually copy the data, it still refers to the same bytes 159fdfaf233616a001f36717586917a12638b55d716pjulien * as the original ByteBuffer. Also useful with nested FlatBuffers, etc. 160fdfaf233616a001f36717586917a12638b55d716pjulien * 161fdfaf233616a001f36717586917a12638b55d716pjulien * @param vector_offset The position of the vector in the byte buffer 162fdfaf233616a001f36717586917a12638b55d716pjulien * @param elem_size The size of each element in the array 163fdfaf233616a001f36717586917a12638b55d716pjulien * @return The {@link ByteBuffer} for the array 16469a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 165858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen protected ByteBuffer __vector_as_bytebuffer(int vector_offset, int elem_size) { 166858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen int o = __offset(vector_offset); 167858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen if (o == 0) return null; 1684d3db99283199ffd8d5fdbe84933444d25b980f4pjulien ByteBuffer bb = this.bb.duplicate().order(ByteOrder.LITTLE_ENDIAN); 1694d3db99283199ffd8d5fdbe84933444d25b980f4pjulien int vectorstart = __vector(o); 1704d3db99283199ffd8d5fdbe84933444d25b980f4pjulien bb.position(vectorstart); 1714d3db99283199ffd8d5fdbe84933444d25b980f4pjulien bb.limit(vectorstart + __vector_len(o) * elem_size); 1724d3db99283199ffd8d5fdbe84933444d25b980f4pjulien return bb; 173858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen } 174858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen 17569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 17669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * Initialize any Table-derived type to point to the union at the given `offset`. 17769a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 17869a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param t A `Table`-derived type that should point to the union at `offset`. 17969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @param offset An `int` index into the Table's ByteBuffer. 18069a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * @return Returns the Table that points to the union at `offset`. 18169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 18226a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen protected Table __union(Table t, int offset) { 18326a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen offset += bb_pos; 18426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen t.bb_pos = offset + bb.getInt(offset); 18526a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen t.bb = bb; 18626a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen return t; 18726a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen } 18809a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen 18969a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara /** 190fdfaf233616a001f36717586917a12638b55d716pjulien * Check if a {@link ByteBuffer} contains a file identifier. 19169a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara * 192fdfaf233616a001f36717586917a12638b55d716pjulien * @param bb A {@code ByteBuffer} to check if it contains the identifier 193fdfaf233616a001f36717586917a12638b55d716pjulien * `ident`. 194fdfaf233616a001f36717586917a12638b55d716pjulien * @param ident A `String` identifier of the FlatBuffer file. 195fdfaf233616a001f36717586917a12638b55d716pjulien * @return True if the buffer contains the file identifier 19669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara */ 197858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen protected static boolean __has_identifier(ByteBuffer bb, String ident) { 19809a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen if (ident.length() != FILE_IDENTIFIER_LENGTH) 19909a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen throw new AssertionError("FlatBuffers: file identifier must be length " + 20009a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen FILE_IDENTIFIER_LENGTH); 20109a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen for (int i = 0; i < FILE_IDENTIFIER_LENGTH; i++) { 202858e9961e2d9291ef47ee3a9e23971ac429121b3Wouter van Oortmerssen if (ident.charAt(i) != (char)bb.get(bb.position() + SIZEOF_INT + i)) return false; 20309a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen } 20409a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen return true; 20509a2999c66abc92e5c33fdef75c63dec81f90a3aWouter van Oortmerssen } 206e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen 2078fdced4e1141a98fb37e952058874423702347caTGIshib /** 2088fdced4e1141a98fb37e952058874423702347caTGIshib * Sort tables by the key. 2098fdced4e1141a98fb37e952058874423702347caTGIshib * 2109f16090f901c30f872422f60db21a0370dde8bbfTGIshib * @param offsets An 'int' indexes of the tables into the bb. 2118fdced4e1141a98fb37e952058874423702347caTGIshib * @param bb A {@code ByteBuffer} to get the tables. 2128fdced4e1141a98fb37e952058874423702347caTGIshib */ 213e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen protected void sortTables(int[] offsets, final ByteBuffer bb) { 2148fdced4e1141a98fb37e952058874423702347caTGIshib Integer[] off = new Integer[offsets.length]; 2158fdced4e1141a98fb37e952058874423702347caTGIshib for (int i = 0; i < offsets.length; i++) off[i] = offsets[i]; 216e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen java.util.Arrays.sort(off, new java.util.Comparator<Integer>() { 217e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen public int compare(Integer o1, Integer o2) { 218e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen return keysCompare(o1, o2, bb); 219e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen } 220e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen }); 2218fdced4e1141a98fb37e952058874423702347caTGIshib for (int i = 0; i < offsets.length; i++) offsets[i] = off[i]; 2228fdced4e1141a98fb37e952058874423702347caTGIshib } 2238fdced4e1141a98fb37e952058874423702347caTGIshib 2248fdced4e1141a98fb37e952058874423702347caTGIshib /** 2258fdced4e1141a98fb37e952058874423702347caTGIshib * Compare two tables by the key. 2268fdced4e1141a98fb37e952058874423702347caTGIshib * 2279f16090f901c30f872422f60db21a0370dde8bbfTGIshib * @param o1 An 'Integer' index of the first key into the bb. 2289f16090f901c30f872422f60db21a0370dde8bbfTGIshib * @param o2 An 'Integer' index of the second key into the bb. 2298fdced4e1141a98fb37e952058874423702347caTGIshib * @param bb A {@code ByteBuffer} to get the keys. 2308fdced4e1141a98fb37e952058874423702347caTGIshib */ 2318fdced4e1141a98fb37e952058874423702347caTGIshib protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; } 232e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen 2338fdced4e1141a98fb37e952058874423702347caTGIshib /** 2348fdced4e1141a98fb37e952058874423702347caTGIshib * Compare two strings in the buffer. 2358fdced4e1141a98fb37e952058874423702347caTGIshib * 2368fdced4e1141a98fb37e952058874423702347caTGIshib * @param offset_1 An 'int' index of the first string into the bb. 2378fdced4e1141a98fb37e952058874423702347caTGIshib * @param offset_2 An 'int' index of the second string into the bb. 2388fdced4e1141a98fb37e952058874423702347caTGIshib * @param bb A {@code ByteBuffer} to get the strings. 2398fdced4e1141a98fb37e952058874423702347caTGIshib */ 2408fdced4e1141a98fb37e952058874423702347caTGIshib protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) { 2418fdced4e1141a98fb37e952058874423702347caTGIshib offset_1 += bb.getInt(offset_1); 2428fdced4e1141a98fb37e952058874423702347caTGIshib offset_2 += bb.getInt(offset_2); 2438fdced4e1141a98fb37e952058874423702347caTGIshib int len_1 = bb.getInt(offset_1); 2448fdced4e1141a98fb37e952058874423702347caTGIshib int len_2 = bb.getInt(offset_2); 2458fdced4e1141a98fb37e952058874423702347caTGIshib int startPos_1 = offset_1 + SIZEOF_INT; 2468fdced4e1141a98fb37e952058874423702347caTGIshib int startPos_2 = offset_2 + SIZEOF_INT; 2478fdced4e1141a98fb37e952058874423702347caTGIshib int len = Math.min(len_1, len_2); 2488fdced4e1141a98fb37e952058874423702347caTGIshib for(int i = 0; i < len; i++) { 249625c9898754a491a1c195743eafdb22908e4102cAlex Wasserman if (bb.get(i + startPos_1) != bb.get(i + startPos_2)) 250625c9898754a491a1c195743eafdb22908e4102cAlex Wasserman return bb.get(i + startPos_1) - bb.get(i + startPos_2); 2518fdced4e1141a98fb37e952058874423702347caTGIshib } 2527c69c5dc3d635e29e3442339caa8eb06b8b9775cTGIshib return len_1 - len_2; 2538fdced4e1141a98fb37e952058874423702347caTGIshib } 254e1f8037cb55cbeac5d96ad63c2f5c70560737340Wouter van Oortmerssen 2559f16090f901c30f872422f60db21a0370dde8bbfTGIshib /** 2569f16090f901c30f872422f60db21a0370dde8bbfTGIshib * Compare string from the buffer with the 'String' object. 2579f16090f901c30f872422f60db21a0370dde8bbfTGIshib * 2589f16090f901c30f872422f60db21a0370dde8bbfTGIshib * @param offset_1 An 'int' index of the first string into the bb. 2597c69c5dc3d635e29e3442339caa8eb06b8b9775cTGIshib * @param key Second string as a byte array. 2609f16090f901c30f872422f60db21a0370dde8bbfTGIshib * @param bb A {@code ByteBuffer} to get the first string. 2619f16090f901c30f872422f60db21a0370dde8bbfTGIshib */ 2627c69c5dc3d635e29e3442339caa8eb06b8b9775cTGIshib protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) { 2639f16090f901c30f872422f60db21a0370dde8bbfTGIshib offset_1 += bb.getInt(offset_1); 2649f16090f901c30f872422f60db21a0370dde8bbfTGIshib int len_1 = bb.getInt(offset_1); 2657c69c5dc3d635e29e3442339caa8eb06b8b9775cTGIshib int len_2 = key.length; 2669f16090f901c30f872422f60db21a0370dde8bbfTGIshib int startPos_1 = offset_1 + Constants.SIZEOF_INT; 2679f16090f901c30f872422f60db21a0370dde8bbfTGIshib int len = Math.min(len_1, len_2); 2689f16090f901c30f872422f60db21a0370dde8bbfTGIshib for (int i = 0; i < len; i++) { 269625c9898754a491a1c195743eafdb22908e4102cAlex Wasserman if (bb.get(i + startPos_1) != key[i]) 270625c9898754a491a1c195743eafdb22908e4102cAlex Wasserman return bb.get(i + startPos_1) - key[i]; 2719f16090f901c30f872422f60db21a0370dde8bbfTGIshib } 2727c69c5dc3d635e29e3442339caa8eb06b8b9775cTGIshib return len_1 - len_2; 2739f16090f901c30f872422f60db21a0370dde8bbfTGIshib } 27426a30738a4fa4e92300821fd761764ec8df2dcf2Wouter van Oortmerssen} 27569a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara 27669a31b807a85e9a5ca4efb839f37ecb6dcf3eed5Mark Klara/// @endcond 277