public static byte[] HexDecode(RStr encoded) { using FastBuffer <byte> b = new(encoded.Length / 2); int n = HexDecode(encoded, b.p, b.n); var r = new byte[n]; Marshal.Copy((IntPtr)b.p, r, 0, n); return(r); }
/// <summary> /// Converts hex encoded string to a struct variable. /// Returns false if decoded size != <c>sizeof(T)</c>. /// </summary> /// <param name="encoded">String or char[] or span of string/array/memory containing hex encoded data.</param> /// <param name="decoded">The result variable.</param> public static bool HexDecode <T>(RStr encoded, out T decoded) where T : unmanaged { T t; if (HexDecode(encoded, &t, sizeof(T)) != sizeof(T)) { decoded = default; return(false); } decoded = t; return(true); }
/// <summary> /// Converts string to UTF-8 byte[]. Can append "\0" (default) or some other string. /// </summary> /// <param name="chars">String or char[] or span of string/array/memory.</param> /// <param name="append">A string to append, or null. For example "\0" (default) or "\r\n". Must contain only ASCII characters.</param> /// <exception cref="ArgumentException"><i>append</i> contains non-ASCII characters.</exception> public static byte[] Utf8Encode(RStr chars, string append = "\0") { int n = Encoding.UTF8.GetByteCount(chars); int nAppend = append.Lenn(); var r = new byte[n + nAppend]; int nn = Encoding.UTF8.GetBytes(chars, r); Debug.Assert(nn == n); if (nAppend > 0 && !(nAppend == 1 && append[0] == '\0')) { foreach (char c in append) { if (c > 127) { throw new ArgumentException("append must be ASCII"); } r[nn++] = (byte)c; } } return(r); //speed: faster than WideCharToMultiByte. Same as System.Text.Unicode.Utf8.FromUtf16. }
/// <summary> /// Converts hex encoded string to binary data. Writes to caller's memory buffer. /// Returns the number of bytes written in <i>decoded</i> memory. It is equal or less than <c>Math.Min(bufferSize, encoded.Length/2)</c>. /// </summary> /// <param name="encoded">String or char[] or span of string/array/memory containing hex encoded data.</param> /// <param name="decoded">Memory buffer for result.</param> /// <param name="bufferSize">Max number of bytes that can be written to the <i>decoded</i> memory buffer.</param> /// <remarks> /// Skips spaces and other non-hex-digit characters. Example: "01 23 46 67" is the same as "01234667". /// The number of hex digit characters should be divisible by 2, else the last character is ignored. /// </remarks> public static int HexDecode(RStr encoded, void *decoded, int bufferSize) { if (encoded.Length == 0) { return(0); } var t = Tables_.Hex; byte *r = (byte *)decoded, rTo = r + bufferSize; uint k = 1; for (int i = 0; i < encoded.Length; i++) { uint c = (uint)(encoded[i] - '0'); if (c >= 55) { continue; } c = t[c]; if (c == 0xFF) { continue; } k <<= 4; k |= c; if (0 != (k & 0x100)) { if (r >= rTo) { break; } *r++ = (byte)k; k = 1; } } return((int)(r - (byte *)decoded)); //speed: slightly slower than Base64Decode for the same binary data size. }