OSDN Git Service

f4068a42b860460249823b5770e808ad4a1256be
[bm-asn1/bm-asn1.git] / jp / bitmeister / asn1 / value / HexString.java
1 /*
2  * Copyright 2011-2012 BitMeister Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package jp.bitmeister.asn1.value;
17
18 import jp.bitmeister.asn1.exception.ASN1IllegalArgument;
19
20 /**
21  * Represents ASN.1 'Hex string(hString)' item.
22  * 
23  * <p>
24  * An instance of this class represents a 'hString' item.
25  * </p>
26  * 
27  * @author WATANABE, Jun. <jwat at bitmeister.jp>
28  */
29 public class HexString implements StringItem {
30
31         /**
32          * Hexadecimal digit characters.
33          */
34         private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
35                         '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
36
37         /**
38          * The hexadecimal string.
39          */
40         private String string;
41
42         /**
43          * Instantiates a {@code HexString} and initialize it with a {@code String}.
44          * 
45          * @param string
46          *            The {@code String} that consist of an arbitrary numbers of
47          *            hexadecimal characters.
48          */
49         public HexString(String string) {
50                 if (!string.matches("[0-9A-Fa-f \n]*")) {
51                         ASN1IllegalArgument ex = new ASN1IllegalArgument();
52                         ex.setMessage("Invalid string '" + string
53                                         + "'. hString must consist of hexadecimal string.", null,
54                                         null, null, null);
55                         throw ex;
56                 }
57                 StringBuilder builder = new StringBuilder();
58                 for (char c : string.toCharArray()) {
59                         if (Character.digit(c, 16) >= 0) {
60                                 builder.append(c);
61                         }
62                 }
63                 this.string = builder.toString().trim().toUpperCase();
64         }
65
66         /**
67          * Instantiates a {@code HexString} and initialize it with an array of
68          * {@code byte}.
69          * 
70          * @param array
71          *            The array of {@code byte}.
72          */
73         public HexString(byte... array) {
74                 StringBuilder builder = new StringBuilder();
75                 for (Byte b : array) {
76                         builder.append(HEX_DIGITS[(b & 0xf0) >> 4]);
77                         builder.append(HEX_DIGITS[b & 0x0f]);
78                 }
79                 string = builder.toString();
80         }
81
82         /**
83          * Returns the string value of this hString.
84          * 
85          * @return The hexadecimal string.
86          */
87         public String string() {
88                 return string;
89         }
90
91         /**
92          * Converts the value of this hString to an array of {@code boolean}.
93          * 
94          * @return An array of {@code boolean}.
95          */
96         public boolean[] toBinArray() {
97                 boolean[] array = new boolean[string.length() * 4];
98                 int index = 0, mask = 0;
99                 int octet = 0;
100                 for (int i = 0; i < array.length; i++) {
101                         if (mask == 0) {
102                                 octet = charToInt(string.charAt(index++));
103                                 mask = 8;
104                         }
105                         array[i] = (octet & mask) > 0;
106                         mask >>>= 1;
107                 }
108                 return array;
109         }
110
111         /**
112          * Converts the value of this hString to an array of {@code byte}.
113          * 
114          * @return An array of {@code byte}.
115          */
116         public byte[] toByteArray() {
117                 byte[] array = new byte[(string.length() + 1) / 2];
118                 int ci = string.length() - 1, bi = array.length - 1;
119                 if (string.length() % 2 != 0) {
120                         array[bi--] = (byte) (charToInt(string.charAt(ci--)) << 4);
121                 }
122                 for (; ci > 0; bi--) {
123                         array[bi] = (byte) charToInt(string.charAt(ci--));
124                         array[bi] += (byte) (charToInt(string.charAt(ci--)) << 4);
125                 }
126                 return array;
127         }
128
129         /**
130          * Returns a string representation of this item.
131          * 
132          * @return A string representation of this item.
133          */
134         @Override
135         public String toString() {
136                 return '\'' + string + "\'H";
137         }
138
139         /**
140          * Converts a hexadecimal {@code char} to {@code int} value.
141          * 
142          * @param c A hexadecimal character.
143          * @return The integer value.
144          */
145         private int charToInt(char c) {
146                 return c <= '9' ? c - '0' : c + (10 - 'A');
147         }
148 }