/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.unit.extra;
import org.apache.log4j.Logger;
import com.ttProject.unit.extra.bit.Bit1;
import com.ttProject.unit.extra.bit.Bit14;
import com.ttProject.unit.extra.bit.Bit2;
import com.ttProject.unit.extra.bit.Bit21;
import com.ttProject.unit.extra.bit.Bit28;
import com.ttProject.unit.extra.bit.Bit3;
import com.ttProject.unit.extra.bit.Bit35;
import com.ttProject.unit.extra.bit.Bit4;
import com.ttProject.unit.extra.bit.Bit42;
import com.ttProject.unit.extra.bit.Bit49;
import com.ttProject.unit.extra.bit.Bit5;
import com.ttProject.unit.extra.bit.Bit56;
import com.ttProject.unit.extra.bit.Bit6;
import com.ttProject.unit.extra.bit.Bit7;
import com.ttProject.unit.extra.bit.Bit8;
/**
* get the ebml value
* @author taktod
*/
public class EbmlValue extends Bit {
/** logger */
@SuppressWarnings("unused")
private Logger logger = Logger.getLogger(EbmlValue.class);
private byte zeroCount = 0;
private Bit numBit = null;
private Bit dataBit = null;
/**
* constructor
* @param count
*/
public EbmlValue() {
super(0);
numBit = new Bit1(1);
dataBit = new Bit7();
}
@Override
public int getBitCount() {
return numBit.getBitCount() + dataBit.getBitCount();
}
@Override
public int get() {
long data = getLong();
if(data > 0xFFFFFFFFL) {
throw new RuntimeException("use getLong(), not get()");
}
return (int)data;
}
/**
* ref the data
* @return
*/
public long getLong() {
if(dataBit instanceof BitN) {
return ((BitN) dataBit).getLong();
}
else {
return dataBit.get();
}
}
/**
* get the raw ebml value.
* @return
*/
public long getEbmlValue() {
return new BitN(numBit, dataBit).getLong();
}
/**
* set the raw ebml value.
* @param value
*/
public void setEbmlValue(long value) {
if(value >>> 7 == 1) {
numBit = new Bit1(1);
dataBit = new Bit7((int)(value & 0x7F));
}
else if(value >>> 14 == 1) {
numBit = new Bit2(1);
dataBit = new Bit14((int)(value & 0x3FFF));
}
else if(value >>> 21 == 1) {
numBit = new Bit3(1);
dataBit = new Bit21((int)(value & 0x1FFFFF));
}
else if(value >>> 28 == 1) {
numBit = new Bit4(1);
dataBit = new Bit28((int)(value & 0x0FFFFFFF));
}
else if(value >>> 35 == 1) {
numBit = new Bit5(1);
BitN data = new Bit35();
data.setLong(value & 0x07FFFFFFFFL);
dataBit = data;
}
else if(value >>> 42 == 1) {
numBit = new Bit6(1);
BitN data = new Bit42();
data.setLong(value & 0x03FFFFFFFFFFL);
dataBit = data;
}
else if(value >>> 49 == 1) {
numBit = new Bit7(1);
BitN data = new Bit49();
data.setLong(value & 0x01FFFFFFFFFFFFL);
dataBit = data;
}
else if(value >>> 56 == 1) {
numBit = new Bit8(1);
BitN data = new Bit56();
data.setLong(value & 0x00FFFFFFFFFFFFFFL);
dataBit = data;
}
}
/**
* {@inheritDoc}
*/
@Override
public void set(int value) {
if(value >>> 7 == 0) {
numBit = new Bit1(1);
dataBit = new Bit7(value);
}
else if(value >>> 14 == 0) {
numBit = new Bit2(1);
dataBit = new Bit14(value);
}
else if(value >>> 21 == 0) {
numBit = new Bit3(1);
dataBit = new Bit21(value);
}
else if(value >>> 28 == 0) {
numBit = new Bit4(1);
dataBit = new Bit28(value);
}
else {
numBit = new Bit5(1);
dataBit = new Bit35(value);
}
}
public void setLong(long value) {
if(value >>> 7 == 0) {
numBit = new Bit1(1);
dataBit = new Bit7((int)value);
}
else if(value >>> 14 == 0) {
numBit = new Bit2(1);
dataBit = new Bit14((int)value);
}
else if(value >>> 21 == 0) {
numBit = new Bit3(1);
dataBit = new Bit21((int)value);
}
else if(value >>> 28 == 0) {
numBit = new Bit4(1);
dataBit = new Bit28((int)value);
}
else if(value >>> 35 == 0) {
numBit = new Bit5(1);
BitN data = new Bit35();
data.setLong(value);
dataBit = data;
}
else if(value >>> 42 == 0) {
numBit = new Bit6(1);
BitN data = new Bit42();
data.setLong(value);
dataBit = data;
}
else if(value >>> 49 == 0) {
numBit = new Bit7(1);
BitN data = new Bit49();
data.setLong(value);
dataBit = data;
}
else if(value >>> 56 == 0) {
numBit = new Bit8(1);
BitN data = new Bit56();
data.setLong(value);
dataBit = data;
}
else {
throw new RuntimeException("overflow. too big data.");
}
}
/**
* add one bit, to know data size.
* @param bit1
* @return
*/
public boolean addBit1(Bit1 bit1) {
if(bit1.get() == 1) {
// このタイミングでnumBitが決定します。
switch(zeroCount) {
case 0: numBit = new Bit1(1); break;
case 1: numBit = new Bit2(1); break;
case 2: numBit = new Bit3(1); break;
case 3: numBit = new Bit4(1); break;
case 4: numBit = new Bit5(1); break;
case 5: numBit = new Bit6(1); break;
case 6: numBit = new Bit7(1); break;
case 7: numBit = new Bit8(1); break;
default:
throw new RuntimeException("invalid ebml value.");
}
return false;
}
else {
zeroCount ++;
}
return true;
}
/**
* ref the basic data bit.
* TODO rename?
* @return
*/
public Bit getDataBit() {
switch(zeroCount) {
case 0: dataBit = new Bit7(); break;
case 1: dataBit = new Bit14(); break;
case 2: dataBit = new Bit21(); break;
case 3: dataBit = new Bit28(); break;
case 4: dataBit = new Bit35(); break;
case 5: dataBit = new Bit42(); break;
case 6: dataBit = new Bit49(); break;
case 7: dataBit = new Bit56(); break;
default:
throw new RuntimeException("imvalid ebml value.");
}
return dataBit;
}
/**
* ref the data bit.
* TODO rename?
* @return
*/
protected Bit getEbmlDataBit() {
return dataBit;
}
/**
* ref the num bit.
* TODO rename?
* @return
*/
protected Bit getEbmlNumBit() {
return numBit;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
StringBuilder data = new StringBuilder();
data.append(numBit.toString());
data.append(dataBit.toString());
return data.toString();
}
}