Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.storemate.store.util;
  
Reverse of BytesToStuff, used for encoding data
  
  public abstract class StuffToBytes
 {
     /*
     /**********************************************************************
     /* Shared constants
     /**********************************************************************
      */
 
     public final static int MAX_VLONG_LENGTH = 9;
     public final static int MAX_VINT_LENGTH = 5;

    
First data section is exactly 16 bytes long and fixed (see [https://github.com/cowtowncoder/StoreMate/wiki/BDBDataFormat])
 
     public final static int BASE_LENGTH = 16;

    
Zero-length can be expressed as a single byte, but due to variable-lengthness it won't be plain 0, so let's define constant to use.
 
     public final static byte ZERO_LENGTH_AS_BYTE = (byte) 0x80;
     
     /*
     /**********************************************************************
     /* Shared state
     /**********************************************************************
      */
     
     protected int _ptr;
     
     /*
     /**********************************************************************
     /* Life-cycle
     /**********************************************************************
      */
 
     protected StuffToBytes() { }

    
Factory method for constructing actual "writer" instance; something used for building serializations of data.
 
     public static StuffToBytes writer(int maxLen) {
         return new Writer(maxLen);
     }

    
Factory method for building "estimator", thing that just counts upper bound of bytes that would be produced, without actually doing any encoding or copying.
 
     public static StuffToBytes estimator() {
         return new Estimator();
     }
 
     /*
     /**********************************************************************
     /* API
     /**********************************************************************
      */
 
     public final int offset() {
         return ;
     }
     
     public abstract StuffToBytes appendByte(byte b);
     public abstract StuffToBytes appendInt(int i);
     public abstract StuffToBytes appendLong(long l);
 
     public abstract StuffToBytes appendVInt(int i);
     public abstract StuffToBytes appendVLong(long l);
     
     public final StuffToBytes appendBytes(byte[] data) {
         return appendBytes(data, 0, data.length);
     }
     
     public abstract StuffToBytes appendBytes(byte[] dataint offsetint length);
     
     public abstract <T> T withResult(WithBytesCallback<T> cb);
 
     public abstract StuffToBytes appendLengthAndBytes(ByteContainer bytes);

    
Method for constructing actual serialization with appended data. Will only work for writer, not estimate.
 
     public abstract ByteContainer bufferedBytes();
     
     /*
    /**********************************************************************
    /* Implementations
    /**********************************************************************
     */
    protected static class Writer extends StuffToBytes
        implements WithBytesCallback<StuffToBytes>
    {
        
Buffer in which to append stuff (for real writers); if null, used in "byte counting" mode
        protected final byte[] _buffer;
        protected final int _end;
 
        protected Writer(int maxLen)
        {
            /* one safety measure: to allow for simpler appending of
             * VLongs and VInts, reserve bit of extra space.
             */
            maxLen += ;
             = new byte[maxLen];
             = maxLen;
        }
        
        @Override
        public <T> T withResult(WithBytesCallback<T> cb) {
            return cb.withBytes(,  0, );
        }
        /*
        /**********************************************************************
        /* API
        /**********************************************************************
         */
        @Override
        public ByteContainer bufferedBytes() {
            return ByteContainer.simple(, 0, );
        }
        @Override
        public StuffToBytes appendByte(byte b)
        {
            if ( >= ) {
                _reportBounds(1);
            }
            [++] = b;
            return this;
        }
        @Override
        public StuffToBytes appendLong(long l)
        {
            _verifyBounds(8);
            _appendInt((int) (l >>> 32));
            _appendInt((intl);
            return this;
        }
        @Override
        public StuffToBytes appendInt(int i)
        {
            _verifyBounds(4);
            _appendInt(i);
            return this;
        }
        @Override
        public StuffToBytes appendVInt(int value)
        {
            if (value < 0) throw new IllegalArgumentException();
            // minor optimization for trivial case of single byte
            if (value <= 0x7F) {
                [++] = (byte) (value | 0x80);
                return this;
            }
            // otherwise, count length first
            final int start = ;
            int end = start;
            int tmp = (value >>> 7);
            while (tmp > 0) {
                tmp >>>= 7;
                ++end;
            }
             = end+1;
            // and then write out
            [end] = (byte) ((value & 0x7F) | 0x80);
            do {
                value >>>= 7;
                [--end] = (byte) (value & 0x7F);
            } while (end > start);
            return this;
        }
        @Override
        public StuffToBytes appendVLong(long value)
        {
            if (value < 0L) {
                throw new IllegalArgumentException("Can not encode negative values, got: "+value);
            }
            if (value < .) {
                return appendVInt((intvalue);
            }
            // so we know it's at least 5 bytes long... count exact length
            final int start = ;
            int end = start+4;
            // and can downgrade to ints for counting rest of byte length
            int tmp = (int) (value >>> 35);
            while (tmp > 0) {
                tmp >>>= 7;
                ++end;
            }
             = end+1;
            // and then write out from end to beginning
            [end] = (byte) ((value & 0x7F) | 0x80);
            do {
                value >>>= 7;
                [--end] = (byte) (value & 0x7F);
            } while (end > start);
            return this;
        }
        @Override
        public StuffToBytes appendBytes(byte[] dataint offsetint length) {
            _verifyBounds(length);
            System.arraycopy(dataoffsetlength);
             += length;
            return this;
        }
        
        @Override
        public StuffToBytes appendLengthAndBytes(ByteContainer bytes)
        {
            if (bytes == null) { // nothing to add is same as byte[0] for us, so:
                appendVInt(0);
                return this;
            }
            appendVInt(bytes.byteLength());
            bytes.withBytes(this);
            return this;
        }
        @Override
        public StuffToBytes withBytes(byte[] bufferint offsetint length) {
            return appendBytes(bufferoffsetlength);
        }
        
        /*
        /**********************************************************************
        /* Internal methods
        /**********************************************************************
         */
        protected void _appendInt(int i)
        {
            int ptr = ;
            final byte[] buf = ;
            
            buf[ptr++] = (byte) (i >> 24);
            buf[ptr++] = (byte) (i >> 16);
            buf[ptr++] = (byte) (i >> 8);
            buf[ptr++] = (bytei;
            
             = ptr;
        }
        
        protected void _verifyBounds(int bytesNeeded)
        {
            if (( + bytesNeeded) > ) {
                _reportBounds(bytesNeeded);
            }
        }
        
        protected void _reportBounds(int bytesNeeded)
        {
            int left =  - ;
            throw new IllegalStateException("Buffer overrun: need "+bytesNeeded
                    +"; only have "+left+" (offset "++")");
        }
    }

    
Implementation that merely counts size that would be taken if content was written.
    protected static class Estimator extends StuffToBytes
    {
        protected Estimator() { }
        @Override
        public <T> T withResult(WithBytesCallback<T> cb) {
            throw new UnsupportedOperationException();
        }
        @Override
        public ByteContainer bufferedBytes() {
            throw new UnsupportedOperationException();
        }
        
        @Override
        public StuffToBytes appendByte(byte b) {
            ++;
            return this;
        }
        @Override
        public StuffToBytes appendLong(long l) {
             += 8;
            return this;
        }
        @Override
        public StuffToBytes appendInt(int i)
        {
             += 4;
            return this;
        }
        @Override
        public StuffToBytes appendVInt(int i)
        {
            if (i <= 0x7F) {
                ++;
                return this;
            }
            do {
                i >>>= 7;
                ++;
            } while (i != 0);
            return this;
        }
        @Override
        public StuffToBytes appendVLong(long l)
        {
            if (l < .) {
                return appendVInt((intl);
            }
             += 5;
            int rem = (int) (l >>> 35);
            while (rem > 0) {
                rem >>>= 7;
                ++;
            }
            return this;
        }
        
        @Override
        public StuffToBytes appendBytes(byte[] dataint offsetint length) {
             += length;
            return this;
        }
        
        @Override
        public StuffToBytes appendLengthAndBytes(ByteContainer bytes)
        {
            if (bytes == null) {
                ++;
            } else {
                int len = bytes.byteLength();
                appendVInt(len);
                 += len;
            }
            return this;
        }
    }
New to GrepCode? Check out our FAQ X