/* * (c) Copyright 2009 Talis Information Ltd. * All rights reserved. * [See end of file] */ package migrate.lib; import java.nio.ByteBuffer ; import java.util.Arrays ; import org.openjena.atlas.lib.NotImplemented ; /** ZigZag integers: map signed numbers onto unsigned numbers * that can then be @plainlink{VarInteger} encoded. */ public final class ZigZagInteger { /* http://code.google.com/apis/protocolbuffers/docs/encoding.html 0 => 0 -1 => 1 1 => 2 etc which is (32 bit) (n << 1) ^ (n >> 31) The >> is arthimetic shift n>>32 is zero for n >= 0 n>>32 is all ones for n < 0 */ public static byte[] encode(long value) { // TODO //return null ; throw new NotImplemented("ZigZagInteger.encode") ; } public static int encode(ByteBuffer bytes, long value) { return -1 ; } public static int encode(ByteBuffer bytes, int startIdx, long value) { return -1 ; } public static long decode(byte[] bytes, int idx) { return decode(ByteBuffer.wrap(bytes), idx) ; } public static long decode(ByteBuffer bytes) { return decode(bytes, 0) ; } public static long decode(ByteBuffer bytes, int idx) { return -1 ; } /** Make a VarInteger from the bytes found start from idx */ public static ZigZagInteger make(byte[] bytes) { return new ZigZagInteger(bytes) ; } private static String toString(byte[] bytes) { return toString(bytes, 0) ; } private static String toString(byte[] bytes, int idx) { return null ; } public static boolean equals(long value, byte[] bytes) { return equals(value, ByteBuffer.wrap(bytes)) ; } public static boolean equals(long value, ByteBuffer bytes) { return equals(value, bytes, 0) ; } public static boolean equals(long value, ByteBuffer bytes, int idx) { long x = decode(bytes, idx) ; return x == value ; } // ---- Factory // -- Some constants public static ZigZagInteger zigzag_0 = new ZigZagInteger(0) ; public static ZigZagInteger zigzag_1 = new ZigZagInteger(1) ; public static ZigZagInteger zigzag_2 = new ZigZagInteger(2) ; public static ZigZagInteger zigzag_minus_1 = new ZigZagInteger(-1) ; /** Return a ZigZagInteger that encodes the value */ public static ZigZagInteger valueOf(long value) { if ( value == 0 ) return zigzag_0 ; if ( value == 1 ) return zigzag_1 ; if ( value == -1 ) return zigzag_minus_1 ; if ( value == 2 ) return zigzag_2 ; return new ZigZagInteger(value) ; } public static int lengthOf(long value) { return calcLengthTable(value) ; } // ---- The object byte[] bytes ; long value = -1 ; private ZigZagInteger(long value) { if ( value < 0 ) throw new IllegalArgumentException("Positive integers only") ; bytes = encode(value) ; } private ZigZagInteger(byte[] bytes) { if ( bytes.length == 0 ) throw new IllegalArgumentException("Zero length byte[]") ; this.bytes = bytes ; } public int length() { return bytes.length ; } public byte[] bytes() { return bytes ; } public long value() { if ( value == -1 ) value = decode(bytes, 0) ; return value ; } @Override public int hashCode() { return Arrays.hashCode(bytes) ; } @Override public boolean equals(Object other) { if ( ! ( other instanceof ZigZagInteger ) ) return false ; ZigZagInteger vint = (ZigZagInteger)other ; return Arrays.equals(bytes, vint.bytes) ; } @Override public String toString() { return toString(bytes) ; } // Next is the impossible (it's the sign bit) 1L<<63 static final long VarIntLengths[] = { 1L<<7 , 1L<<14 , 1L<<21 , 1L<<28 , 1L<<35, 1L<<42, 1L<<49, 1L<<56 } ; // By semi-lookup. private static int calcLengthTable(long value) { // Convert to VarInteger value = (value << 1) ^ (value >> 63) ; return VarInteger.calcLengthTable(value) ; } // // By calculation. // private static int calcLength(long value) // { // int len = 1 ; // The byte with high bit zero. // long N = value ; // byte b = 0 ; // while (true) // { // N >>>= 7 ; // if ( N == 0 ) // break ; // len ++ ; // } // return len ; // } } /* * (c) Copyright 2009 Talis Information Ltd. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */