1 package au.gov.amsa.util;
2
3 public final class SixBit {
4
5
6 private static final int[] INT_TO_SIX_BIT = createIntToSixBit();
7
8 private static int[] createIntToSixBit() {
9 int[] toSixbit = new int[256 * 256];
10
11
12 for (int chr = 0; chr < toSixbit.length; chr++) {
13 if (chr < 48 || chr > 119 || chr > 87 && chr < 96) {
14 toSixbit[chr] = -1;
15 } else if (chr < 0x60) {
16 toSixbit[chr] = chr - 48 & 0x3F;
17 } else {
18 toSixbit[chr] = chr - 56 & 0x3F;
19 }
20 }
21 return toSixbit;
22 }
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public static void convertSixBitToBits(String str, int padBits, boolean bitSet[],
37 boolean[] calculated, int from, int to) {
38 if (str.length() == 0)
39 return;
40 int index = from - from % 6;
41 int strFrom = from / 6;
42 int slen = str.length() - 1;
43 int strTo = to / 6 + 1;
44 for (int i = strFrom; i < Math.min(strTo, slen); i++) {
45 if (!calculated[i]) {
46 char chr = str.charAt(i);
47 int binVal = INT_TO_SIX_BIT[chr];
48 if (binVal == -1) {
49 throw new SixBitException("Illegal sixbit ascii char: " + chr);
50 }
51 bitSet[index] = (binVal & 32) > 0;
52 bitSet[index + 1] = (binVal & 16) > 0;
53 bitSet[index + 2] = (binVal & 8) > 0;
54 bitSet[index + 3] = (binVal & 4) > 0;
55 bitSet[index + 4] = (binVal & 2) > 0;
56 bitSet[index + 5] = (binVal & 1) > 0;
57
58 calculated[i] = true;
59 }
60
61 index += 6;
62 }
63 if (strTo > slen) {
64
65 char chr = str.charAt(slen);
66 int binVal = INT_TO_SIX_BIT[chr];
67 if (binVal == -1) {
68 throw new SixBitException("Illegal sixbit ascii char: " + chr);
69 }
70 int bits = 6 - padBits;
71
72 switch (bits) {
73 case 6:
74 bitSet[index + 5] = (binVal & 1) > 0;
75 case 5:
76 bitSet[index + 4] = (binVal & 2) > 0;
77 case 4:
78 bitSet[index + 3] = (binVal & 4) > 0;
79 case 3:
80 bitSet[index + 2] = (binVal & 8) > 0;
81 case 2:
82 bitSet[index + 1] = (binVal & 16) > 0;
83 case 1:
84 bitSet[index] = (binVal & 32) > 0;
85 }
86
87 calculated[slen] = true;
88 }
89 }
90
91 public static long getValue(int from, int to, boolean[] bitSet) {
92 if (to > bitSet.length) {
93 throw new SixBitException(bitSet.length + " is not enough bits. At least " + to
94 + " expected.");
95 }
96 long val = 0;
97 long powMask = 1;
98 for (int i = to - 1; i >= from; i--) {
99 if (bitSet[i]) {
100 val += powMask;
101 }
102 powMask <<= 1;
103 }
104 return val;
105 }
106
107 public static long getSignedValue(int from, int to, boolean[] bitSet) {
108 if (to > bitSet.length) {
109 throw new SixBitException(bitSet.length + " is not enough bits. At least " + to
110 + " expected.");
111 }
112 long val = 0;
113 long powMask = 1;
114
115 for (int i = to - 1; i >= from; i--) {
116 if (bitSet[i]) {
117 val += powMask;
118 }
119 powMask <<= 1;
120 }
121 if (bitSet[from]) {
122 val = val - powMask;
123 }
124 return val;
125 }
126
127 public static String getString(int from, int to, boolean[] bitSet) {
128 int len = (to - from) / 6;
129 char[] resStr = new char[len];
130 int pos = from;
131 int i;
132 for (i = 0; i < len; i++) {
133
134
135
136 char ch = (char) intToAscii((char) SixBit.getValue(pos, pos + 6, bitSet));
137
138 if (ch == '@') {
139 len = i;
140 break;
141 }
142 resStr[i] = ch;
143 pos += 6;
144 }
145
146 while (len > 0 && (resStr[len - 1] == ' '))
147 len -= 1;
148 return new String(resStr, 0, len);
149 }
150
151
152
153
154
155
156
157 private static int intToAscii(int val) {
158 if (val > 63) {
159 throw new SixBitException("Char value " + val + " not allowed");
160 } else if (val < 32) {
161 return val + 64;
162 } else {
163 return val;
164 }
165 }
166
167 }