Example usage for java.nio ByteBuffer put

List of usage examples for java.nio ByteBuffer put

Introduction

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

Prototype

public ByteBuffer put(ByteBuffer src) 

Source Link

Document

Writes all the remaining bytes of the src byte buffer to this buffer's current position, and increases both buffers' position by the number of bytes copied.

Usage

From source file:edu.harvard.iq.dvn.ingest.dsb.impl.DvnNewJavaFieldCutter.java

public void cutColumns(InputStream in, int noCardsPerCase, int caseLength, String delimitor, String tabFileName)
        throws IOException {

    if (delimitor == null) {
        delimitor = defaultDelimitor;/*w ww .  j  a v a  2s.c  om*/
    }

    OUT_LEN = colwidth; // calculated by parseList
    dbgLog.fine("out_len=" + OUT_LEN);

    String firstline = null;

    if (caseLength == 0) {

        int cread;
        int ccounter = 0;

        firstline = "";

        while (caseLength == 0 && (cread = in.read()) != -1) {
            ccounter++;
            if (cread == '\n') {
                caseLength = ccounter;
            }
            char c = (char) cread;
            firstline = firstline + c;
        }

    }

    if (caseLength == 0) {
        throw new IOException("Subsetting failed: could not read incoming byte stream. "
                + "(Requested file may be unavailable or missing)");

    }

    REC_LEN = caseLength;
    dbgLog.fine("REC_LEN=" + REC_LEN);

    for (int i = 0; i < cargSet.get(Long.valueOf(noCardsPerCase)).size(); i++) {
        int varEndOffset = cargSet.get(Long.valueOf(noCardsPerCase)).get(i).get(1);

        if (REC_LEN <= varEndOffset + 1) {
            throw new IOException("Failed to subset incoming byte stream. Invalid input. "
                    + "(Detected the first record of " + REC_LEN + " bytes; "
                    + "one of the columns requested ends at " + varEndOffset + " bytes).");
        }
    }

    Boolean dottednotation = false;
    Boolean foundData = false;

    // cutting a data file

    ReadableByteChannel rbc = Channels.newChannel(in);
    // input byte-buffer size = row-length + 1(=> new line char)
    ByteBuffer inbuffer = ByteBuffer.allocate(REC_LEN);

    OutputStream outs = new FileOutputStream(tabFileName);
    WritableByteChannel outc = Channels.newChannel(outs);
    ByteBuffer outbuffer = null;

    int pos = 0;
    int offset = 0;
    int outoffset = 0;

    int begin = 0;
    int end = 0;
    int blankoffset = 0;

    int blanktail = 0;
    int k;

    try {
        // lc: line counter
        int lc = 0;
        while (firstline != null || rbc.read(inbuffer) != -1) {

            if (firstline != null) {
                // we have the first line saved as a String:
                inbuffer.put(firstline.getBytes());
                firstline = null;
            }

            // calculate i-th card number
            lc++;
            k = lc % noCardsPerCase;
            if (k == 0) {
                k = noCardsPerCase;
            }
            //out.println("***** " +lc+ "-th line, recod k=" + k + " *****");
            byte[] line_read = new byte[OUT_LEN];
            byte[] junk = new byte[REC_LEN];
            byte[] line_final = new byte[OUT_LEN];

            //out.println("READ: " + offset);
            inbuffer.rewind();

            offset = 0;
            outoffset = 0;

            // how many variables are cut from this k-th card
            int noColumns = cargSet.get(Long.valueOf(k)).size();

            //out.println("noColumns=" + noColumns);
            //out.println("cargSet k =" + cargSet.get(Long.valueOf(k)));

            for (int i = 0; i < noColumns; i++) {
                //out.println("**** " + i +"-th col ****");
                begin = cargSet.get(Long.valueOf(k)).get(i).get(0); // bounds[2 * i];
                end = cargSet.get(Long.valueOf(k)).get(i).get(1); // bounds[2 * i + 1];

                //out.println("i: begin: " + begin + "\ti: end:" + end);

                try {
                    // throw away offect bytes
                    if (begin - offset - 1 > 0) {
                        inbuffer.get(junk, 0, (begin - offset - 1));
                    }
                    // get requested bytes
                    inbuffer.get(line_read, outoffset, (end - begin + 1));
                    // set outbound data
                    outbounds[2 * i] = outoffset;
                    outbounds[2 * i + 1] = outoffset + (end - begin);
                    // current position moved to outoffset
                    pos = outoffset;

                    dottednotation = false;
                    foundData = false;

                    blankoffset = 0;
                    blanktail = 0;

                    // as position increases
                    while (pos <= (outoffset + (end - begin))) {

                        //out.println("pos=" + pos + "\tline_read[pos]=" +
                        //    new String(line_read).replace("\000", "\052"));

                        // decimal octal
                        // 48 =>0 60
                        // 46 => . 56
                        // 32 = space 40

                        // dot: 
                        if (line_read[pos] == '\056') {
                            dottednotation = true;
                        }

                        // space:
                        if (line_read[pos] == '\040') {
                            if (foundData) {
                                blanktail = blanktail > 0 ? blanktail : pos - 1;
                            } else {
                                blankoffset = pos + 1;
                            }
                        } else {
                            foundData = true;
                            blanktail = 0;
                        }

                        pos++;
                    }
                    // increase the outoffset by width
                    outoffset += (end - begin + 1);
                    // dot false
                    if (!dottednotation) {
                        if (blankoffset > 0) {
                            // set outbound value to blankoffset
                            outbounds[2 * i] = blankoffset;
                        }
                        if (blanktail > 0) {
                            outbounds[2 * i + 1] = blanktail;
                        }
                    }

                } catch (BufferUnderflowException bufe) {
                    //bufe.printStackTrace();
                    throw new IOException(bufe.getMessage());
                }
                // set offset to the value of end-position
                offset = end;
            }

            outoffset = 0;
            // for each var
            for (int i = 0; i < noColumns; i++) {
                begin = outbounds[2 * i];
                end = outbounds[2 * i + 1];
                //out.println("begin=" + begin + "\t end=" + end);
                for (int j = begin; j <= end; j++) {
                    line_final[outoffset++] = line_read[j];
                }

                if (i < (noColumns - 1)) {
                    line_final[outoffset++] = '\011'; // tab x09
                } else {
                    if (k == cargSet.size()) {
                        line_final[outoffset++] = '\012'; // LF x0A
                    } else {
                        line_final[outoffset++] = '\011'; // tab x09
                    }
                }
            }
            //out.println("line_final=" +
            //    new String(line_final).replace("\000", "\052"));
            outbuffer = ByteBuffer.wrap(line_final, 0, outoffset);
            outc.write(outbuffer);
            inbuffer.clear();

        } // while loop
    } catch (IOException ex) {
        //ex.printStackTrace();
        throw new IOException("Failed to subset incoming fixed-field stream: " + ex.getMessage());
    }

}

From source file:com.linkedin.databus.core.DbusEventV1.java

private static int serializeStringKeyEvent(byte[] key, ByteBuffer serializationBuffer,
        DbusEventInfo eventInfo) {//w  w w .  j ava 2s. c om
    ByteBuffer valueBuffer = eventInfo.getValueByteBuffer();
    int payloadLen = (valueBuffer == null) ? eventInfo.getValueLength() : valueBuffer.remaining();

    int startPosition = serializationBuffer.position();
    byte[] attributes = null;

    // Event without explicit opcode specified should always be considered UPSERT or existing code will break
    if (eventInfo.getOpCode() == DbusOpcode.DELETE) {
        if (serializationBuffer.order() == ByteOrder.BIG_ENDIAN)
            attributes = DeleteStringKeyAttributesBigEndian.clone();
        else
            attributes = DeleteStringKeyAttributesLittleEndian.clone();
    } else {
        if (serializationBuffer.order() == ByteOrder.BIG_ENDIAN)
            attributes = UpsertStringKeyAttributesBigEndian.clone();
        else
            attributes = UpsertStringKeyAttributesLittleEndian.clone();
    }

    if (eventInfo.isEnableTracing()) {
        setTraceFlag(attributes, serializationBuffer.order());
    }

    if (eventInfo.isReplicated())
        setExtReplicationFlag(attributes, serializationBuffer.order());

    serializationBuffer.put(DbusEventFactory.DBUS_EVENT_V1).putInt(HeaderCrcDefault)
            .putInt(StringValueOffset(key.length) + payloadLen).put(attributes)
            .putLong(eventInfo.getSequenceId()).putShort(eventInfo.getpPartitionId())
            .putShort(eventInfo.getlPartitionId()).putLong(eventInfo.getTimeStampInNanos())
            .putShort(eventInfo.getSrcId()).put(eventInfo.getSchemaId(), 0, 16).putInt(HeaderCrcDefault)
            .putInt(key.length).put(key);
    if (valueBuffer != null) {
        // note. put will advance position. In the case of wrapped byte[] it is ok, in the case of
        // ByteBuffer this is actually a read only copy of the buffer passed in.
        serializationBuffer.put(valueBuffer);
    }

    int stopPosition = serializationBuffer.position();
    long valueCrc = ByteBufferCRC32.getChecksum(serializationBuffer, startPosition + StringKeyOffset,
            key.length + payloadLen);
    Utils.putUnsignedInt(serializationBuffer, startPosition + ValueCrcOffset, valueCrc);
    if (eventInfo.isAutocommit()) {
        //TODO (DDSDBUS-61): Medium : can avoid new here
        DbusEventV1 e = new DbusEventV1(serializationBuffer, startPosition);
        e.applyCrc();
    }

    serializationBuffer.position(stopPosition);
    return (stopPosition - startPosition);
}

From source file:com.newatlanta.appengine.nio.channels.GaeFileChannel.java

@Override
public synchronized int read(ByteBuffer dst) throws IOException {
    checkReadOptions();/*ww  w.  j  av a2s  .co  m*/
    long fileLen = doGetSize();
    if (position >= fileLen) {
        return -1;
    }
    int totalBytesRead = 0;
    while (dst.hasRemaining() && (position < fileLen)) {
        int r = dst.remaining();
        initBuffer(r);
        if (calcBlockIndex(position + r - 1) == index) {
            // within current block, read until dst is full or to EOF
            int eofoffset = calcBlockOffset(fileLen);
            int limit = Math.min(buffer.position() + r, eofoffset);
            if (limit > buffer.capacity()) {
                // copy the remaining bytes in buffer to dst, then fill dst
                // with empty bytes until full or to the calculated limit
                dst.put(buffer);
                dst.put(new byte[Math.min(limit - buffer.capacity(), dst.remaining())]);
            } else {
                buffer.limit(limit);
                dst.put(buffer);
                buffer.limit(buffer.capacity()); // restore original limit
            }
            int bytesRead = (r - dst.remaining());
            totalBytesRead += bytesRead;
            positionInternal(position + bytesRead, false);
        } else {
            // read to the end of the current block
            r = buffer.remaining();
            if (r == 0) {
                r = (int) (blockSize - position);
                dst.put(new byte[r]);
            } else {
                dst.put(buffer);
            }
            totalBytesRead += r;

            // move position to beginning of next buffer, repeat loop
            positionInternal(position + r, false);
        }
    }
    //closeBlock();
    return totalBytesRead;
}

From source file:com.serenegiant.media.TLMediaEncoder.java

/**
 * Method to set byte array to the MediaCodec encoder
* if you use Surface to input data to encoder, you should not call this method
 * @param buffer//  w  ww .j av  a  2s.  c o m
 * @param lengthlength of byte array, zero means EOS.
 * @param presentationTimeUs
 */
//   protected void encode(final byte[] buffer, final int length, final long presentationTimeUs) {
protected void encode(final ByteBuffer buffer, int length, long presentationTimeUs) {
    if (!mIsRunning || !isRecording())
        return;
    while (mIsRunning) {
        final int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
        if (inputBufferIndex >= 0) {
            final ByteBuffer inputBuffer = encoderInputBuffers[inputBufferIndex];
            inputBuffer.clear();
            if (buffer != null) {
                inputBuffer.put(buffer);
            }
            if (length <= 0) {
                // send EOS
                mIsEOS = true;
                if (DEBUG)
                    Log.i(TAG, "send BUFFER_FLAG_END_OF_STREAM");
                mMediaCodec.queueInputBuffer(inputBufferIndex, 0, 0, presentationTimeUs,
                        MediaCodec.BUFFER_FLAG_END_OF_STREAM);
            } else {
                mMediaCodec.queueInputBuffer(inputBufferIndex, 0, length, presentationTimeUs, 0);
            }
            break;
        } else if (inputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
            // wait for MediaCodec encoder is ready to encode
            // nothing to do here because MediaCodec#dequeueInputBuffer(TIMEOUT_USEC)
            // will wait for maximum TIMEOUT_USEC(10msec) on each call
        }
    }
}

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

/**
 * Create the usage map definition page buffer.  The "used pages" map is in
 * row 0, the "pages with free space" map is in row 1.  Index usage maps are
 * in subsequent rows.// w ww  .ja va  2s . c  o  m
 */
private static void createUsageMapDefinitionBuffer(TableCreator creator) throws IOException {
    // 2 table usage maps plus 1 for each index
    int umapNum = 2 + creator.getIndexCount();

    JetFormat format = creator.getFormat();
    int usageMapRowLength = format.OFFSET_USAGE_MAP_START + format.USAGE_MAP_TABLE_BYTE_LENGTH;
    int freeSpace = format.DATA_PAGE_INITIAL_FREE_SPACE
            - (umapNum * getRowSpaceUsage(usageMapRowLength, format));

    // for now, don't handle writing that many indexes
    if (freeSpace < 0) {
        throw new IOException("FIXME attempting to write too many indexes");
    }

    int umapPageNumber = creator.getUmapPageNumber();

    PageChannel pageChannel = creator.getPageChannel();
    ByteBuffer rtn = pageChannel.createPageBuffer();
    rtn.put(PageTypes.DATA);
    rtn.put((byte) 0x1); //Unknown
    rtn.putShort((short) freeSpace); //Free space in page
    rtn.putInt(0); //Table definition
    rtn.putInt(0); //Unknown
    rtn.putShort((short) umapNum); //Number of records on this page

    // write two rows of usage map definitions for the table
    int rowStart = findRowEnd(rtn, 0, format) - usageMapRowLength;
    for (int i = 0; i < 2; ++i) {
        rtn.putShort(getRowStartOffset(i, format), (short) rowStart);
        if (i == 0) {
            // initial "usage pages" map definition
            rtn.put(rowStart, UsageMap.MAP_TYPE_REFERENCE);
        } else {
            // initial "pages with free space" map definition
            rtn.put(rowStart, UsageMap.MAP_TYPE_INLINE);
        }
        rowStart -= usageMapRowLength;
    }

    if (creator.hasIndexes()) {

        for (int i = 0; i < creator.getIndexes().size(); ++i) {
            IndexBuilder idx = creator.getIndexes().get(i);

            // allocate root page for the index
            int rootPageNumber = pageChannel.allocateNewPage();
            int umapRowNum = i + 2;

            // stash info for later use
            TableCreator.IndexState idxState = creator.getIndexState(idx);
            idxState.setRootPageNumber(rootPageNumber);
            idxState.setUmapRowNumber((byte) umapRowNum);
            idxState.setUmapPageNumber(umapPageNumber);

            // index map definition, including initial root page
            rtn.putShort(getRowStartOffset(umapRowNum, format), (short) rowStart);
            rtn.put(rowStart, UsageMap.MAP_TYPE_INLINE);
            rtn.putInt(rowStart + 1, rootPageNumber);
            rtn.put(rowStart + 5, (byte) 1);

            rowStart -= usageMapRowLength;
        }
    }

    pageChannel.writePage(rtn, umapPageNumber);
}

From source file:de.rwhq.btree.LeafNode.java

/**
 * Initializes the Leaf with data/*from ww w  . ja v  a 2 s  .c o m*/
 *
 * @param kvs
 *       data to insert as KeyValueObj Array
 * @param from
 *       from where in the array to start inserting
 *    @param maxTo
 *        usually lvs.length - 1
 * @return number of keys inserted
 */
public int bulkInitialize(final SimpleEntry<K, ?>[] kvs, final int from, final int maxTo) {
    initialize();

    final int remainingToInsert = maxTo - from + 1;
    if (remainingToInsert <= 0)
        return 0;

    final ByteBuffer buf = rawPage().bufferForWriting(Header.size());

    final int entrySize = keySerializer.getSerializedLength() + valueSerializer.getSerializedLength();
    final int entriesThatFit = buf.remaining() / entrySize;
    final int entriesToInsert = entriesThatFit > remainingToInsert ? remainingToInsert : entriesThatFit;

    // determine value type
    boolean isSerialized = (kvs[from].getValue() instanceof byte[]);

    if (!isSerialized) {
        for (int i = 0; i < entriesToInsert; i++) {
            buf.put(keySerializer.serialize(kvs[from + i].getKey()));
            buf.put(valueSerializer.serialize((V) kvs[from + i].getValue()));
        }
    } else {
        for (int i = 0; i < entriesToInsert; i++) {
            buf.put(keySerializer.serialize(kvs[from + i].getKey()));
            buf.put((byte[]) kvs[from + i].getValue());
        }
    }

    setNumberOfEntries(entriesToInsert);

    rawPage.sync();
    return entriesToInsert;
}

From source file:com.slytechs.capture.file.editor.AbstractRawIterator.java

public void resize(final long size) throws IOException {

    // Check for reasonable value since we currently only allocate from heap
    if (size > Integer.MAX_VALUE) {
        throw new UnsupportedOperationException("Current implementation uses in memory allocation. "
                + "Not enough memory to allocate for the request. "
                + "Must use physical storage backed allocation cache.");
    }// w  w w .  j a v a  2 s .c o  m

    final long p = this.getPosition();
    final ByteBuffer b = this.next();
    final int length = (int) this.getRecordLength(b);

    if (size == length) {
        return; // Nothing to do

    } else if (size < 0) {
        /*
         * Simply trucate the record by removing part of its region
         */
        final int delta = length - (int) size;
        this.edits.remove(p + delta, delta);

    } else {
        /*
         * Expand the record by replacing the original segment where the record
         * resides, with a new segment of the new size. Copy the original record
         * content into the new buffer that replaces it.
         */
        final PartialLoader loader = new MemoryCacheLoader((int) size, headerReader);
        final ByteBuffer dst = loader.fetchBlock(0, (int) size).getByteBuffer();

        // Do copy of or original record buffer into the new buffer
        dst.put(b);

        // Do the region replacement
        this.edits.replace(p, length, size, loader);
    }

    this.autoflush.autoflushChange(length + size);
}

From source file:byps.http.HHttpServlet.java

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    if (log.isDebugEnabled())
        log.debug("doGet(");

    // Test adapter function?
    final String testAdapterStr = request.getParameter(HTestAdapter.KEY_PARAM);
    if (testAdapterStr != null && testAdapterStr.length() != 0) {
        doTestAdapter(request, response);
        if (log.isDebugEnabled())
            log.debug(")doGet");
        return;/*from   w  w w  .j a  v a  2s  .  com*/
    }

    // Negotiate?
    final String negoStr = request.getParameter("negotiate");
    if (log.isDebugEnabled())
        log.debug("negotiate=" + negoStr);
    if (negoStr != null && negoStr.length() != 0) {
        ByteBuffer ibuf = ByteBuffer.allocate(negoStr.length() * 3);
        ibuf.put(negoStr.getBytes("UTF-8"));
        ibuf.flip();
        doNegotiate(request, response, ibuf);
        return;
    }

    // Get stream or old utility request

    // Parameter messageid
    final String messageIdStr = request.getParameter("messageid");
    if (log.isDebugEnabled())
        log.debug("messageId=" + messageIdStr);
    if (messageIdStr == null || messageIdStr.length() == 0) {
        // response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.getWriter().println("HHttpServlet running.");
        return;
    }

    // Paremter streamid is set, if a stream is to be read
    final String streamIdStr = request.getParameter("streamid");
    if (log.isDebugEnabled())
        log.debug("streamId=" + streamIdStr);

    // Parameter cancel is set, if the message given by messageid must be
    // canceled. For newer clients, this functionality is replaced by the
    // UtilityRequest interface.
    // To support older clients, it is still handled here.
    final String cancelStr = request.getParameter("cancel");
    if (log.isDebugEnabled())
        log.debug("cancel=" + cancelStr);
    if (cancelStr != null && cancelStr.length() != 0) {

        final HSession sess = getSessionFromMessageHeaderOrHttpRequest(null, request);
        if (sess != null) {

            long messageId = BBufferJson.parseLong(messageIdStr);

            if (messageId == HWireClient.MESSAGEID_CANCEL_ALL_REQUESTS) {
                if (log.isDebugEnabled())
                    log.debug("activeMessages.cleanup");
                sess.wireServer.cancelAllMessages();
            } else if (messageId == HWireClient.MESSAGEID_DISCONNECT) {
                if (log.isDebugEnabled())
                    log.debug("sess.done");
                sess.done();
            } else {
                if (log.isDebugEnabled())
                    log.debug("activeMessages.cancelMessage");
                sess.wireServer.cancelMessage(messageId);
            }

        }

        response.setStatus(HttpServletResponse.SC_OK);
        response.getOutputStream().close();

    }

    // Read a stream
    else if (streamIdStr != null && streamIdStr.length() != 0) {
        if (log.isDebugEnabled())
            log.debug("sendOutgoingStream");

        final String serverIdStr = request.getParameter("serverid");

        // Byte-Range request?
        // http://stackoverflow.com/questions/8293687/sample-http-range-request-session
        // Range: bytes=0-
        // Range: bytes=64312833-64657026

        final BContentStream stream = doGetStream(serverIdStr, messageIdStr, streamIdStr);

        HRangeRequest rangeRequest = new HRangeRequest(request);

        sendOutgoingStream(stream, response, rangeRequest);
    }

    // Bad request
    else {
        response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
        response.getOutputStream().close();
    }

    if (log.isDebugEnabled())
        log.debug(")doGet");
}

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

/**
 * Writes the given name into the given buffer in the format as expected by
 * {@link #readName}./*ww  w. jav a 2s.  c o  m*/
 */
static void writeName(ByteBuffer buffer, String name, Charset charset) {
    ByteBuffer encName = Column.encodeUncompressedText(name, charset);
    buffer.putShort((short) encName.remaining());
    buffer.put(encName);
}

From source file:com.healthmarketscience.jackcess.impl.ColumnImpl.java

/**
 * Writes the column definitions into a table definition buffer.
 * @param buffer Buffer to write to/*w ww  .  j a v  a  2 s  . co m*/
 */
protected static void writeDefinitions(TableCreator creator, ByteBuffer buffer) throws IOException {
    List<ColumnBuilder> columns = creator.getColumns();
    short fixedOffset = (short) 0;
    short variableOffset = (short) 0;
    // we specifically put the "long variable" values after the normal
    // variable length values so that we have a better chance of fitting it
    // all (because "long variable" values can go in separate pages)
    short longVariableOffset = countNonLongVariableLength(columns);
    for (ColumnBuilder col : columns) {

        buffer.put(col.getType().getValue());
        buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); //constant magic number
        buffer.putShort(col.getColumnNumber()); //Column Number

        if (col.isVariableLength()) {
            if (!col.getType().isLongValue()) {
                buffer.putShort(variableOffset++);
            } else {
                buffer.putShort(longVariableOffset++);
            }
        } else {
            buffer.putShort((short) 0);
        }

        buffer.putShort(col.getColumnNumber()); //Column Number again

        if (col.getType().isTextual()) {
            // this will write 4 bytes (note we don't support writing dbs which
            // use the text code page)
            writeSortOrder(buffer, col.getTextSortOrder(), creator.getFormat());
        } else {
            // note scale/precision not stored for calculated numeric fields
            if (col.getType().getHasScalePrecision() && !col.isCalculated()) {
                buffer.put(col.getPrecision()); // numeric precision
                buffer.put(col.getScale()); // numeric scale
            } else {
                buffer.put((byte) 0x00); //unused
                buffer.put((byte) 0x00); //unused
            }
            buffer.putShort((short) 0); //Unknown
        }

        buffer.put(getColumnBitFlags(col)); // misc col flags

        // note access doesn't seem to allow unicode compression for calced fields
        if (col.isCalculated()) {
            buffer.put(CALCULATED_EXT_FLAG_MASK);
        } else if (col.isCompressedUnicode()) { //Compressed
            buffer.put(COMPRESSED_UNICODE_EXT_FLAG_MASK);
        } else {
            buffer.put((byte) 0);
        }

        buffer.putInt(0); //Unknown, but always 0.

        //Offset for fixed length columns
        if (col.isVariableLength()) {
            buffer.putShort((short) 0);
        } else {
            buffer.putShort(fixedOffset);
            fixedOffset += col.getType().getFixedSize(col.getLength());
        }

        if (!col.getType().isLongValue()) {
            short length = col.getLength();
            if (col.isCalculated()) {
                // calced columns have additional value overhead
                if (!col.getType().isVariableLength() || col.getType().getHasScalePrecision()) {
                    length = CalculatedColumnUtil.CALC_FIXED_FIELD_LEN;
                } else {
                    length += CalculatedColumnUtil.CALC_EXTRA_DATA_LEN;
                }
            }
            buffer.putShort(length); //Column length
        } else {
            buffer.putShort((short) 0x0000); // unused
        }

    }
    for (ColumnBuilder col : columns) {
        TableImpl.writeName(buffer, col.getName(), creator.getCharset());
    }
}