1 module hunt.util.ConverterUtils; 2 3 import hunt.Exceptions; 4 import hunt.util.Appendable; 5 import hunt.util.StringBuilder; 6 import hunt.util.Common; 7 import hunt.util.Traits; 8 9 import std.conv; 10 import std.format; 11 import std.string; 12 import std.typecons; 13 import std.ascii; 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 }