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