@@ -6031,6 +6031,10 @@ Params:
60316031
60326032Returns:
60336033 a `string`, a `wstring` or a `dstring`, according to the type of hexData.
6034+
6035+ References:
6036+ Prefer using $(LREF hexData) instead, especially if the `hexData` string is long
6037+ because it does not use templates.
60346038 */
60356039template hexString (string hexData)
60366040if (hexData.isHexLiteral)
@@ -6136,6 +6140,88 @@ private auto hexStrLiteral(String)(scope String hexData)
61366140 assert (hexString! " ab cd" == hexString! " ABCD" );
61376141}
61386142
6143+ /* ***********************************************
6144+ * Convert string of `[0-9A-Fa-f]` characters to an array of ubytes.
6145+ *
6146+ * Other characters in the string are considered separators.
6147+ * Adjacent pairs of characters form the nibbles of the ubyte.
6148+ * Non-pairing characters form the low nibble of the ubyte.
6149+ * The returned array does not have a terminating zero appended.
6150+ * The GC is used because `hexData()` is intended to be used
6151+ * at compile time to, for example, initialize manifest constants
6152+ * and statically initialize global variables.
6153+ * Params:
6154+ * s = string of data to convert
6155+ * Returns:
6156+ * unique immutable array of ubytes allocated on the GC heap
6157+ * References:
6158+ * $(LREF hexString)
6159+ */
6160+ immutable (ubyte )[] hexData (const (char )[] s) pure nothrow @trusted
6161+ {
6162+ ubyte [] result;
6163+ result.length = (s.length + 1 ) / 2 ;
6164+ size_t i;
6165+
6166+ void append (ubyte u)
6167+ {
6168+ result[i++ ] = u;
6169+ }
6170+
6171+ ubyte u;
6172+ uint digits;
6173+ foreach (char c; s)
6174+ {
6175+ if (' 0' <= c && c <= ' 9' )
6176+ c -= ' 0' ;
6177+ else if (' a' <= c && c <= ' f' )
6178+ c -= ' a' - 10 ;
6179+ else if (' A' <= c && c <= ' F' )
6180+ c -= ' A' - 10 ;
6181+ else
6182+ {
6183+ if (digits)
6184+ append(u);
6185+ u = 0 ;
6186+ digits = 0 ;
6187+ continue ;
6188+ }
6189+
6190+
6191+ if (++ digits == 2 )
6192+ {
6193+ append(cast (ubyte )((u << 4 ) + c));
6194+ digits = 0 ;
6195+ }
6196+ else
6197+ u = c;
6198+ }
6199+ if (digits)
6200+ append(u);
6201+
6202+ return cast (immutable ) result[0 .. i];
6203+ }
6204+
6205+ // /
6206+ @safe nothrow unittest
6207+ {
6208+ static g1 = hexData(" af,fa" );
6209+ assert (g1 == [0xAF , 0xFA ]);
6210+
6211+ enum a1 = hexData(" AAbb" );
6212+ assert (a1 == [0xAA , 0xBB ]);
6213+ enum a2 = hexData(" " );
6214+ assert (a2 == []);
6215+ enum a3 = hexData(" \t\r\n " );
6216+ assert (a3 == []);
6217+ enum a4 = hexData(" f" );
6218+ assert (a4 == [0xF ]);
6219+ enum a5 = hexData(" f," );
6220+ assert (a5 == [0xF ]);
6221+ enum a6 = hexData(" 0BF " );
6222+ assert (a6 == [0x0B , 0x0F ]);
6223+ }
6224+
61396225
61406226/**
61416227 * Convert integer to a range of characters.
0 commit comments