Example usage for java.nio ByteBuffer getInt

List of usage examples for java.nio ByteBuffer getInt

Introduction

In this page you can find the example usage for java.nio ByteBuffer getInt.

Prototype

public abstract int getInt();

Source Link

Document

Returns the int at the current position and increases the position by 4.

Usage

From source file:edu.harvard.iq.dataverse.ingest.tabulardata.impl.plugins.dta.DTAFileReader.java

private void decodeData(BufferedInputStream stream) throws IOException {

    dbgLog.fine("\n***** decodeData(): start *****");

    if (stream == null) {
        throw new IllegalArgumentException("stream == null!");
    }/*  ww  w  .j  ava 2  s  .  c  om*/

    //int nvar = (Integer)smd.getFileInformation().get("varQnty");
    int nvar = dataTable.getVarQuantity().intValue();
    //int nobs = (Integer)smd.getFileInformation().get("caseQnty");
    int nobs = dataTable.getCaseQuantity().intValue();

    if (dbgLog.isLoggable(Level.FINE)) {
        dbgLog.fine("data dimensions[observations x variables] = (" + nobs + "x" + nvar + ")");
    }
    if (dbgLog.isLoggable(Level.FINE)) {
        dbgLog.fine("bytes per row=" + bytes_per_row + " bytes");
    }

    if (dbgLog.isLoggable(Level.FINE)) {
        dbgLog.fine("variableTypes=" + Arrays.deepToString(variableTypes));
    }
    if (dbgLog.isLoggable(Level.FINE)) {
        dbgLog.fine("StringLengthTable=" + StringLengthTable);
    }

    // create a File object to save the tab-delimited data file
    FileOutputStream fileOutTab = null;
    PrintWriter pwout = null;
    File tabDelimitedDataFile = File.createTempFile("tempTabfile.", ".tab");

    // save the temp tab-delimited file in the return ingest object:        
    ingesteddata.setTabDelimitedFile(tabDelimitedDataFile);

    fileOutTab = new FileOutputStream(tabDelimitedDataFile);
    pwout = new PrintWriter(new OutputStreamWriter(fileOutTab, "utf8"), true);

    /* Should we lose this dateFormat thing in 4.0? 
     * the UNF should be calculatable on the app side solely from the data
     * stored in the tab file and the type information stored the dataVariable
     * object. 
     * furthermore, the very idea of storing a format entry not just for 
     * every variable, but for every value/observation is a bit strange. 
     * TODO: review and confirm that, in the 3.* implementation, every
     * entry in dateFormat[nvar][*] is indeed the same - except for the 
     * missing value entries. -- L.A. 4.0
      (OK, I got rid of the dateFormat; instead I kinda sorta assume
      that the format is the same for every value in a column, save for 
      the missing values... like this: 
      dataTable.getDataVariables().get(columnCounter).setFormatSchemaName(ddt.format);
      BUT, this needs to be reviewed/confirmed etc! 
     */
    //String[][] dateFormat = new String[nvar][nobs];

    for (int i = 0; i < nobs; i++) {
        byte[] dataRowBytes = new byte[bytes_per_row];
        Object[] dataRow = new Object[nvar];

        int nbytes = stream.read(dataRowBytes, 0, bytes_per_row);

        if (nbytes == 0) {
            String errorMessage = "reading data: no data were read at(" + i + "th row)";
            throw new IOException(errorMessage);
        }
        // decoding each row
        int byte_offset = 0;
        for (int columnCounter = 0; columnCounter < variableTypes.length; columnCounter++) {

            Integer varType = variableTypeMap.get(variableTypes[columnCounter]);

            // 4.0 Check if this is a time/date variable: 
            boolean isDateTimeDatum = false;
            String formatCategory = dataTable.getDataVariables().get(columnCounter).getFormatCategory();
            if (formatCategory != null && (formatCategory.equals("time") || formatCategory.equals("date"))) {
                isDateTimeDatum = true;
            }

            String variableFormat = dateVariableFormats[columnCounter];

            switch (varType != null ? varType : 256) {
            case -5:
                // Byte case
                // note: 1 byte signed
                byte byte_datum = dataRowBytes[byte_offset];

                if (dbgLog.isLoggable(Level.FINER)) {
                    dbgLog.finer(i + "-th row " + columnCounter + "=th column byte =" + byte_datum);
                }
                if (byte_datum >= BYTE_MISSING_VALUE) {
                    if (dbgLog.isLoggable(Level.FINER)) {
                        dbgLog.finer(i + "-th row " + columnCounter + "=th column byte MV=" + byte_datum);
                    }
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;
                } else {
                    dataRow[columnCounter] = byte_datum;
                }

                byte_offset++;
                break;
            case -4:
                // Stata-int (=java's short: 2byte) case
                // note: 2-byte signed int, not java's int
                ByteBuffer int_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 2);
                if (isLittleEndian) {
                    int_buffer.order(ByteOrder.LITTLE_ENDIAN);

                }
                short short_datum = int_buffer.getShort();

                if (dbgLog.isLoggable(Level.FINER)) {
                    dbgLog.finer(i + "-th row " + columnCounter + "=th column stata int =" + short_datum);
                }
                if (short_datum >= INT_MISSIG_VALUE) {
                    if (dbgLog.isLoggable(Level.FINER)) {
                        dbgLog.finer(i + "-th row " + columnCounter + "=th column stata long missing value="
                                + short_datum);
                    }
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;
                } else {

                    if (isDateTimeDatum) {

                        DecodedDateTime ddt = decodeDateTimeData("short", variableFormat,
                                Short.toString(short_datum));
                        if (dbgLog.isLoggable(Level.FINER)) {
                            dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format="
                                    + ddt.format);
                        }
                        dataRow[columnCounter] = ddt.decodedDateTime;
                        //dateFormat[columnCounter][i] = ddt.format;
                        dataTable.getDataVariables().get(columnCounter).setFormat(ddt.format);

                    } else {
                        dataRow[columnCounter] = short_datum;
                    }
                }
                byte_offset += 2;
                break;
            case -3:
                // stata-Long (= java's int: 4 byte) case
                // note: 4-byte singed, not java's long
                //dbgLog.fine("DATreader: stata long");

                ByteBuffer long_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 4);
                if (isLittleEndian) {
                    long_buffer.order(ByteOrder.LITTLE_ENDIAN);

                }
                int int_datum = long_buffer.getInt();

                if (dbgLog.isLoggable(Level.FINE)) {
                    //dbgLog.fine(i + "-th row " + columnCounter
                    //        + "=th column stata long =" + int_datum);
                }
                if (int_datum >= LONG_MISSING_VALUE) {
                    if (dbgLog.isLoggable(Level.FINE)) {
                        //dbgLog.fine(i + "-th row " + columnCounter
                        //        + "=th column stata long missing value=" + int_datum);
                    }
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;
                } else {
                    if (isDateTimeDatum) {
                        DecodedDateTime ddt = decodeDateTimeData("int", variableFormat,
                                Integer.toString(int_datum));
                        if (dbgLog.isLoggable(Level.FINER)) {
                            dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format="
                                    + ddt.format);
                        }
                        dataRow[columnCounter] = ddt.decodedDateTime;
                        dataTable.getDataVariables().get(columnCounter).setFormat(ddt.format);

                    } else {
                        dataRow[columnCounter] = int_datum;
                    }

                }
                byte_offset += 4;
                break;
            case -2:
                // float case
                // note: 4-byte
                ByteBuffer float_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 4);
                if (isLittleEndian) {
                    float_buffer.order(ByteOrder.LITTLE_ENDIAN);
                }
                float float_datum = float_buffer.getFloat();

                if (dbgLog.isLoggable(Level.FINER)) {
                    dbgLog.finer(i + "-th row " + columnCounter + "=th column float =" + float_datum);
                }
                if (FLOAT_MISSING_VALUE_SET.contains(float_datum)) {
                    if (dbgLog.isLoggable(Level.FINER)) {
                        dbgLog.finer(i + "-th row " + columnCounter + "=th column float missing value="
                                + float_datum);
                    }
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;

                } else {

                    if (isDateTimeDatum) {
                        DecodedDateTime ddt = decodeDateTimeData("float", variableFormat,
                                doubleNumberFormatter.format(float_datum));
                        if (dbgLog.isLoggable(Level.FINER)) {
                            dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format="
                                    + ddt.format);
                        }
                        dataRow[columnCounter] = ddt.decodedDateTime;
                        dataTable.getDataVariables().get(columnCounter).setFormat(ddt.format);
                    } else {
                        dataRow[columnCounter] = float_datum;
                        // This may be temporary - but for now (as in, while I'm testing 
                        // 4.0 ingest against 3.* ingest, I need to be able to tell if a 
                        // floating point value was a single, or double float in the 
                        // original STATA file: -- L.A. Jul. 2014
                        dataTable.getDataVariables().get(columnCounter).setFormat("float");
                    }

                }
                byte_offset += 4;
                break;
            case -1:
                // double case
                // note: 8-byte
                ByteBuffer double_buffer = ByteBuffer.wrap(dataRowBytes, byte_offset, 8);
                if (isLittleEndian) {
                    double_buffer.order(ByteOrder.LITTLE_ENDIAN);
                }
                double double_datum = double_buffer.getDouble();

                if (DOUBLE_MISSING_VALUE_SET.contains(double_datum)) {
                    if (dbgLog.isLoggable(Level.FINER)) {
                        dbgLog.finer(i + "-th row " + columnCounter + "=th column double missing value="
                                + double_datum);
                    }
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;
                } else {

                    if (isDateTimeDatum) {
                        DecodedDateTime ddt = decodeDateTimeData("double", variableFormat,
                                doubleNumberFormatter.format(double_datum));
                        if (dbgLog.isLoggable(Level.FINER)) {
                            dbgLog.finer(i + "-th row , decodedDateTime " + ddt.decodedDateTime + ", format="
                                    + ddt.format);
                        }
                        dataRow[columnCounter] = ddt.decodedDateTime;
                        dataTable.getDataVariables().get(columnCounter).setFormat(ddt.format);
                    } else {
                        dataRow[columnCounter] = doubleNumberFormatter.format(double_datum);
                    }

                }
                byte_offset += 8;
                break;
            case 0:
                // String case
                int strVarLength = StringLengthTable.get(columnCounter);
                String raw_datum = new String(
                        Arrays.copyOfRange(dataRowBytes, byte_offset, (byte_offset + strVarLength)),
                        "ISO-8859-1");
                // TODO: 
                // is it the right thing to do, to default to "ISO-8859-1"?
                // (it may be; since there's no mechanism for specifying
                // alternative encodings in Stata, this may be their default;
                // it just needs to be verified. -- L.A. Jul. 2014)
                String string_datum = getNullStrippedString(raw_datum);
                if (dbgLog.isLoggable(Level.FINER)) {
                    dbgLog.finer(i + "-th row " + columnCounter + "=th column string =" + string_datum);
                }
                if (string_datum.isEmpty()) {
                    if (dbgLog.isLoggable(Level.FINER)) {
                        dbgLog.finer(i + "-th row " + columnCounter + "=th column string missing value="
                                + string_datum);
                    }
                    // TODO: 
                    /* Is this really a missing value case? 
                     * Or is it an honest empty string? 
                     * Is there such a thing as a missing value for a String in Stata?
                     * -- L.A. 4.0
                     */
                    dataRow[columnCounter] = MissingValueForTabDelimitedFile;
                } else {
                    /*
                     * Some special characters, like new lines and tabs need to 
                     * be escaped - otherwise they will break our TAB file 
                     * structure! 
                     * But before we escape anything, all the back slashes 
                     * already in the string need to be escaped themselves.
                     */
                    String escapedString = string_datum.replace("\\", "\\\\");
                    // escape quotes: 
                    escapedString = escapedString.replaceAll("\"", Matcher.quoteReplacement("\\\""));
                    // escape tabs and new lines:
                    escapedString = escapedString.replaceAll("\t", Matcher.quoteReplacement("\\t"));
                    escapedString = escapedString.replaceAll("\n", Matcher.quoteReplacement("\\n"));
                    escapedString = escapedString.replaceAll("\r", Matcher.quoteReplacement("\\r"));
                    // the escaped version of the string is stored in the tab file 
                    // enclosed in double-quotes; this is in order to be able 
                    // to differentiate between an empty string (tab-delimited empty string in 
                    // double quotes) and a missing value (tab-delimited empty string). 
                    // Although the question still remains - is it even possible 
                    // to store an empty string, that's not a missing value, in Stata? 
                    // - see the comment in the missing value case above. -- L.A. 4.0
                    dataRow[columnCounter] = "\"" + escapedString + "\"";
                }
                byte_offset += strVarLength;
                break;
            default:
                dbgLog.fine("unknown variable type found");
                String errorMessage = "unknow variable Type found at data section";
                throw new InvalidObjectException(errorMessage);
            } // switch
        } // for-columnCounter

        // Dump the row of data to the tab-delimited file we are producing:
        pwout.println(StringUtils.join(dataRow, "\t"));

        if (dbgLog.isLoggable(Level.FINE)) {
            //dbgLog.fine(i + "-th row's data={" + StringUtils.join(dataRow, ",") + "};");
        }

    } // for- i (row)

    pwout.close();

    if (dbgLog.isLoggable(Level.FINE)) {
        dbgLog.fine("variableTypes:\n" + Arrays.deepToString(variableTypes));
    }

    dbgLog.fine("DTA Ingest: decodeData(): end.");

}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private void decodeAppLogs(ByteBuffer buf) {
    UUID uuid = getUUID(buf);/* ww w . j a va 2 s  . c o  m*/
    int timestamp = buf.getInt();
    int logLevel = buf.get() & 0xff;
    int messageLength = buf.get() & 0xff;
    int lineNumber = buf.getShort() & 0xffff;
    String fileName = getFixedString(buf, 16);
    String message = getFixedString(buf, messageLength);
    LOG.debug("APP_LOGS (" + logLevel + ") from uuid " + uuid.toString() + " in " + fileName + ":" + lineNumber
            + " " + message);
}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private GBDeviceEventSendBytes decodePing(ByteBuffer buf) {
    byte command = buf.get();
    if (command == PING_PING) {
        int cookie = buf.getInt();
        LOG.info("Received PING - will reply");
        GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
        sendBytes.encodedBytes = encodePing(PING_PONG, cookie);
        return sendBytes;
    }//  w  w w.  j ava2 s.  c o m
    return null;
}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private GBDeviceEvent decodeVoiceControl(ByteBuffer buf) {
    buf.order(ByteOrder.LITTLE_ENDIAN);
    byte command = buf.get();
    int flags = buf.getInt();
    byte session_type = buf.get(); //0x01 dictation 0x02 command
    short session_id = buf.getShort();
    //attributes/*w ww.  j av a  2s . co m*/
    byte count = buf.get();
    byte type = buf.get();
    short length = buf.getShort();
    byte[] version = new byte[20];
    buf.get(version); //it's a string like "1.2rc1"
    int sample_rate = buf.getInt();
    short bit_rate = buf.getShort();
    byte bitstream_version = buf.get();
    short frame_size = buf.getShort();

    GBDeviceEventSendBytes sendBytes = new GBDeviceEventSendBytes();
    if (command == 0x01) { //session setup
        sendBytes.encodedBytes = null;
    } else if (command == 0x02) { //dictation result
        sendBytes.encodedBytes = null;
    }
    return sendBytes;
}

From source file:com.healthmarketscience.jackcess.Column.java

/**
 * Deserialize a raw byte value for this column into an Object
 * @param data The raw byte value/*  w  w w.  ja  v a2s . c  o  m*/
 * @param order Byte order in which the raw value is stored
 * @return The deserialized Object
 * @usage _advanced_method_
 */
public Object read(byte[] data, ByteOrder order) throws IOException {
    ByteBuffer buffer = ByteBuffer.wrap(data);
    buffer.order(order);
    if (_type == DataType.BOOLEAN) {
        throw new IOException("Tried to read a boolean from data instead of null mask.");
    } else if (_type == DataType.BYTE) {
        return Byte.valueOf(buffer.get());
    } else if (_type == DataType.INT) {
        return Short.valueOf(buffer.getShort());
    } else if (_type == DataType.LONG) {
        return Integer.valueOf(buffer.getInt());
    } else if (_type == DataType.DOUBLE) {
        return Double.valueOf(buffer.getDouble());
    } else if (_type == DataType.FLOAT) {
        return Float.valueOf(buffer.getFloat());
    } else if (_type == DataType.SHORT_DATE_TIME) {
        return readDateValue(buffer);
    } else if (_type == DataType.BINARY) {
        return data;
    } else if (_type == DataType.TEXT) {
        return decodeTextValue(data);
    } else if (_type == DataType.MONEY) {
        return readCurrencyValue(buffer);
    } else if (_type == DataType.OLE) {
        if (data.length > 0) {
            return readLongValue(data);
        }
        return null;
    } else if (_type == DataType.MEMO) {
        if (data.length > 0) {
            return readLongStringValue(data);
        }
        return null;
    } else if (_type == DataType.NUMERIC) {
        return readNumericValue(buffer);
    } else if (_type == DataType.GUID) {
        return readGUIDValue(buffer, order);
    } else if ((_type == DataType.UNKNOWN_0D) || (_type == DataType.UNKNOWN_11)) {
        // treat like "binary" data
        return data;
    } else if (_type == DataType.COMPLEX_TYPE) {
        return new ComplexValueForeignKey(this, buffer.getInt());
    } else if (_type.isUnsupported()) {
        return rawDataWrapper(data);
    } else {
        throw new IOException("Unrecognized data type: " + _type);
    }
}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private GBDeviceEventAppManagement decodeAppFetch(ByteBuffer buf) {
    byte command = buf.get();
    if (command == 0x01) {
        UUID uuid = getUUID(buf);
        buf.order(ByteOrder.LITTLE_ENDIAN);
        int app_id = buf.getInt();
        GBDeviceEventAppManagement fetchRequest = new GBDeviceEventAppManagement();
        fetchRequest.type = GBDeviceEventAppManagement.EventType.INSTALL;
        fetchRequest.event = GBDeviceEventAppManagement.Event.REQUEST;
        fetchRequest.token = app_id;//from w  w w .j a  va2 s .c om
        fetchRequest.uuid = uuid;
        return fetchRequest;
    }
    return null;
}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private GBDeviceEventScreenshot decodeScreenshot(ByteBuffer buf, int length) {
    if (mDevEventScreenshot == null) {
        byte result = buf.get();
        mDevEventScreenshot = new GBDeviceEventScreenshot();
        int version = buf.getInt();
        if (result != 0) {
            return null;
        }// w  ww. j  av a 2s  . c o  m
        mDevEventScreenshot.width = buf.getInt();
        mDevEventScreenshot.height = buf.getInt();

        if (version == 1) {
            mDevEventScreenshot.bpp = 1;
            mDevEventScreenshot.clut = clut_pebble;
        } else {
            mDevEventScreenshot.bpp = 8;
            mDevEventScreenshot.clut = clut_pebbletime;
        }

        mScreenshotRemaining = (mDevEventScreenshot.width * mDevEventScreenshot.height
                * mDevEventScreenshot.bpp) / 8;

        mDevEventScreenshot.data = new byte[mScreenshotRemaining];
        length -= 13;
    }
    if (mScreenshotRemaining == -1) {
        return null;
    }
    for (int i = 0; i < length; i++) {
        byte corrected = buf.get();
        if (mDevEventScreenshot.bpp == 1) {
            corrected = reverseBits(corrected);
        } else {
            corrected = (byte) (corrected & 0b00111111);
        }

        mDevEventScreenshot.data[mDevEventScreenshot.data.length - mScreenshotRemaining + i] = corrected;
    }
    mScreenshotRemaining -= length;
    LOG.info("Screenshot remaining bytes " + mScreenshotRemaining);
    if (mScreenshotRemaining == 0) {
        mScreenshotRemaining = -1;
        LOG.info("Got screenshot : " + mDevEventScreenshot.width + "x" + mDevEventScreenshot.height + "  "
                + "pixels");
        GBDeviceEventScreenshot devEventScreenshot = mDevEventScreenshot;
        mDevEventScreenshot = null;
        return devEventScreenshot;
    }
    return null;
}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private ArrayList<Pair<Integer, Object>> decodeDict(ByteBuffer buf) {
    ArrayList<Pair<Integer, Object>> dict = new ArrayList<>();
    buf.order(ByteOrder.LITTLE_ENDIAN);
    byte dictSize = buf.get();
    while (dictSize-- > 0) {
        Integer key = buf.getInt();
        byte type = buf.get();
        short length = buf.getShort();
        switch (type) {
        case TYPE_INT:
        case TYPE_UINT:
            if (length == 1) {
                dict.add(new Pair<Integer, Object>(key, buf.get()));
            } else if (length == 2) {
                dict.add(new Pair<Integer, Object>(key, buf.getShort()));
            } else {
                dict.add(new Pair<Integer, Object>(key, buf.getInt()));
            }/*from w w w .  j ava 2  s  . c om*/
            break;
        case TYPE_CSTRING:
        case TYPE_BYTEARRAY:
            byte[] bytes = new byte[length];
            buf.get(bytes);
            if (type == TYPE_BYTEARRAY) {
                dict.add(new Pair<Integer, Object>(key, bytes));
            } else {
                dict.add(new Pair<Integer, Object>(key, new String(bytes)));
            }
            break;
        default:
        }
    }
    return dict;
}

From source file:org.apache.hadoop.hbase.io.hfile.TestHFileBlockIndex.java

@Test
public void testSecondaryIndexBinarySearch() throws IOException {
    int numTotalKeys = 99;
    assertTrue(numTotalKeys % 2 == 1); // Ensure no one made this even.

    // We only add odd-index keys into the array that we will binary-search.
    int numSearchedKeys = (numTotalKeys - 1) / 2;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(baos);

    dos.writeInt(numSearchedKeys);/*from w  w  w.  ja  va 2s  . c  o  m*/
    int curAllEntriesSize = 0;
    int numEntriesAdded = 0;

    // Only odd-index elements of this array are used to keep the secondary
    // index entries of the corresponding keys.
    int secondaryIndexEntries[] = new int[numTotalKeys];

    for (int i = 0; i < numTotalKeys; ++i) {
        byte[] k = TestHFileWriterV2.randomOrderedKey(rand, i * 2);
        KeyValue cell = new KeyValue(k, Bytes.toBytes("f"), Bytes.toBytes("q"), Bytes.toBytes("val"));
        //KeyValue cell = new KeyValue.KeyOnlyKeyValue(k, 0, k.length);
        keys.add(cell.getKey());
        String msgPrefix = "Key #" + i + " (" + Bytes.toStringBinary(k) + "): ";
        StringBuilder padding = new StringBuilder();
        while (msgPrefix.length() + padding.length() < 70)
            padding.append(' ');
        msgPrefix += padding;
        if (i % 2 == 1) {
            dos.writeInt(curAllEntriesSize);
            secondaryIndexEntries[i] = curAllEntriesSize;
            LOG.info(msgPrefix + "secondary index entry #" + ((i - 1) / 2) + ", offset " + curAllEntriesSize);
            curAllEntriesSize += cell.getKey().length + HFileBlockIndex.SECONDARY_INDEX_ENTRY_OVERHEAD;
            ++numEntriesAdded;
        } else {
            secondaryIndexEntries[i] = -1;
            LOG.info(msgPrefix + "not in the searched array");
        }
    }

    // Make sure the keys are increasing.
    for (int i = 0; i < keys.size() - 1; ++i)
        assertTrue(KeyValue.COMPARATOR.compare(new KeyValue.KeyOnlyKeyValue(keys.get(i), 0, keys.get(i).length),
                new KeyValue.KeyOnlyKeyValue(keys.get(i + 1), 0, keys.get(i + 1).length)) < 0);

    dos.writeInt(curAllEntriesSize);
    assertEquals(numSearchedKeys, numEntriesAdded);
    int secondaryIndexOffset = dos.size();
    assertEquals(Bytes.SIZEOF_INT * (numSearchedKeys + 2), secondaryIndexOffset);

    for (int i = 1; i <= numTotalKeys - 1; i += 2) {
        assertEquals(dos.size(), secondaryIndexOffset + secondaryIndexEntries[i]);
        long dummyFileOffset = getDummyFileOffset(i);
        int dummyOnDiskSize = getDummyOnDiskSize(i);
        LOG.debug("Storing file offset=" + dummyFileOffset + " and onDiskSize=" + dummyOnDiskSize
                + " at offset " + dos.size());
        dos.writeLong(dummyFileOffset);
        dos.writeInt(dummyOnDiskSize);
        LOG.debug("Stored key " + ((i - 1) / 2) + " at offset " + dos.size());
        dos.write(keys.get(i));
    }

    dos.writeInt(curAllEntriesSize);

    ByteBuffer nonRootIndex = ByteBuffer.wrap(baos.toByteArray());
    for (int i = 0; i < numTotalKeys; ++i) {
        byte[] searchKey = keys.get(i);
        byte[] arrayHoldingKey = new byte[searchKey.length + searchKey.length / 2];

        // To make things a bit more interesting, store the key we are looking
        // for at a non-zero offset in a new array.
        System.arraycopy(searchKey, 0, arrayHoldingKey, searchKey.length / 2, searchKey.length);

        KeyValue.KeyOnlyKeyValue cell = new KeyValue.KeyOnlyKeyValue(arrayHoldingKey, searchKey.length / 2,
                searchKey.length);
        int searchResult = BlockIndexReader.binarySearchNonRootIndex(cell, nonRootIndex, KeyValue.COMPARATOR);
        String lookupFailureMsg = "Failed to look up key #" + i + " (" + Bytes.toStringBinary(searchKey) + ")";

        int expectedResult;
        int referenceItem;

        if (i % 2 == 1) {
            // This key is in the array we search as the element (i - 1) / 2. Make
            // sure we find it.
            expectedResult = (i - 1) / 2;
            referenceItem = i;
        } else {
            // This key is not in the array but between two elements on the array,
            // in the beginning, or in the end. The result should be the previous
            // key in the searched array, or -1 for i = 0.
            expectedResult = i / 2 - 1;
            referenceItem = i - 1;
        }

        assertEquals(lookupFailureMsg, expectedResult, searchResult);

        // Now test we can get the offset and the on-disk-size using a
        // higher-level API function.s
        boolean locateBlockResult = (BlockIndexReader.locateNonRootIndexEntry(nonRootIndex, cell,
                KeyValue.COMPARATOR) != -1);

        if (i == 0) {
            assertFalse(locateBlockResult);
        } else {
            assertTrue(locateBlockResult);
            String errorMsg = "i=" + i + ", position=" + nonRootIndex.position();
            assertEquals(errorMsg, getDummyFileOffset(referenceItem), nonRootIndex.getLong());
            assertEquals(errorMsg, getDummyOnDiskSize(referenceItem), nonRootIndex.getInt());
        }
    }

}

From source file:nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.PebbleProtocol.java

private GBDeviceEvent[] decodeDictToJSONAppMessage(UUID uuid, ByteBuffer buf) throws JSONException {
    buf.order(ByteOrder.LITTLE_ENDIAN);
    byte dictSize = buf.get();
    if (dictSize == 0) {
        LOG.info("dict size is 0, ignoring");
        return null;
    }//from   ww w  .j av a 2  s . com
    JSONArray jsonArray = new JSONArray();
    while (dictSize-- > 0) {
        JSONObject jsonObject = new JSONObject();
        Integer key = buf.getInt();
        byte type = buf.get();
        short length = buf.getShort();
        jsonObject.put("key", key);
        if (type == TYPE_CSTRING) {
            length--;
        }
        jsonObject.put("length", length);
        switch (type) {
        case TYPE_UINT:
            jsonObject.put("type", "uint");
            if (length == 1) {
                jsonObject.put("value", buf.get() & 0xff);
            } else if (length == 2) {
                jsonObject.put("value", buf.getShort() & 0xffff);
            } else {
                jsonObject.put("value", buf.getInt() & 0xffffffffL);
            }
            break;
        case TYPE_INT:
            jsonObject.put("type", "int");
            if (length == 1) {
                jsonObject.put("value", buf.get());
            } else if (length == 2) {
                jsonObject.put("value", buf.getShort());
            } else {
                jsonObject.put("value", buf.getInt());
            }
            break;
        case TYPE_BYTEARRAY:
        case TYPE_CSTRING:
            byte[] bytes = new byte[length];
            buf.get(bytes);
            if (type == TYPE_BYTEARRAY) {
                jsonObject.put("type", "bytes");
                jsonObject.put("value", new String(Base64.encode(bytes, Base64.NO_WRAP)));
            } else {
                jsonObject.put("type", "string");
                jsonObject.put("value", new String(bytes));
                buf.get(); // skip null-termination;
            }
            break;
        default:
            LOG.info("unknown type in appmessage, ignoring");
            return null;
        }
        jsonArray.put(jsonObject);
    }

    GBDeviceEventSendBytes sendBytesAck = null;
    if (mAlwaysACKPebbleKit) {
        // this is a hack we send an ack to the Pebble immediately because somebody said it helps some PebbleKit apps :P
        sendBytesAck = new GBDeviceEventSendBytes();
        sendBytesAck.encodedBytes = encodeApplicationMessageAck(uuid, last_id);
    }
    GBDeviceEventAppMessage appMessage = new GBDeviceEventAppMessage();
    appMessage.appUUID = uuid;
    appMessage.id = last_id & 0xff;
    appMessage.message = jsonArray.toString();
    return new GBDeviceEvent[] { appMessage, sendBytesAck };
}