List of usage examples for java.nio ByteBuffer get
public abstract byte get(int index);
From source file:com.healthmarketscience.jackcess.Database.java
/** * @return the current database password, or {@code null} if none set. * @usage _general_method_//from w w w. j a v a2s . co m */ public String getDatabasePassword() throws IOException { ByteBuffer buffer = takeSharedBuffer(); try { _pageChannel.readPage(buffer, 0); byte[] pwdBytes = new byte[_format.SIZE_PASSWORD]; buffer.position(_format.OFFSET_PASSWORD); buffer.get(pwdBytes); // de-mask password using extra password mask if necessary (the extra // password mask is generated from the database creation date stored in // the header) byte[] pwdMask = getPasswordMask(buffer, _format); if (pwdMask != null) { for (int i = 0; i < pwdBytes.length; ++i) { pwdBytes[i] ^= pwdMask[i % pwdMask.length]; } } boolean hasPassword = false; for (int i = 0; i < pwdBytes.length; ++i) { if (pwdBytes[i] != 0) { hasPassword = true; break; } } if (!hasPassword) { return null; } String pwd = Column.decodeUncompressedText(pwdBytes, getCharset()); // remove any trailing null chars int idx = pwd.indexOf('\0'); if (idx >= 0) { pwd = pwd.substring(0, idx); } return pwd; } finally { releaseSharedBuffer(buffer); } }
From source file:com.healthmarketscience.jackcess.Column.java
/** * @param lvalDefinition Column value that points to an LVAL record * @return The LVAL data/* w ww. j ava2 s .c om*/ */ private byte[] readLongValue(byte[] lvalDefinition) throws IOException { ByteBuffer def = ByteBuffer.wrap(lvalDefinition).order(PageChannel.DEFAULT_BYTE_ORDER); int lengthWithFlags = def.getInt(); int length = lengthWithFlags & (~LONG_VALUE_TYPE_MASK); byte[] rtn = new byte[length]; byte type = (byte) ((lengthWithFlags & LONG_VALUE_TYPE_MASK) >>> 24); if (type == LONG_VALUE_TYPE_THIS_PAGE) { // inline long value def.getInt(); //Skip over lval_dp def.getInt(); //Skip over unknown def.get(rtn); } else { // long value on other page(s) if (lvalDefinition.length != getFormat().SIZE_LONG_VALUE_DEF) { throw new IOException("Expected " + getFormat().SIZE_LONG_VALUE_DEF + " bytes in long value definition, but found " + lvalDefinition.length); } int rowNum = ByteUtil.getUnsignedByte(def); int pageNum = ByteUtil.get3ByteInt(def, def.position()); ByteBuffer lvalPage = getPageChannel().createPageBuffer(); switch (type) { case LONG_VALUE_TYPE_OTHER_PAGE: { getPageChannel().readPage(lvalPage, pageNum); short rowStart = Table.findRowStart(lvalPage, rowNum, getFormat()); short rowEnd = Table.findRowEnd(lvalPage, rowNum, getFormat()); if ((rowEnd - rowStart) != length) { throw new IOException("Unexpected lval row length"); } lvalPage.position(rowStart); lvalPage.get(rtn); } break; case LONG_VALUE_TYPE_OTHER_PAGES: ByteBuffer rtnBuf = ByteBuffer.wrap(rtn); int remainingLen = length; while (remainingLen > 0) { lvalPage.clear(); getPageChannel().readPage(lvalPage, pageNum); short rowStart = Table.findRowStart(lvalPage, rowNum, getFormat()); short rowEnd = Table.findRowEnd(lvalPage, rowNum, getFormat()); // read next page information lvalPage.position(rowStart); rowNum = ByteUtil.getUnsignedByte(lvalPage); pageNum = ByteUtil.get3ByteInt(lvalPage); // update rowEnd and remainingLen based on chunkLength int chunkLength = (rowEnd - rowStart) - 4; if (chunkLength > remainingLen) { rowEnd = (short) (rowEnd - (chunkLength - remainingLen)); chunkLength = remainingLen; } remainingLen -= chunkLength; lvalPage.limit(rowEnd); rtnBuf.put(lvalPage); } break; default: throw new IOException("Unrecognized long value type: " + type); } } return rtn; }
From source file:com.healthmarketscience.jackcess.Table.java
/** * Read the table definition/* ww w .java2 s .c om*/ */ private void readTableDefinition(ByteBuffer tableBuffer) throws IOException { if (LOG.isDebugEnabled()) { tableBuffer.rewind(); LOG.debug("Table def block:\n" + ByteUtil.toHexString(tableBuffer, getFormat().SIZE_TDEF_HEADER)); } _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS); _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER); if (getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) { _lastComplexTypeAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER); } _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE); _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS); _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS); short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS); _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS); _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES); int rowNum = ByteUtil.getUnsignedByte(tableBuffer, getFormat().OFFSET_OWNED_PAGES); int pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_OWNED_PAGES + 1); _ownedPages = UsageMap.read(getDatabase(), pageNum, rowNum, false); rowNum = ByteUtil.getUnsignedByte(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES); pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES + 1); _freeSpacePages = UsageMap.read(getDatabase(), pageNum, rowNum, false); for (int i = 0; i < _indexCount; i++) { _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat())); } int colOffset = getFormat().OFFSET_INDEX_DEF_BLOCK + _indexCount * getFormat().SIZE_INDEX_DEFINITION; int dispIndex = 0; for (int i = 0; i < columnCount; i++) { Column column = new Column(this, tableBuffer, colOffset + (i * getFormat().SIZE_COLUMN_HEADER), dispIndex++); _columns.add(column); if (column.isVariableLength()) { // also shove it in the variable columns list, which is ordered // differently from the _columns list _varColumns.add(column); } } tableBuffer.position(colOffset + (columnCount * getFormat().SIZE_COLUMN_HEADER)); for (int i = 0; i < columnCount; i++) { Column column = _columns.get(i); column.setName(readName(tableBuffer)); } Collections.sort(_columns); _autoNumColumns = getAutoNumberColumns(_columns); // setup the data index for the columns int colIdx = 0; for (Column col : _columns) { col.setColumnIndex(colIdx++); } // sort variable length columns based on their index into the variable // length offset table, because we will write the columns in this order Collections.sort(_varColumns, VAR_LEN_COLUMN_COMPARATOR); // read index column information for (int i = 0; i < _indexCount; i++) { _indexDatas.get(i).read(tableBuffer, _columns); } // read logical index info (may be more logical indexes than index datas) for (int i = 0; i < _logicalIndexCount; i++) { _indexes.add(new Index(tableBuffer, _indexDatas, getFormat())); } // read logical index names for (int i = 0; i < _logicalIndexCount; i++) { _indexes.get(i).setName(readName(tableBuffer)); } Collections.sort(_indexes); // re-sort columns if necessary if (getDatabase().getColumnOrder() != ColumnOrder.DATA) { Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR); } for (Column col : _columns) { // some columns need to do extra work after the table is completely // loaded col.postTableLoadInit(); } }
From source file:com.healthmarketscience.jackcess.impl.TableImpl.java
/** * @param database database which owns this table * @param tableBuffer Buffer to read the table with * @param pageNumber Page number of the table definition * @param name Table name/*from w w w . j ava 2s . co m*/ */ protected TableImpl(DatabaseImpl database, ByteBuffer tableBuffer, int pageNumber, String name, int flags) throws IOException { _database = database; _tableDefPageNumber = pageNumber; _name = name; _flags = flags; // read table definition tableBuffer = loadCompleteTableDefinitionBuffer(tableBuffer); _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS); _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER); if (getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) { _lastComplexTypeAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER); } _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE); _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS); _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS); short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS); _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS); _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES); tableBuffer.position(getFormat().OFFSET_OWNED_PAGES); _ownedPages = UsageMap.read(getDatabase(), tableBuffer, false); tableBuffer.position(getFormat().OFFSET_FREE_SPACE_PAGES); _freeSpacePages = UsageMap.read(getDatabase(), tableBuffer, false); for (int i = 0; i < _indexCount; i++) { _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat())); } readColumnDefinitions(tableBuffer, columnCount); readIndexDefinitions(tableBuffer); // read column usage map info while (tableBuffer.remaining() >= 2) { short umapColNum = tableBuffer.getShort(); if (umapColNum == IndexData.COLUMN_UNUSED) { break; } int pos = tableBuffer.position(); UsageMap colOwnedPages = null; UsageMap colFreeSpacePages = null; try { colOwnedPages = UsageMap.read(getDatabase(), tableBuffer, false); colFreeSpacePages = UsageMap.read(getDatabase(), tableBuffer, false); } catch (IllegalStateException e) { // ignore invalid usage map info colOwnedPages = null; colFreeSpacePages = null; tableBuffer.position(pos + 8); LOG.warn("Table " + _name + " invalid column " + umapColNum + " usage map definition: " + e); } for (ColumnImpl col : _columns) { if (col.getColumnNumber() == umapColNum) { col.setUsageMaps(colOwnedPages, colFreeSpacePages); break; } } } // re-sort columns if necessary if (getDatabase().getColumnOrder() != ColumnOrder.DATA) { Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR); } for (ColumnImpl col : _columns) { // some columns need to do extra work after the table is completely // loaded col.postTableLoadInit(); } _fkEnforcer = new FKEnforcer(this); if (!isSystem()) { // after fully constructed, allow column validator to be configured (but // only for user tables) for (ColumnImpl col : _columns) { col.setColumnValidator(null); } } }
From source file:com.healthmarketscience.jackcess.impl.IndexData.java
/** * Reads an index page, populating the correct collection based on the page * type (node or leaf).// w w w . j ava 2s . c o m */ protected void readDataPage(DataPage dataPage) throws IOException { ByteBuffer buffer = _indexBufferH.getPageBuffer(getPageChannel()); getPageChannel().readPage(buffer, dataPage.getPageNumber()); boolean isLeaf = isLeafPage(buffer); dataPage.setLeaf(isLeaf); // note, "header" data is in LITTLE_ENDIAN format, entry data is in // BIG_ENDIAN format int entryPrefixLength = ByteUtil.getUnsignedShort(buffer, getFormat().OFFSET_INDEX_COMPRESSED_BYTE_COUNT); int entryMaskLength = getFormat().SIZE_INDEX_ENTRY_MASK; int entryMaskPos = getFormat().OFFSET_INDEX_ENTRY_MASK; int entryPos = entryMaskPos + entryMaskLength; int lastStart = 0; int totalEntrySize = 0; byte[] entryPrefix = null; List<Entry> entries = new ArrayList<Entry>(); TempBufferHolder tmpEntryBufferH = TempBufferHolder.newHolder(TempBufferHolder.Type.HARD, true, ENTRY_BYTE_ORDER); Entry prevEntry = FIRST_ENTRY; for (int i = 0; i < entryMaskLength; i++) { byte entryMask = buffer.get(entryMaskPos + i); for (int j = 0; j < 8; j++) { if ((entryMask & (1 << j)) != 0) { int length = (i * 8) + j - lastStart; buffer.position(entryPos + lastStart); // determine if we can read straight from the index page (if no // entryPrefix). otherwise, create temp buf with complete entry. ByteBuffer curEntryBuffer = buffer; int curEntryLen = length; if (entryPrefix != null) { curEntryBuffer = getTempEntryBuffer(buffer, length, entryPrefix, tmpEntryBufferH); curEntryLen += entryPrefix.length; } totalEntrySize += curEntryLen; Entry entry = newEntry(curEntryBuffer, curEntryLen, isLeaf); if (prevEntry.compareTo(entry) >= 0) { throw new IOException("Unexpected order in index entries, " + prevEntry + " >= " + entry); } entries.add(entry); if ((entries.size() == 1) && (entryPrefixLength > 0)) { // read any shared entry prefix entryPrefix = new byte[entryPrefixLength]; buffer.position(entryPos + lastStart); buffer.get(entryPrefix); } lastStart += length; prevEntry = entry; } } } dataPage.setEntryPrefix(entryPrefix != null ? entryPrefix : EMPTY_PREFIX); dataPage.setEntries(entries); dataPage.setTotalEntrySize(totalEntrySize); int prevPageNumber = buffer.getInt(getFormat().OFFSET_PREV_INDEX_PAGE); int nextPageNumber = buffer.getInt(getFormat().OFFSET_NEXT_INDEX_PAGE); int childTailPageNumber = buffer.getInt(getFormat().OFFSET_CHILD_TAIL_INDEX_PAGE); dataPage.setPrevPageNumber(prevPageNumber); dataPage.setNextPageNumber(nextPageNumber); dataPage.setChildTailPageNumber(childTailPageNumber); }
From source file:co.paralleluniverse.galaxy.core.Cache.java
private boolean writeData(CacheLine line, ByteBuffer data) { if (data.remaining() > maxItemSize) throw new IllegalArgumentException("Data size is " + data.remaining() + " bytes and exceeds the limit of " + maxItemSize + " bytes."); if (compareBeforeWrite) { if (line.data != null && data.remaining() == line.data.remaining()) { final int p1 = line.data.position(); final int p2 = data.position(); boolean modified = false; for (int i = 0; i < data.remaining(); i++) { if (line.data.get(p1 + i) != data.get(p2 + i)) { modified = true;/*from w ww. jav a 2 s. com*/ break; } } if (!modified) return false; } } allocateLineData(line, data.remaining()); line.data.put(data); line.data.flip(); return true; }
From source file:com.healthmarketscience.jackcess.Table.java
/** * Reads the column data from the given row buffer. Leaves limit unchanged. * Caches the returned value in the rowState. *///from w w w . ja v a 2s . com private static Object getRowColumn(JetFormat format, ByteBuffer rowBuffer, Column column, RowState rowState, Map<Column, byte[]> rawVarValues) throws IOException { byte[] columnData = null; try { NullMask nullMask = rowState.getNullMask(rowBuffer); boolean isNull = nullMask.isNull(column); if (column.getType() == DataType.BOOLEAN) { // Boolean values are stored in the null mask. see note about // caching below return rowState.setRowValue(column.getColumnIndex(), Boolean.valueOf(!isNull)); } else if (isNull) { // well, that's easy! (no need to update cache w/ null) return null; } // reset position to row start rowBuffer.reset(); // locate the column data bytes int rowStart = rowBuffer.position(); int colDataPos = 0; int colDataLen = 0; if (!column.isVariableLength()) { // read fixed length value (non-boolean at this point) int dataStart = rowStart + format.OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET; colDataPos = dataStart + column.getFixedDataOffset(); colDataLen = column.getType().getFixedSize(column.getLength()); } else { int varDataStart; int varDataEnd; if (format.SIZE_ROW_VAR_COL_OFFSET == 2) { // read simple var length value int varColumnOffsetPos = (rowBuffer.limit() - nullMask.byteSize() - 4) - (column.getVarLenTableIndex() * 2); varDataStart = rowBuffer.getShort(varColumnOffsetPos); varDataEnd = rowBuffer.getShort(varColumnOffsetPos - 2); } else { // read jump-table based var length values short[] varColumnOffsets = readJumpTableVarColOffsets(rowState, rowBuffer, rowStart, nullMask); varDataStart = varColumnOffsets[column.getVarLenTableIndex()]; varDataEnd = varColumnOffsets[column.getVarLenTableIndex() + 1]; } colDataPos = rowStart + varDataStart; colDataLen = varDataEnd - varDataStart; } // grab the column data columnData = new byte[colDataLen]; rowBuffer.position(colDataPos); rowBuffer.get(columnData); if ((rawVarValues != null) && column.isVariableLength()) { // caller wants raw value as well rawVarValues.put(column, columnData); } // parse the column data. we cache the row values in order to be able // to update the index on row deletion. note, most of the returned // values are immutable, except for binary data (returned as byte[]), // but binary data shouldn't be indexed anyway. return rowState.setRowValue(column.getColumnIndex(), column.read(columnData)); } catch (Exception e) { // cache "raw" row value. see note about caching above rowState.setRowValue(column.getColumnIndex(), Column.rawDataWrapper(columnData)); return rowState.handleRowError(column, columnData, e); } }
From source file:com.linkedin.databus.core.DbusEventBuffer.java
/** * Injects an event in the regular stream of events * @return true iff successful/* ww w . ja va2 s .c o m*/ * @throws InvalidEventException */ public boolean injectEvent(DbusEventInternalReadable event) throws InvalidEventException { final ByteBuffer eventBuf = event.getRawBytes(); byte[] cpEventBytes = null; if (eventBuf.hasArray()) { cpEventBytes = eventBuf.array(); } else { cpEventBytes = new byte[event.getRawBytes().limit()]; eventBuf.get(cpEventBytes); } ByteArrayInputStream cpIs = new ByteArrayInputStream(cpEventBytes); ReadableByteChannel cpRbc = Channels.newChannel(cpIs); int ecnt = readEvents(cpRbc); return ecnt > 0; }
From source file:com.linkedin.databus.core.DbusEventBuffer.java
/** * Used by readEventsInternal to move the partial event at the end to the beginning of the * staging buffer so we can try to read more data. * * @param readPos/*from w ww . j av a 2 s. c om*/ * @param logDebugEnabled */ private void compactStgBuffer(ReadEventsReadPosition readPos, boolean logDebugEnabled) { final ByteBuffer readBuffer = readPos.getReadBuffer(); readBuffer.clear();//despite its name, clear() does not remove the data if (readPos.hasNext()) { if (logDebugEnabled) { _log.debug("Copying " + readPos.bytesRemaining() + " bytes to the start of the readBuffer"); } for (int i = 0; i < readPos.bytesRemaining(); ++i) { readBuffer.put(readBuffer.get(readPos.getPosition() + i)); } readPos.startIteration(); if (logDebugEnabled) { _log.debug("readBuffer after compaction: " + readBuffer + "; " + readPos); } } }
From source file:edu.umass.cs.gigapaxos.paxospackets.RequestPacket.java
/** * The weird constant above is to try to avoid mistakes in the painful (but * totally worth it) byte'ification method below. Using bytes as opposed to * json strings makes a non-trivial difference (~2x over json-smart and >4x * over org.json. So we just chuck json libraries and use our own byte[] * serializer for select packets./* w w w . j a v a2 s . c om*/ * * The serialization overhead really matters most for RequestPacket and * AcceptPacket. Every request, even with batching, must be deserialized by * the coordinator and must be serialized back while sending out the * AcceptPacket. The critical path is the following at a coordinator and is * incurred at least in part even with batching for every request: (1) * receive request, (2) send accept, (3) receive accept_replies, (4) send * commit Accordingly, we use byteification for {@link RequestPacket}, * {@link AcceptPacket}, {@link BatchedAcceptReply} and * {@link BatchedCommit}. * * */ protected byte[] toBytes(boolean instrument) { // return cached value if already present if ((this.getType() == PaxosPacketType.REQUEST || this.getType() == PaxosPacketType.ACCEPT) && this.byteifiedSelf != null && !instrument) return this.byteifiedSelf; // check if we can use byteification at all; if not, use toString() if (!((BYTEIFICATION && IntegerMap.allInt()) || instrument)) { try { if (this.getType() == PaxosPacketType.REQUEST || this.getType() == PaxosPacketType.ACCEPT) return this.byteifiedSelf = this.toString().getBytes(CHARSET); // cache return this.toString().getBytes(CHARSET); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); return null; } } // else byteify try { int exactLength = 0; byte[] array = new byte[this.lengthEstimate()]; ByteBuffer bbuf = ByteBuffer.wrap(array); assert (bbuf.position() == 0); // paxospacket stuff super.toBytes(bbuf); int ppPos = bbuf.position(); // for assertion assert (bbuf.position() == ByteBuffer.wrap(array, SIZEOF_PAXOSPACKET_FIXED - 1, 1).get() + SIZEOF_PAXOSPACKET_FIXED) : bbuf.position() + " != " + ByteBuffer.wrap(array, SIZEOF_PAXOSPACKET_FIXED - 1, 1).get() + SIZEOF_PAXOSPACKET_FIXED; exactLength += (bbuf.position()); bbuf.putLong(this.requestID); bbuf.put(this.stop ? (byte) 1 : (byte) 0); exactLength += (Long.BYTES + 1); // addresses /* Note: 0 is ambiguous with wildcard address, but that's okay * because an incoming packet will never come with a wildcard * address. */ bbuf.put(this.clientAddress != null ? this.clientAddress.getAddress().getAddress() : new byte[4]); // 0 (not -1) means invalid port bbuf.putShort(this.clientAddress != null ? (short) this.clientAddress.getPort() : 0); /* Note: 0 is an ambiguous wildcard address that could also be a * legitimate value of the listening socket address. If the request * happens to have no listening address, we will end up assuming it * was received on the wildcard address. At worst, the matching for * the corresponding response back to the client can fail. */ bbuf.put(this.listenAddress != null ? this.listenAddress.getAddress().getAddress() : new byte[4]); // 0 (not -1) means invalid port bbuf.putShort(this.listenAddress != null ? (short) this.listenAddress.getPort() : 0); exactLength += 2 * (Integer.BYTES + Short.BYTES); // other non-final fields bbuf.putInt(this.entryReplica); bbuf.putLong(this.entryTime); bbuf.put(this.shouldReturnRequestValue ? (byte) 1 : (byte) 0); bbuf.putInt(this.forwardCount); exactLength += (Integer.BYTES + Long.BYTES + 1 + Integer.BYTES); // digest related fields: broadcasted, digest // whether this request was already broadcasted bbuf.put(this.broadcasted ? (byte) 1 : (byte) 0); exactLength += 1; assert (exactLength == // where parent left us off ppPos + SIZEOF_REQUEST_FIXED // for the three int fields not yet filled - 4 * Integer.BYTES) : exactLength + " != [" + ppPos + " + " + SIZEOF_REQUEST_FIXED + " - " + 4 * Integer.BYTES + "]"; // digest length and digest iteself bbuf.putInt(this.digest != null ? this.digest.length : 0); exactLength += Integer.BYTES; if (this.digest != null) bbuf.put(this.digest); exactLength += (this.digest != null ? this.digest.length : 0); // /////////// end of digest related fields ////////// // highly variable length fields // requestValue byte[] reqValBytes = this.requestValue != null ? this.requestValue.getBytes(CHARSET) : new byte[0]; bbuf.putInt(reqValBytes != null ? reqValBytes.length : 0); bbuf.put(reqValBytes); exactLength += (4 + reqValBytes.length); // responseValue byte[] respValBytes = this.responseValue != null ? this.responseValue.getBytes(CHARSET) : new byte[0]; bbuf.putInt(respValBytes != null ? respValBytes.length : 0); bbuf.put(respValBytes); exactLength += (4 + respValBytes.length); // batched requests batchSize|(length:batchedReqBytes)+ bbuf.putInt(this.batchSize()); exactLength += (4); if (this.batchSize() > 0) for (RequestPacket req : this.batched) { byte[] element = req.toBytes(); bbuf.putInt(element.length); bbuf.put(element); exactLength += (4 + element.length); } // bbuf.array() was a generous allocation byte[] exactBytes = new byte[exactLength]; bbuf.flip(); assert (bbuf.remaining() == exactLength) : bbuf.remaining() + " != " + exactLength; bbuf.get(exactBytes); if (this.getType() == PaxosPacketType.REQUEST) this.byteifiedSelf = exactBytes; return exactBytes; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return null; }