-
-
Notifications
You must be signed in to change notification settings - Fork 745
add std.conv.hexData() #7211
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add std.conv.hexData() #7211
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6031,6 +6031,10 @@ Params: | |
|
|
||
| Returns: | ||
| a `string`, a `wstring` or a `dstring`, according to the type of hexData. | ||
|
|
||
| References: | ||
| Prefer using $(LREF hexData) instead, especially if the `hexData` string is long | ||
| because it does not use templates. | ||
| */ | ||
| template hexString(string hexData) | ||
| if (hexData.isHexLiteral) | ||
|
|
@@ -6136,6 +6140,88 @@ private auto hexStrLiteral(String)(scope String hexData) | |
| assert(hexString!"ab cd" == hexString!"ABCD"); | ||
| } | ||
|
|
||
| /************************************************ | ||
| * Convert string of `[0-9A-Fa-f]` characters to an array of ubytes. | ||
| * | ||
| * Other characters in the string are considered separators. | ||
| * Adjacent pairs of characters form the nibbles of the ubyte. | ||
| * Non-pairing characters form the low nibble of the ubyte. | ||
| * The returned array does not have a terminating zero appended. | ||
| * The GC is used because `hexData()` is intended to be used | ||
| * at compile time to, for example, initialize manifest constants | ||
| * and statically initialize global variables. | ||
| * Params: | ||
| * s = string of data to convert | ||
| * Returns: | ||
| * unique array of ubytes allocated on the GC heap | ||
| * References: | ||
| * $(LREF hexString) | ||
| */ | ||
| ubyte[] hexData(const(char)[] s) pure nothrow @safe | ||
| { | ||
| ubyte[] result; | ||
| result.length = (s.length + 1) / 2; | ||
| size_t i; | ||
|
|
||
| void append(ubyte u) | ||
| { | ||
| result[i++] = u; | ||
| } | ||
|
|
||
| ubyte u; | ||
| uint digits; | ||
| foreach (char c; s) | ||
| { | ||
| if ('0' <= c && c <= '9') | ||
| c -= '0'; | ||
| else if ('a' <= c && c <= 'f') | ||
| c -= 'a' - 10; | ||
| else if ('A' <= c && c <= 'F') | ||
| c -= 'A' - 10; | ||
| else | ||
| { | ||
| if (digits) | ||
| append(u); | ||
| u = 0; | ||
| digits = 0; | ||
| continue; | ||
| } | ||
|
|
||
|
|
||
|
Comment on lines
+6189
to
+6190
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One line space will suffice.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I use two lines to separate one function from the next unrelated one. |
||
| if (++digits == 2) | ||
| { | ||
| append(cast(ubyte)((u << 4) + c)); | ||
| digits = 0; | ||
| } | ||
| else | ||
| u = c; | ||
| } | ||
| if (digits) | ||
| append(u); | ||
|
|
||
| return result[0 .. i]; | ||
| } | ||
|
|
||
| /// | ||
| @safe nothrow unittest | ||
| { | ||
| static g1 = hexData("af,fa"); | ||
| assert(g1 == [0xAF, 0xFA]); | ||
|
|
||
| enum a1 = hexData("AAbb"); | ||
| assert(a1 == [0xAA, 0xBB]); | ||
| enum a2 = hexData(""); | ||
| assert(a2 == []); | ||
| enum a3 = hexData(" \t\r\n"); | ||
| assert(a3 == []); | ||
| enum a4 = hexData("f"); | ||
| assert(a4 == [0xF]); | ||
| enum a5 = hexData(" f,"); | ||
| assert(a5 == [0xF]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why support odd number of digits? This is probably going to almost always be an error or typo. |
||
| enum a6 = hexData("0BF "); | ||
| assert(a6 == [0x0B, 0x0F]); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should probably be some tests to test the behavior with invalid inputs. Speaking of which, they seem to be ignored? Combined with the decision to support one-digit characters, this seems like a bad idea, e.g. in
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. G-Z should be an error, that's bug prone.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As currently specified there are no invalid inputs to this function. |
||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Convert integer to a range of characters. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems a bit much, it's called from three places