/**
* JEBML - Java library to read/write EBML/Matroska elements.
* Copyright (C) 2004 Jory Stone <jebml@jory.info>
* Based on Javatroska (C) 2002 John Cannon <spyder@matroska.org>
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.jcodec.containers.mkv.ebml;
/*
* SignedInteger.java
*
* Created on February 17, 2003, 1:54 PM
*/
/**
* Basic class for the Signed Integer EBML data type.
*
* @author John Cannon
*/
public class SignedIntegerElement extends BinaryElement {
public SignedIntegerElement(byte[] typeID) {
super(typeID);
}
public void setValue(long value) {
setData(convertToBytes(value));
}
public long getValue() {
if ((data.limit()-data.position()) == 8)
return data.duplicate().getLong();
byte[] b = data.array();
long l = 0;
for (int i = b.length-1; i >=0 ; i--)
l |= (b[i] & 0xFFL) << (8*(b.length-1-i));
return l;
}
/**
* TODO: This should be replaces with a straight-forward calculation
*
* @param val
* @return
*/
public static int getSerializedSize(long val) {
if (val <= 0x40 && val >= (-0x3F)) {
return 1;
} else if (val <= 0x2000 && val >= (-0x1FFF)) {
return 2;
} else if (val <= 0x100000 && val >= (-0x0FFFFF)) {
return 3;
} else if (val <= 0x8000000 && val >= (-0x07FFFFFF)) {
return 4;
} else if (val <= 0x400000000L && val >= -0x03FFFFFFFFL) {
return 5;
} else if (val <= 0x20000000000L && val >= -0x01FFFFFFFFFFL) {
return 6;
} else if (val <= 0x1000000000000l && val >= -0x00FFFFFFFFFFFFL) {
return 7;
} else {
return 8;
}
}
public static final long[] signedComplement = { 0, 0x3F, 0x1FFF, 0x0FFFFF, 0x07FFFFFF, 0x03FFFFFFFFL, 0x01FFFFFFFFFFL, 0x00FFFFFFFFFFFFL, 0x007FFFFFFFFFFFFFL };
public static long convertToUnsigned(long val) {
return val + signedComplement[getSerializedSize(val)];
}
public static byte[] convertToBytes(long val) {
int num = getSerializedSize(val);
val += signedComplement[num];
// Assert.assertEquals("Int size changed after adding compliment, shouldn't happen.", num, getSerializedSize(val));
return Element.ebmlBytes(val, num);
}
}