Creates a new big-endian buffer whose content is the specified
{@code array} encoded in the specified {@code charset}.
The new buffer's {@code readerIndex} and {@code writerIndex} are
{@code 0} and the length of the encoded string respectively.
170314
public static ByteBuf copiedBuffer(char[] array, Charset charset) {
        if (array == null) {
            throw new NullPointerException("array");
        }
        return copiedBuffer(array, 0, array.length, charset);
    }
130518
public static byte[] readBytes(ByteBuffer buffer, int start, int end) {
		byte[] bs = new byte[end - start];
		System.arraycopy(buffer.array(), start, bs, 0, bs.length);
		return bs;
	}
31381
public CharBuffer subSequence(int start, int end) {
        int pos = position();
        int lim = limit();
        assert (pos <= lim);
        pos = (pos <= lim ? pos : lim);
        int len = lim - pos;

        if ((start < 0) || (end > len) || (start > end))
            throw new IndexOutOfBoundsException();
        return new ByteBufferAsCharBuffer(bb,
                -1,
                pos + start,
                pos + end,
                capacity(),
                offset,
                order);
    }
830429
public JBBPTextWriter Byte(final byte[] array, int off, int len) throws IOException {
    ensureValueMode();
    while (len-- > 0) {
      Byte(array[off++]);
    }

    return this;
  }
539954
public static long readLongLittleEndian(byte[] buffer, int offset) {
		long value;
		value = (buffer[offset] & 0xFF);
		value |= (buffer[offset + 1] & 0xFF) << 8;
		value |= (buffer[offset + 2] & 0xFF) << 16;
		value |= ((long)(buffer[offset + 3] & 0xFF)) << 24;
		value |= ((long)(buffer[offset + 4] & 0xFF)) << 32;
		value |= ((long)(buffer[offset + 5] & 0xFF)) << 40;
		value |= ((long)(buffer[offset + 6] & 0xFF)) << 48;
		value |= ((long)(buffer[offset + 7] & 0xFF)) << 56;
		return value;
	}
506742
@Override
    public int decode ( byte[] buffer, int bufferIndex, int len ) throws SMBProtocolDecodingException {
        int start = bufferIndex;
        this.createTime = SMBUtil.readTime(buffer, bufferIndex);
        bufferIndex += 8;
        this.lastAccessTime = SMBUtil.readTime(buffer, bufferIndex);
        bufferIndex += 8;
        this.lastWriteTime = SMBUtil.readTime(buffer, bufferIndex);
        bufferIndex += 8;
        this.changeTime = SMBUtil.readTime(buffer, bufferIndex);
        bufferIndex += 8;
        this.attributes = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;
        return bufferIndex - start;
    }
82375
public byte[] readVarArray() throws IOException {
    int len = (int) readVarLong();
    byte[] result = new byte[len];
    in.read(result);
    return result;
  }
933726
protected void bufferize(byte b) {
        if (index == buffer.length) {
            byte[] newBuffer = new byte[buffer.length * 2];
            System.arraycopy(buffer, 0, newBuffer, 0, index);
            buffer = newBuffer;
        }
        buffer[index++] = b;
    }
396032
public static String getString(ByteBuffer buf, int offset, int length, Charset encoding) {
        buf = buf.duplicate();
        buf.position(buf.position() + offset);
        if (buf.hasArray()) {
            return new String(buf.array(), buf.arrayOffset() + buf.position(), length, encoding);
        } else {
            byte[] bytes = new byte[length];
            buf.get(bytes);
            return new String(bytes, encoding);
        }
    }
1298329
@Override
    public int decode ( byte[] buffer, int bufferIndex, int len ) throws SMBProtocolDecodingException {
        int start = bufferIndex;
        this.chunksWritten = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;
        this.chunkBytesWritten = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;
        this.totalBytesWritten = SMBUtil.readInt4(buffer, bufferIndex);
        bufferIndex += 4;
        return bufferIndex - start;
    }
787477
public static void encode (char[] string, int offset, int length, boolean encodeNewline, Writer writer)
        throws IOException
    {
        encode(string, offset, length, encodeNewline, true, writer);
    }
1148747
public static void writeLongLittleEndian(byte[] buffer, int offset, long value) {
		buffer[offset++] = (byte)(value & 0xFF);
		buffer[offset++] = (byte)((value >> 8) & 0xFF);
		buffer[offset++] = (byte)((value >> 16) & 0xFF);
		buffer[offset++] = (byte)((value >> 24) & 0xFF);
		buffer[offset++] = (byte)((value >> 32) & 0xFF);
		buffer[offset++] = (byte)((value >> 40) & 0xFF);
		buffer[offset++] = (byte)((value >> 48) & 0xFF);
		buffer[offset] = (byte)((value >> 56) & 0xFF);
	}
1253533
public static LinkedBuffer encode(final byte[] input, int inOffset, int inLen,
            final WriteSession session, final LinkedBuffer lb) throws IOException
    {
        int outputSize = ((inLen + 2) / 3) * 4;
        session.size += outputSize;

        final int available = lb.buffer.length - lb.offset;
        if (outputSize > available)
        {
            int chunks = available / 4;
            if (chunks == 0)
            {
                // available size is less than 4
                if (outputSize > session.nextBufferSize)
                {
                    final byte[] encoded = new byte[outputSize];
                    encode(input, inOffset, inLen, encoded, 0);
                    // return a fresh buffer.
                    return new LinkedBuffer(session.nextBufferSize,
                            new LinkedBuffer(encoded, 0, outputSize, lb));
                }

                final byte[] encoded = new byte[session.nextBufferSize];
                encode(input, inOffset, inLen, encoded, 0);
                // continue with the existing byte array of the previous buffer
                return new LinkedBuffer(encoded, 0, outputSize, lb);
            }

            int inBefore = inOffset;
            final byte[] buffer = lb.buffer;
            int offset = lb.offset;
            byte b0, b1, b2;

            // process available
            while (chunks-- > 0)
            {
                b0 = input[inOffset++];
                b1 = input[inOffset++];
                b2 = input[inOffset++];
                buffer[offset++] = nibble2code[(b0 >>> 2) & 0x3f];
                buffer[offset++] = nibble2code[(b0 << 4) & 0x3f | (b1 >>> 4) & 0x0f];
                buffer[offset++] = nibble2code[(b1 << 2) & 0x3f | (b2 >>> 6) & 0x03];
                buffer[offset++] = nibble2code[b2 & 077];
            }

            inLen -= (inOffset - inBefore);

            outputSize -= (offset - lb.offset);

            lb.offset = offset;

            if (outputSize > session.nextBufferSize)
            {
                final byte[] encoded = new byte[outputSize];
                encode(input, inOffset, inLen, encoded, 0);
                // return a fresh buffer.
                return new LinkedBuffer(session.nextBufferSize,
                        new LinkedBuffer(encoded, 0, outputSize, lb));
            }

            final byte[] encoded = new byte[session.nextBufferSize];
            encode(input, inOffset, inLen, encoded, 0);
            // continue with the existing byte array of the previous buffer
            return new LinkedBuffer(encoded, 0, outputSize, lb);
        }

        encode(input, inOffset, inLen, lb.buffer, lb.offset);
        lb.offset += outputSize;

        return lb;
    }
1036510
public final byte[] encode(byte[] source, int off, int len) {		
		int	len43 = len * 4 / 3;
		byte[] outBuff = new byte[ ( len43 )					  // main 4:3
								   + ( (len % 3) > 0 ? 4 : 0 ) ]; // account for padding
		int d = 0;
		int e = 0;
		int len2 = len - 2;
		int lineLength = 0;
		for (; d < len2; d+=3, e+=4) {
			encode3to4(source, d+off, 3, outBuff, e);

			lineLength += 4;
		} // end for: each piece of array

		if (d < len) {
			encode3to4(source, d+off, len - d, outBuff, e);
			e += 4;
		} // end if: some padding needed
		
		byte[] out = new byte[e];
		System.arraycopy(outBuff, 0, out, 0, e); 
		return out;
	}
139795
public static byte[] fromHexByteArray(final byte[] buffer)
    {
        final byte[] outputBuffer = new byte[buffer.length >> 1];

        for (int i = 0; i < buffer.length; i += 2)
        {
            final int hi = FROM_HEX_DIGIT_TABLE[buffer[i]] << 4;
            final int lo = FROM_HEX_DIGIT_TABLE[buffer[i + 1]]; // lgtm [java/index-out-of-bounds]
            outputBuffer[i >> 1] = (byte)(hi | lo);
        }

        return outputBuffer;
    }
273558
public static LinkedBuffer encode(final byte[] input, int inOffset, int inLen,
            final WriteSession session, final OutputStream out, 
            final LinkedBuffer lb) throws IOException
    {
        int outputSize = ((inLen+2)/3)*4;
        session.size += outputSize;
        
        final int available = lb.buffer.length - lb.offset;
        if(outputSize > available)
        {
            final int bufSize = lb.buffer.length - lb.start;
            if(outputSize > bufSize)
            {
                // still larger than buffer size.
                int chunks = available/4;
                if(chunks == 0)
                {
                    // available size is less than 4
                    // flush and reset
                    out.write(lb.buffer, lb.start, lb.offset-lb.start);
                    lb.offset = lb.start;
                    
                    final int loops = bufSize/4, inProcessLen = loops*3, outProcessLen = loops*4;
                    do
                    {
                        inOffset = encodeExplicit(input, inOffset, 0, lb.buffer, 
                                lb.offset, loops);
                        
                        out.write(lb.buffer, lb.offset, outProcessLen);
                        inLen -= inProcessLen;
                        outputSize -= outProcessLen;
                    }
                    while(inLen > inProcessLen);
                    
                    // write remaining
                    encode(input, inOffset, inLen, lb.buffer, lb.offset);
                    lb.offset += outputSize;
                    
                    return lb;
                }
                
                int inBefore = inOffset;
                byte[] buffer = lb.buffer;
                int offset = lb.offset;
                byte b0, b1, b2;
                
                // process available
                while(chunks-->0)
                {
                    b0=input[inOffset++];
                    b1=input[inOffset++];
                    b2=input[inOffset++];
                    buffer[offset++]=nibble2code[(b0>>>2)&0x3f];
                    buffer[offset++]=nibble2code[(b0<<4)&0x3f|(b1>>>4)&0x0f];
                    buffer[offset++]=nibble2code[(b1<<2)&0x3f|(b2>>>6)&0x03];
                    buffer[offset++]=nibble2code[b2&077];
                }
                
                inLen -= (inOffset - inBefore);
                
                outputSize -= (offset - lb.offset);
                
                // flush available
                out.write(buffer, lb.start, offset-lb.start);
                // reset
                lb.offset = lb.start;
                
                if(outputSize > bufSize)
                {
                    // still larger than buffer size.
                    final int loops = bufSize/4, inProcessLen = loops*3, outProcessLen = loops*4;
                    do
                    {
                        inOffset = encodeExplicit(input, inOffset, 0, lb.buffer, 
                                lb.offset, loops);
                        
                        out.write(lb.buffer, lb.offset, outProcessLen);
                        inLen -= inProcessLen;
                        outputSize -= outProcessLen;
                    }
                    while(inLen > inProcessLen);
                    
                    // write remaining
                    encode(input, inOffset, inLen, lb.buffer, lb.offset);
                    lb.offset += outputSize;
                    
                    return lb;
                }
                
                encode(input, inOffset, inLen, lb.buffer, lb.offset);
                lb.offset += outputSize;

                return lb;
            }
            
            // flush and reset
            out.write(lb.buffer, lb.start, lb.offset-lb.start);
            lb.offset = lb.start;
        }
        
        encode(input, inOffset, inLen, lb.buffer, lb.offset);
        lb.offset += outputSize;

        return lb;
    }
242845
@Override
	public void writeBytes(String s)
    {
    	int len = s.length();
    	ensureCapacity(size+len);
    	for (int i = 0 ; i < len ; i++)
    	    buf[pos++] = (byte)s.charAt(i);
    }
    
	/* (non-Javadoc)
	 * @see java.io.DataOutput#writeChars(java.lang.String)
	 */
	@Override
	public void writeChars(String s)
	{
		int len = s.length();
		ensureCapacity(size+len*2);
        for (int i = 0 ; i < len ; i++) {
            int v = s.charAt(i);
            buf[pos++] = (byte)((v >>> 8) & 0xFF); 
            buf[pos++] = (byte)((v >>> 0) & 0xFF); 
        }
	}
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#write(byte[], int, int)
     */
    @Override
	public void write(byte[] data,int offset,int len)
    {
        int newCount = size+len; 
        ensureCapacity(newCount);
        System.arraycopy(data, offset, buf, size, len);
        size = newCount;
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeByte(int)
     */
    @Override
	public void writeByte(int b)
    {
        ensureCapacity(size+1);
        buf[size++] = (byte)b;
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeBoolean(boolean)
     */
    @Override
	public void writeBoolean(boolean v)
    {
        write(v ? 1 : 0);
    }
    
    /**
     * Read a byte value at an arbitrary position in the buffer
     * @param position the target position
     */
    public byte readByte(int position)
    {
    	return buf[position];
    }
    
    /**
     * Write a byte value at an arbitrary position in the buffer
     * @param v the byte value
     * @param position the target position
     */
    public void writeByte(byte v,int position)
    {
    	buf[position] = v;
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeShort(int)
     */
    @Override
	public void writeShort(int v)
    {
        ensureCapacity(size + 2);
        buf[size++] = (byte)((v >>>  8) & 0xFF);
        buf[size++] = (byte)((v >>>  0) & 0xFF);
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeInt(int)
     */
    @Override
	public void writeInt(int v)
    {
        ensureCapacity(size + 4);
        buf[size++] = (byte)((v >>> 24) & 0xFF);
        buf[size++] = (byte)((v >>> 16) & 0xFF);
        buf[size++] = (byte)((v >>>  8) & 0xFF);
        buf[size++] = (byte)((v >>>  0) & 0xFF);
    }
    
    /**
     * Write a int value at an arbitrary position in the stream
     * @param v the int value
     * @param pos the target position
     */
    public void writeInt(int v,int pos)
    {
        buf[pos++] = (byte)((v >>> 24) & 0xFF);
        buf[pos++] = (byte)((v >>> 16) & 0xFF);
        buf[pos++] = (byte)((v >>>  8) & 0xFF);
        buf[pos]   = (byte)((v >>>  0) & 0xFF);
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeLong(long)
     */
    @Override
	public void writeLong(long v)
    {
        ensureCapacity(size + 8);
        buf[size++] = (byte)(v >>> 56);
        buf[size++] = (byte)(v >>> 48);
        buf[size++] = (byte)(v >>> 40);
        buf[size++] = (byte)(v >>> 32);
        buf[size++] = (byte)(v >>> 24);
        buf[size++] = (byte)(v >>> 16);
        buf[size++] = (byte)(v >>>  8);
        buf[size++] = (byte)(v >>>  0);
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeFloat(float)
     */
    @Override
	public void writeFloat(float v)
    {
        writeInt(Float.floatToIntBits(v));
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeDouble(double)
     */
    @Override
	public void writeDouble(double v)
    {
        writeLong(Double.doubleToLongBits(v));
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeChar(int)
     */
    @Override
	public void writeChar(int v)
    {
        ensureCapacity(size + 2);
        buf[size++] = (byte)((v >>>  8) & 0xFF);
        buf[size++] = (byte)((v >>>  0) & 0xFF);
    }
    
    /*
     * (non-Javadoc)
     * @see java.io.DataOutput#writeUTF(java.lang.String)
     */
    @Override
	public void writeUTF(String str)
    {
        int strlen = str.length();
        if (strlen < 255)
            writeUTF(str,UTF_TYPE_1);
        else
        if (strlen < 65535)
            writeUTF(str,UTF_TYPE_2);
        else
            writeUTF(str,UTF_TYPE_4);
    }
    
    private void writeUTF( String str , byte type )
    {       
        // We need at least type + strlen bytes (1 byte/char) + 1
        int strlen = str.length();
        int rawlen = size+type+strlen+1;
        ensureCapacity(rawlen);
        
        // Write UTF type prefix
        buf[size++] = type;
        
        // Write the string length
        switch (type)
        {
            case UTF_TYPE_1 :
                buf[size++] = (byte)((strlen >>>  0) & 0xFF);
                break;
            case UTF_TYPE_2 :
                buf[size++] = (byte)((strlen >>>  8) & 0xFF);
                buf[size++] = (byte)((strlen >>>  0) & 0xFF);
                break;
            case UTF_TYPE_4 :
                buf[size++] = (byte)((strlen >>> 24) & 0xFF);
                buf[size++] = (byte)((strlen >>> 16) & 0xFF);
                buf[size++] = (byte)((strlen >>>  8) & 0xFF);
                buf[size++] = (byte)((strlen >>>  0) & 0xFF);
                break;
            default:
            	throw new IllegalArgumentException("Invalid UTF type : "+type);   
        }

        // Write the string
        int c,i = 0;
        for (i = 0 ; i < strlen ; i++)
        {
            c = str.charAt(i);
            if (!((c >= 0x0001) && (c <= 0x007F)))
                break;
            buf[size++] = (byte)c;
        }
        // Are we done ?
        if (i == strlen)
            return;

        // Fallback to full encoding mode
        for ( ; i < strlen ; i++)
        {
            c = str.charAt(i);

            if ((c >= 0x0001) && (c <= 0x007F))
            {
                // One byte
                buf[size++] = (byte)c;
            }
            else if (c > 0x07FF)
            {
                rawlen += 3;
                ensureCapacity(rawlen);
                
                buf[size++] = (byte)(0xE0 | ((c >> 12) & 0x0F));
                buf[size++] = (byte)(0x80 | ((c >> 6) & 0x3F));
                buf[size++] = (byte)(0x80 | ((c >> 0) & 0x3F));
            }
            else
            {
                rawlen += 2;
                ensureCapacity(rawlen);
                
                buf[size++] = (byte)(0xC0 | ((c >> 6) & 0x1F));
                buf[size++] = (byte)(0x80 | ((c >> 0) & 0x3F));
            }
        }
    }