diff options
Diffstat (limited to 'src/net/gcdc/asn1/uper/ByteBitBuffer.java')
-rw-r--r-- | src/net/gcdc/asn1/uper/ByteBitBuffer.java | 271 |
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(); + } + +} |