internal static unsafe Guid Read(ref ProtoReader.State state) { // note: we can't use a stackalloc-span here because the compiler doesn't trust // state, which is a ref-local (and can store spans), not to store it; since we *don't* // do that, we can be evil byte *ptr = stackalloc byte[MAX_LENGTH]; var available = state.ReadBytes(new Span <byte>(ptr, MAX_LENGTH)); char standardFormat; switch (available.Length) { case 0: return(Guid.Empty); case 16: // treat as big-endian bytes // expand those bytes to hex, backwards so we don't overwrite live data int write = 32; for (int i = 15; i >= 0; i--) { var val = ptr[i]; ptr[--write] = ToHex(val & 0b1111); ptr[--write] = ToHex((val >> 4) & 0b1111); } available = new Span <byte>(ptr, 32); standardFormat = 'N'; break; case 32: // no hyphens standardFormat = 'N'; break; case 36: // hyphens standardFormat = 'D'; break; default: ThrowHelper.Format($"Unexpected Guid length: {available.Length}"); return(default); } if (!(Utf8Parser.TryParse(available, out Guid guid, out int bytes, standardFormat) && bytes == available.Length)) { ThrowHelper.Format($"Failed to read Guid: '{Encoding.UTF8.GetString(ptr, available.Length)}'"); } return(guid);