Package org.teiid.internal.core.index

Source Code of org.teiid.internal.core.index.CodeByteStream

/*******************************************************************************
* Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     MetaMatrix, Inc - repackaging and updates for use as a metadata store
*******************************************************************************/
package org.teiid.internal.core.index;

import java.io.UTFDataFormatException;

public class CodeByteStream {
  protected byte[] bytes;
  protected int byteOffset= 0;
  protected int bitOffset= 0;
  protected int markByteOffset= -1;
  protected int markBitOffset= -1;

  public CodeByteStream() {
    this(16);
  }
  public CodeByteStream(byte[] bytes) {
    this.bytes= bytes;
  }
  public CodeByteStream(int initialByteLength) {
    bytes= new byte[initialByteLength];
  }
  public int byteLength() {
    return (bitOffset + 7) / 8 + byteOffset;
  }
  public byte[] getBytes(int startOffset, int endOffset) {
    int byteLength= byteLength();
    if (startOffset > byteLength || endOffset > byteLength || startOffset > endOffset)
      throw new IndexOutOfBoundsException();
    int length= endOffset - startOffset;
    byte[] result= new byte[length];
    System.arraycopy(bytes, startOffset, result, 0, length);
    if (endOffset == byteLength && bitOffset != 0) {
      int mask= (1 << bitOffset) - 1;
      result[length - 1] &= (mask << 8 - bitOffset);
    }
    return result;
  }
  protected void grow() {
    byte[] newBytes= new byte[bytes.length * 2 + 1];
    System.arraycopy(bytes, 0, newBytes, 0, bytes.length);
    bytes= newBytes;
  }
  public void mark() {
    markByteOffset= byteOffset;
    markBitOffset= bitOffset;
  }
  /**
   * Reads a single bit (value == 0 or == 1).
   */
  public int readBit() {
    int value= (bytes[byteOffset] >> (7 - bitOffset)) & 1;
    if (++bitOffset >= 8) {
      bitOffset= 0;
      ++byteOffset;
    }
    return value;
  }
  /**
   * Read up to 32 bits from the stream.
   */
  public int readBits(int numBits) {
    int value= 0;
    while (numBits > 0) {
      int bitsToRead= 8 - bitOffset;
      if (bitsToRead > numBits)
        bitsToRead= numBits;
      int mask= (1 << bitsToRead) - 1;
      value |= ((bytes[byteOffset] >> (8 - bitOffset - bitsToRead)) & mask) << (numBits - bitsToRead);
      numBits -= bitsToRead;
      bitOffset += bitsToRead;
      if (bitOffset >= 8) {
        bitOffset -= 8;
        byteOffset += 1;
      }
    }
    return value;
  }
  public final int readByte() {

    // no need to rebuild byte value from bit sequences
    if (bitOffset == 0) return bytes[byteOffset++] & 255;
 
    int value= 0;
    int numBits = 8;
    while (numBits > 0) {
      int bitsToRead= 8 - bitOffset;
      if (bitsToRead > numBits)
        bitsToRead= numBits;
      int mask= (1 << bitsToRead) - 1;
      value |= ((bytes[byteOffset] >> (8 - bitOffset - bitsToRead)) & mask) << (numBits - bitsToRead);
      numBits -= bitsToRead;
      bitOffset += bitsToRead;
      if (bitOffset >= 8) {
        bitOffset -= 8;
        byteOffset += 1;
      }
    }
    return value;
  }
  /**
   * Reads a value using Gamma coding.
   */
  public int readGamma() {
    int numBits= readUnary();
    return readBits(numBits - 1) | (1 << (numBits - 1));
  }
  public char[] readUTF() throws UTFDataFormatException {
    int utflen= readByte();
    if (utflen == 255) {
      // long UTF
      int high = readByte();
      int low = readByte();
      utflen = (high << 8) + low;
    }
    char str[]= new char[utflen];
    int count= 0;
    int strlen= 0;
    while (count < utflen) {
      int c= readByte();
      int char2, char3;
      switch (c >> 4) {
        case 0 :
        case 1 :
        case 2 :
        case 3 :
        case 4 :
        case 5 :
        case 6 :
        case 7 :
          // 0xxxxxxx
          count++;
          str[strlen++]= (char) c;
          break;
        case 12 :
        case 13 :
          // 110x xxxx   10xx xxxx
          count += 2;
          if (count > utflen)
            throw new UTFDataFormatException();
          char2= readByte();
          if ((char2 & 0xC0) != 0x80)
            throw new UTFDataFormatException();
          str[strlen++]= (char) (((c & 0x1F) << 6) | (char2 & 0x3F));
          break;
        case 14 :
          // 1110 xxxx  10xx xxxx  10xx xxxx
          count += 3;
          if (count > utflen)
            throw new UTFDataFormatException();
          char2= readByte();
          char3= readByte();
          if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80))
            throw new UTFDataFormatException();
          str[strlen++]= (char) (((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
          break;
        default :
          // 10xx xxxx,  1111 xxxx
          throw new UTFDataFormatException();
      }
    }
    if (strlen < utflen)
      System.arraycopy(str, 0, str= new char[strlen], 0, strlen);
    return str;
  }
  /**
   *  Reads a value in unary.
   */
  public int readUnary() {
    int value= 1;
    int mask= 1 << (7 - bitOffset);
    while ((bytes[byteOffset] & mask) != 0) {
      ++value;
      if (++bitOffset >= 8) {
        bitOffset= 0;
        ++byteOffset;
        mask= 0x80;
      } else {
        mask >>>= 1;
      }
    }
    // skip the 0 bit
    if (++bitOffset >= 8) {
      bitOffset= 0;
      ++byteOffset;
    }
    return value;
  }
  public void reset() {
    byteOffset= bitOffset= 0;
    markByteOffset= markBitOffset= -1;
  }
  public void reset(byte[] bytes) {
    this.bytes= bytes;
    reset();
  }
  public void reset(byte[] bytes, int byteOffset) {
    reset(bytes);
    this.byteOffset= byteOffset;
  }
  public boolean resetToMark() {
    if (markByteOffset == -1)
      return false;
    byteOffset= markByteOffset;
    bitOffset= markBitOffset;
    markByteOffset= markBitOffset= -1;
    return true;
  }
  public void skipBits(int numBits) {
    int newOffset= byteOffset * 8 + bitOffset + numBits;
    if (newOffset < 0 || (newOffset + 7) / 8 >= bytes.length)
      throw new IllegalArgumentException();
    byteOffset= newOffset / 8;
    bitOffset= newOffset % 8;
  }
  public byte[] toByteArray() {
    return getBytes(0, byteLength());
  }
  /**
   * Writes a single bit (value == 0 or == 1).
   */
  public void writeBit(int value) {
    bytes[byteOffset] |= (value & 1) << (7 - bitOffset);
    if (++bitOffset >= 8) {
      bitOffset= 0;
      if (++byteOffset >= bytes.length)
        grow();
    }
  }
  /**
   * Write up to 32 bits to the stream.
   * The least significant numBits bits of value are written.
   */
  public void writeBits(int value, int numBits) {
    while (numBits > 0) {
      int bitsToWrite= 8 - bitOffset;
      if (bitsToWrite > numBits)
        bitsToWrite= numBits;
      int shift= 8 - bitOffset - bitsToWrite;
      int mask= ((1 << bitsToWrite) - 1) << shift;
      bytes[byteOffset]= (byte) ((bytes[byteOffset] & ~mask) | (((value >>> (numBits - bitsToWrite)) << shift) & mask));
      numBits -= bitsToWrite;
      bitOffset += bitsToWrite;
      if (bitOffset >= 8) {
        bitOffset -= 8;
        if (++byteOffset >= bytes.length)
          grow();
      }
    }
  }
  public void writeByte(int value) {
    writeBits(value, 8);
  }
  /**
   * Writes the given value using Gamma coding, in which positive integer x
   * is represented by coding floor(log2(x) in unary followed by the value
   * of x - 2**floor(log2(x)) in binary.
   * The value must be >= 1.
   */
  public void writeGamma(int value) {
    if (value < 1)
      throw new IllegalArgumentException();
    int temp= value;
    int numBits= 0;
    while (temp != 0) {
      temp >>>= 1;
      ++numBits;
    }
    writeUnary(numBits);
    writeBits(value, numBits - 1);
  }
  public void writeUTF(char[] str, int start, int end) {
    int utflen= 0;
    for (int i= start; i < end; i++) {
      int c= str[i];
      if ((c >= 0x0001) && (c <= 0x007F)) {
        utflen++;
      } else if (c > 0x07FF) {
        utflen += 3;
      } else {
        utflen += 2;
      }
    }
    if (utflen < 255) {
      writeByte(utflen & 0xFF);
    } else if (utflen > 65535) {
      throw new IllegalArgumentException();
    } else {
      writeByte(255); // marker for long UTF
      writeByte((utflen >>> 8) & 0xFF); // high byte
      writeByte((utflen >>> 0) & 0xFF); // low byte
    }
    for (int i= start; i < end; i++) {
      int c= str[i];
      if ((c >= 0x0001) && (c <= 0x007F)) {
        writeByte(c);
      } else if (c > 0x07FF) {
        writeByte(0xE0 | ((c >> 12) & 0x0F));
        writeByte(0x80 | ((c >> 6) & 0x3F));
        writeByte(0x80 | ((c >> 0) & 0x3F));
      } else {
        writeByte(0xC0 | ((c >> 6) & 0x1F));
        writeByte(0x80 | ((c >> 0) & 0x3F));
      }
    }
  }
  /**
   * Write the given value in unary.  The value must be >= 1.
   */
  public void writeUnary(int value) {
    if (value < 1)
      throw new IllegalArgumentException();
    int mask= 1 << (7 - bitOffset);
    // write N-1 1-bits
    while (--value > 0) {
      bytes[byteOffset] |= mask;
      if (++bitOffset >= 8) {
        bitOffset= 0;
        if (++byteOffset >= bytes.length)
          grow();
        mask= 0x80;
      } else {
        mask >>>= 1;
      }
    }
    // write a 0-bit
    bytes[byteOffset] &= ~mask;
    if (++bitOffset >= 8) {
      bitOffset= 0;
      if (++byteOffset >= bytes.length)
        grow();
    }
  }
}
TOP

Related Classes of org.teiid.internal.core.index.CodeByteStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.