Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (C) 2013-2015 Regents of the University of California.

Author(s):
Jeff Thompson <jefft0@remap.ucla.edu> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. A copy of the GNU Lesser General Public License is in the file COPYING.
 
 
 package net.named_data.jndn.encoding;
 
A BinaryXmlEncoder holds an output buffer and has methods to output Binary XML.
 
 public class BinaryXmlEncoder {
  
Create a new BinaryXmlEncoder to use a DynamicByteBuffer with the initialCapacity. When done, you should call getOutput().

Parameters:
initialCapacity The initial capacity of buffer().
 
   public
   BinaryXmlEncoder(int initialCapacity)
   {
      = new DynamicByteBuffer(initialCapacity);
   }

  
Create a new BinaryXmlEncoder with a default DynamicByteBuffer for the output buffer. When done, you shoul call getOutput().
 
   public
   {
      = new DynamicByteBuffer(16);
   }

  
Get the current offset where the next data will be written in the output buffer.

Returns:
The offset in the output buffer.
 
   public final int
   getOffset()
   {
     return .position();
   }

  
Return a slice of the output buffer up to the current position.

Returns:
A ByteBuffer which shares the same underlying buffer with the output buffer.
 
   public final ByteBuffer
   getOutput()
   {
     return .flippedBuffer();
   }
 
   public static final int ENCODING_LIMIT_1_BYTE = ((1 << .) - 1);
   public static final int ENCODING_LIMIT_2_BYTES = ((1 << (. + .)) - 1);
   public static final int ENCODING_LIMIT_3_BYTES = ((1 << (. + 2 * .)) - 1);

  
Write an element start header using DTAG with the tag to the output buffer.

Parameters:
tag The DTAG tag.
 
   public final void
   writeElementStartDTag(int tag)
   {
   }

  
Write an element close to the output buffer.
 
   public final void
   {
   }

  
Write a BLOB header, then the bytes of the blob value to the output buffer.

Parameters:
value A Blob with the buffer for the value.
 
   public final void
   writeBlob(Blob value)
   {
     encodeTypeAndValue(.value.size());
    if (value.size() > 0)
      writeBuffer(value.buf());
  }

  
Write an element start header using DTAG with the tag to the output buffer, then the blob, then an element close. (If you want to just write the blob, use writeBlob.)

Parameters:
tag The DTAG tag.
value A Blob with the buffer for the value.
  public final void
  writeBlobDTagElement(int tagBlob value)
  {
    writeBlob(value);
  }

  
If value.buf() is null or value.size() is 0 then do nothing, otherwise call writeBlobDTagElement.

Parameters:
tag The DTAG tag.
value A Blob with the buffer for the value.
  public final void
  writeOptionalBlobDTagElement(int tagBlob value)
  {
    if (value.buf() != null && value.size() > 0)
      writeBlobDTagElement(tagvalue);
  }

  
Write a UDATA header, then the bytes of the UDATA value to the output buffer.

Parameters:
value A Blob with the buffer for the value.
  public final void
  writeUData(Blob value)
  {
    writeBuffer(value.buf());
  }

  
Write an element start header using DTAG with the tag to the output buffer, then the UDATA value, then an element close. (If you want to just write the UDATA value, use writeUData.)

Parameters:
tag The DTAG tag.
value A Blob with the buffer for the value.
  public final void
  writeUDataDTagElement(int tagBlob value)
  {
    writeUData(value);
  }

  
If value.buf() is null or value.size() is 0 then do nothing, otherwise call writeUDataDTagElement.

Parameters:
tag The DTAG tag.
value A Blob with the buffer for the value.
  public final void
  writeOptionalUDataDTagElement(int tagBlob value)
  {
    if (value.buf() != null && value.size() > 0)
      writeUDataDTagElement(tagvalue);
  }

  
Write a UDATA header, then the value as an unsigned decimal integer.

Parameters:
value The unsigned integer.
  public final void
  {
    // First write the decimal int (to find out how many bytes it is), then shift it forward to make room for the header.
    int startPosition = .position();
  }

  
Write an element start header using DTAG with the tag to the output buffer, then the value as an unsigned decimal integer, then an element close. (If you want to just write the integer, use writeUnsignedDecimalInt.)

Parameters:
tag The DTAG tag.
value The unsigned integer.
  public final void
  writeUnsignedDecimalIntDTagElement(int tagint value)
  {
  }

  
If value is negative then do nothing, otherwise call writeUnsignedDecimalIntDTagElement.

Parameters:
tag The DTAG tag.
value The unsigned integer.
  public final void
  {
    if (value >= 0)
      writeUnsignedDecimalIntDTagElement(tagvalue);
  }
  public final void
  {
    // First encode the big endian backwards, then reverseBufferAndInsertHeader will reverse it.
    int startPosition = .position();
    // A Java long is 64 bits and can hold the bits of a 64 bit double.
    long int64 = (long)Math.round(Math.abs(value));
    while (int64 != 0) {
      .ensuredPut((byte)(int64 & 0xff));
      int64 >>= 8;
    }
  }

  
Write an element start header using DTAG with the tag to the output buffer, then the absolute value of milliseconds as a big endian BLOB converted to 4096 ticks per second, then an element close. (If you want to just write the integer, use writeUnsignedDecimalInt.)

Parameters:
tag The DTAG tag.
milliseconds The the number of milliseconds.
  public final void
  writeTimeMillisecondsDTagElement(int tagdouble milliseconds)
  {
    writeAbsDoubleBigEndianBlob((milliseconds / 1000.0) * 4096.0);
  }

  
If milliseconds is negative then do nothing, otherwise call writeTimeMillisecondsDTagElement.

Parameters:
tag The DTAG tag.
milliseconds The the number of milliseconds.
  public final void
  writeOptionalTimeMillisecondsDTagElement(int tagdouble milliseconds)
  {
    if (milliseconds >= 0)
      writeTimeMillisecondsDTagElement(tagmilliseconds);
  }

  
Encode a header with the type and value and write it to the output buffer.

Parameters:
type The the header type.
value The header value.
  private void
  encodeTypeAndValue(int typeint value)
  {
    if (type > .)
      // This should not happen since this is a private method and we use types from BinaryXml.
      throw new Error("Header type is out of range");
    // Encode backwards. Calculate how many bytes we need.
    int nEncodingBytes = getNHeaderEncodingBytes(value);
    .ensureRemainingCapacity(nEncodingBytes);
    // Bottom 4 bits of the value go in the last byte with the tag.
      (.position() + nEncodingBytes - 1,
       (byte)((. & type | ((. & value) << .)) |
              .)); // set top bit for last byte
    value >>= .;
    // The rest of the value goes into the preceding bytes, 7 bits per byte. (Zero top bit is the "more" flag.)
    int i = .position() + nEncodingBytes - 2;
    while (value != 0 && i >= .position()) {
      .buffer().put(i, (byte)(value & .));
      value >>= .;
      --i;
    }
    if (value != 0)
      // This should not happen if getNHeaderEncodingBytes is correct.
      throw new Error("EncodeTypeAndValue miscalculated N encoding bytes");
    .position(.position() + nEncodingBytes);
  }

  
Call output_.ensureRemainingCapacity to ensure that there is enough room in the output, and copy buffer from its position() to limit() to the output buffer. This does NOT change buffer.position(). This does not write a header.

Parameters:
buffer The ByteBuffer to write.
  private void
  {
    .ensuredPut(bufferbuffer.position(), buffer.limit());
  }

  
Return the number of bytes to encode a header of value x.
  private static int
  {
    // Do a quick check for pre-compiled results.
    if (x <= )
      return 1;
    if (x <= )
      return 2;
    if (x <= )
      return 3;
    int nBytes = 1;
    // Last byte gives you TT_VALUE_BITS.
    // Remainder each gives you REGULAR_VALUE_BITS.
    x >>= .;
    while (x != 0) {
      ++nBytes;
      x >>= .;
    }
    return nBytes;
  }

  
Reverse length bytes in the buffer starting at startPosition.
  private static void
  reverse(ByteBuffer bufferint startPositionint length)
  {
    if (length == 0)
      return;
    int left = startPosition;
    int right = startPosition + length - 1;
    while (left < right) {
      // Swap.
      byte temp = buffer.get(left);
      buffer.put(leftbuffer.get(right));
      buffer.put(righttemp);
      ++left;
      --right;
    }
  }

  
Write x as an unsigned decimal integer to the output with the digits in reverse order, using output_ensureCapacity. This does not write a header. We encode in reverse order because this is the natural way to encode the digits, and the caller can reverse as needed.

Parameters:
x The unsigned integer to write.
  private void
  {
    if (x < 0)
      // Don't expect this to happen.
      x = 0;
    while (true) {
      .ensuredPut((byte)(x % 10 + '0'));
      x /= 10;
      if (x == 0)
        break;
    }
  }

  
Reverse the buffer in output_buffer() from startPosition to the current position, then shift it right by the amount needed to prefix a header with type, then encode the header at startPosition. We reverse and shift in the same function to avoid unnecessary copying if we first reverse then shift.

Parameters:
startPosition The position in output_buffer() of the start of the buffer to shift right.
type The header type.
  private void
  reverseBufferAndInsertHeader(int startPositionint type)
  {
    int nBufferBytes = .position() - startPosition;
    int nHeaderBytes = getNHeaderEncodingBytes(nBufferBytes);
    .ensureRemainingCapacity(nHeaderBytes);
    // To reverse and shift at the same time, we first shift nHeaderBytes to the destination while reversing,
    //   then reverse the remaining bytes in place.
    int from = startPosition;
    int fromEnd = from + nHeaderBytes;
    int to = startPosition + nBufferBytes + nHeaderBytes - 1;
    while (from < fromEnd) {
      .buffer().put(to.buffer().get(from));
      --to;
      ++from;
    }
    // Reverse the remaining bytes in place (if any).
    if (nBufferBytes > nHeaderBytes)
      reverse(.buffer(), startPosition + nHeaderBytesnBufferBytes - nHeaderBytes);
    // Override the offset to force encodeTypeAndValue to encode at startOffset, then fix the offset.
    .position(startPosition);
    encodeTypeAndValue(typenBufferBytes);
    .position(startPosition + nHeaderBytes + nBufferBytes);
  }
  private final DynamicByteBuffer output_;
New to GrepCode? Check out our FAQ X