summaryrefslogtreecommitdiffstats
path: root/src/net/gcdc/asn1/uper/ByteBitBuffer.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/net/gcdc/asn1/uper/ByteBitBuffer.java')
-rw-r--r--src/net/gcdc/asn1/uper/ByteBitBuffer.java271
1 files changed, 271 insertions, 0 deletions
diff --git a/src/net/gcdc/asn1/uper/ByteBitBuffer.java b/src/net/gcdc/asn1/uper/ByteBitBuffer.java
new file mode 100644
index 0000000..e55d9d5
--- /dev/null
+++ b/src/net/gcdc/asn1/uper/ByteBitBuffer.java
@@ -0,0 +1,271 @@
+package net.gcdc.asn1.uper;
+
+
+
+public class ByteBitBuffer implements BitBuffer {
+
+ byte[] bytes;
+ byte[] mask = new byte[] {
+ (byte) 0b1000_0000,
+ 0b0100_0000,
+ 0b0010_0000,
+ 0b0001_0000,
+ 0b0000_1000,
+ 0b0000_0100,
+ 0b0000_0010,
+ 0b0000_0001,
+ };
+
+ boolean isFinite;
+
+ int mark;
+ int position;
+ int limit;
+
+
+ @Override public boolean get(int index) {
+ if (index < 0) {
+ throw new IndexOutOfBoundsException("Index " + index + " is less than 0");
+ } else if (index >= limit) {
+ throw new IndexOutOfBoundsException("Index " + index + " violates the limit " + limit);
+ }
+ boolean result = (bytes[index / 8] & mask[index % 8]) != 0;
+ return result;
+ }
+
+ @Override public boolean get() {
+ boolean result = get(position);
+ position++;
+ return result;
+ }
+
+ private void grow() {
+ byte[] newbytes = new byte[2 * bytes.length];
+ System.arraycopy(bytes, 0, newbytes, 0, bytes.length);
+ bytes = newbytes;
+ }
+
+ @Override public BitBuffer put(int index, boolean element) {
+ if (bytes.length <= index / 8) {
+ if (isFinite) { throw new IndexOutOfBoundsException(); }
+ else { grow(); }
+ }
+ if (element) {
+ bytes[index / 8] |= mask[index % 8];
+ } else {
+ bytes[index / 8] &= ~mask[index % 8];
+ }
+ return this;
+ }
+
+ @Override public BitBuffer put(boolean element) {
+ put(position, element);
+ position++;
+ limit = limit < position ? position : limit; // TODO: should it be here?
+ return this;
+ }
+
+ @Override public BitBuffer putByte(byte element) {
+ for (int i = 0; i < 8; i++) {
+ put((element & mask[i]) != 0);
+ }
+ return this;
+ }
+
+ @Override public BitBuffer putByteArray(int index, byte[] data) {
+
+ for (int l = 0; l < data.length;l++) {
+ for (int i = 0; i < 8; i++) {
+ put((data[l] & mask[i]) != 0);
+ }
+ }
+ return this;
+ }
+
+
+ @Override public byte getByte() {
+ byte result = 0;
+ for (int i = 0; i < 8; i++) {
+ result |= (get() ? 1 : 0) << (7 - i);
+ }
+ return result;
+ }
+
+ @Override public int limit() {
+ return limit;
+ }
+
+ @Override public String toBooleanString(int startIndex, int length) {
+ StringBuilder sb = new StringBuilder(length);
+ for (int i = startIndex; i < startIndex + length; i++) {
+ sb.append(get(i) ? "1" : "0");
+ }
+ return sb.toString();
+ }
+
+ @Override public int capacity() {
+ return isFinite ? bytes.length * 8 : Integer.MAX_VALUE;
+ }
+
+ @Override public int position() {
+ return position;
+ }
+
+ @Override public int remaining() {
+ return limit - position;
+ }
+
+ public ByteBitBuffer(byte[] backingArray) {
+ this.bytes = backingArray;
+ this.isFinite = true;
+ }
+
+ private ByteBitBuffer(int initialCapacity) {
+ this.bytes = new byte[initialCapacity];
+ this.isFinite = false;
+ }
+
+ public static ByteBitBuffer allocate(int lengthInBits) {
+ return new ByteBitBuffer(new byte[(lengthInBits + 7) / 8]);
+ }
+
+ public static ByteBitBuffer createInfinite() {
+ return new ByteBitBuffer(64);
+ }
+
+ @Override public BitBuffer flip() {
+ limit = position;
+ position = 0;
+ return this;
+ }
+
+ @Override public String toBooleanStringFromPosition(int startIndex) {
+ return toBooleanString(startIndex, position-startIndex);
+ }
+
+ @Override public byte[] array() {
+ return bytes;
+ }
+
+ @Override
+ public void putInteger(int position, int length,int number) {
+ String s = Integer.toBinaryString(number);
+ if (s.length() > length) {
+ //value is to large
+ return;
+ }
+
+ for (int i = 0;i < length;i++){
+ int index = position + i;
+ this.put(index,false);
+ }
+
+
+ int startIndex = position + length - s.length();
+ for (int i = 0;i < s.length();i++){
+ /*
+ * i = max --> index = position + length - 1
+ * i = 0 --> index = position +
+ */
+ int index = startIndex + i;
+ if (s.charAt(i) == '1') {
+ this.put(index, true );
+ } else {
+ this.put(index, false);
+ }
+ }
+
+ }
+
+ @Override
+ public void putChar5String(int position, int length, String s) {
+
+ String upperCaseString = s.toUpperCase();
+ int offset = 0;
+ for (int i = 0; i < s.length() ; i++) {
+ char character = upperCaseString.charAt(i);
+ int intValue = (int) character - 32;
+ if (intValue > -1 && intValue < 64) {
+ this.putInteger(position + offset,5, intValue);
+ offset = offset + 5;
+ } else {
+ this.putInteger(position + offset,5,0);
+ position = position + 5;
+ }
+ }
+ }
+
+ @Override
+ public void putChar6String(int position, int length, String s) {
+
+ String upperCaseString = s.toUpperCase();
+ int offset = 0;
+ for (int i = 0; i < s.length() ; i++) {
+ char character = upperCaseString.charAt(i);
+ int intValue = (int) character - 32;
+ if (intValue > -1 && intValue < 64) {
+ this.putInteger(position + offset,6, intValue);
+ offset = offset + 6;
+ } else {
+ this.putInteger(position + offset,6,0);
+ position = position + 6;
+ }
+ }
+ }
+
+ @Override
+ public int getInteger(int position, int length) {
+ StringBuffer sb = new StringBuffer();
+ for (int i = 0;i < length;i++){
+ if (this.get(position + i)) {
+ sb.append("1");
+ } else {
+ sb.append("0");
+ }
+ }
+ return Integer.parseInt(sb.toString(), 2);
+ }
+
+ @Override
+ public String getChar6String(int position, int length) {
+
+ StringBuilder stringBuilder = new StringBuilder();
+
+ int chars = length / 6;
+
+ for (int i = 0; i < chars; i++) {
+ int newPosition = position + i * 6;
+
+ int x = this.getInteger(newPosition, 6);
+ x = x + 32;
+
+ char c = (char) x;
+ stringBuilder.append(c);
+
+ }
+
+ return stringBuilder.toString().trim();
+ }
+
+ @Override
+ public String getChar5String(int position, int length) {
+
+ StringBuilder stringBuilder = new StringBuilder();
+
+ int chars = length / 5;
+
+ for (int i = 0; i < chars; i++) {
+ int newPosition = position + i * 5;
+
+ int x = getInteger(newPosition, 5);
+ x = x + 42;
+
+ char c = (char) x;
+ stringBuilder.append(c);
+
+ }
+
+ return stringBuilder.toString().trim();
+ }
+
+}