1 module hunt.util.ConverterUtils;
2
3 import hunt.Exceptions;
4 import hunt.util.Appendable;
5 import hunt.util.StringBuilder;
6 import hunt.util.Traits;
7
8 import std.conv;
9 import std.format;
10 import std.string;
11 import std.typecons;
12 import std.ascii;
13
14 /**
15 *
16 */
17 struct ConverterUtils {
18
19 /**
20 * @param c An ASCII encoded character 0-9 a-f A-F
21 * @return The byte value of the character 0-16.
22 */
23 static byte convertHexDigit(byte c) {
24 byte b = cast(byte)((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
25 if (b < 0 || b > 15)
26 throw new NumberFormatException("!hex " ~ to!string(c));
27 return b;
28 }
29
30 /* ------------------------------------------------------------ */
31
32 /**
33 * @param c An ASCII encoded character 0-9 a-f A-F
34 * @return The byte value of the character 0-16.
35 */
36 static int convertHexDigit(char c) {
37 int d = ((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
38 if (d < 0 || d > 15)
39 throw new NumberFormatException("!hex " ~ to!string(c));
40 return d;
41 }
42
43 /* ------------------------------------------------------------ */
44
45 /**
46 * @param c An ASCII encoded character 0-9 a-f A-F
47 * @return The byte value of the character 0-16.
48 */
49 static int convertHexDigit(int c) {
50 int d = ((c & 0x1f) + ((c >> 6) * 0x19) - 0x10);
51 if (d < 0 || d > 15)
52 throw new NumberFormatException("!hex " ~ to!string(c));
53 return d;
54 }
55
56 /* ------------------------------------------------------------ */
57 static void toHex(byte b, Appendable buf) {
58 try {
59 int d = 0xf & ((0xF0 & b) >> 4);
60 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
61 d = 0xf & b;
62 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
63 }
64 catch (IOException e) {
65 throw new RuntimeException(e);
66 }
67 }
68
69 /* ------------------------------------------------------------ */
70 static void toHex(int value, Appendable buf) {
71 int d = 0xf & ((0xF0000000 & value) >> 28);
72 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
73 d = 0xf & ((0x0F000000 & value) >> 24);
74 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
75 d = 0xf & ((0x00F00000 & value) >> 20);
76 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
77 d = 0xf & ((0x000F0000 & value) >> 16);
78 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
79 d = 0xf & ((0x0000F000 & value) >> 12);
80 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
81 d = 0xf & ((0x00000F00 & value) >> 8);
82 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
83 d = 0xf & ((0x000000F0 & value) >> 4);
84 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
85 d = 0xf & value;
86 buf.append(cast(char)((d > 9 ? ('A' - 10) : '0') + d));
87
88 // Integer.toString(0, 36);
89 }
90
91 /* ------------------------------------------------------------ */
92 static void toHex(long value, Appendable buf) {
93 toHex(cast(int)(value >> 32), buf);
94 toHex(cast(int) value, buf);
95 }
96
97 /* ------------------------------------------------------------ */
98 static string toHexString(byte b) {
99 return toHexString([b], 0, 1);
100 }
101
102 /* ------------------------------------------------------------ */
103 static string toHexString(byte[] b) {
104 return toHexString(b, 0, cast(int) b.length);
105 }
106
107 /* ------------------------------------------------------------ */
108 static string toHexString(byte[] b, int offset, int length) {
109 StringBuilder buf = new StringBuilder();
110 for (int i = offset; i < offset + length; i++) {
111 int bi = 0xff & b[i];
112 int c = '0' + (bi / 16) % 16;
113 if (c > '9')
114 c = 'A' + (c - '0' - 10);
115 buf.append(cast(char) c);
116 c = '0' + bi % 16;
117 if (c > '9')
118 c = 'a' + (c - '0' - 10);
119 buf.append(cast(char) c);
120 }
121 return buf.toString();
122 }
123
124 static string toHexString(LetterCase letterCase = LetterCase.upper)(const(ubyte)[] b,
125 string separator="", string prefix="") {
126 static if(letterCase == LetterCase.upper) {
127 string fmt = "%(" ~ prefix ~ "%02X" ~ separator ~ "%)";
128 } else {
129 string fmt = "%(" ~ prefix ~ "%02x" ~ separator ~ "%)";
130 }
131
132 return format(fmt, b);
133 }
134
135 /* ------------------------------------------------------------ */
136 /**
137 */
138 static T[] toBytes(T)(string s) if(isByteType!T) {
139 if (s.length % 2 != 0)
140 throw new IllegalArgumentException(s);
141 T[] r = new T[s.length/2];
142 for(size_t i=0; i<r.length; i++) {
143 size_t j = i+i;
144 r[i] = cast(T)to!(int)(s[j .. j+2], 16);
145 }
146 return r;
147 }
148
149 /**
150 */
151 static byte[] fromHexString(string s) {
152 return toBytes!byte(s);
153 // if (s.length % 2 != 0)
154 // throw new IllegalArgumentException(s);
155 // byte[] array = new byte[s.length / 2];
156 // for (int i = 0; i < array.length; i++) {
157 // int b = to!int(s[i * 2 .. i * 2 + 2], 16);
158 // array[i] = cast(byte)(0xff & b);
159 // }
160 // return array;
161 }
162
163 static int parseInt(string s, int offset, int length, int base) {
164 return to!int(s[offset .. offset + length], base);
165 }
166
167 }