unsafe static string GetEscapedString(string value) { var required = Encoding.UTF8.GetByteCount(value); byte[] buffer; required = required * 2 + 2; int result; while (true) { buffer = new byte[required]; fixed(byte *ptr = buffer) { result = ConvertUTF.WriteStringUtf8(value, ptr, buffer.Length); } if (result > 2) { break; } required *= 2; } return(Encoding.UTF8.GetString(buffer, 0, result)); }
public static Lookup?GenerateIndexedLookup(KeyValuePair <ulong, string>[] values, byte *destination, int available) { int valueCount = values.Length; if (valueCount == 0) { return(null); } var maxValue = values.Last().Key + 1; byte *endStrings = destination + available; byte *stringPtr = (byte *)(destination + (maxValue * 4)); var stringsStart = stringPtr; if (stringPtr >= destination + available) { return(null); } int valueIndex = 0; for (ulong i = 0; i < maxValue; i++) { long offset = stringPtr - stringsStart; if (offset > ushort.MaxValue) { return(null); } var enumName = GetString(values, (int)i, ref valueIndex); if (enumName == null) { *(uint *)(destination + (i * 4)) = 0; continue; } *(ushort *)(destination + (i * 4)) = (ushort)offset; int result = ConvertUTF.WriteStringUtf8(enumName, stringPtr, (int)(endStrings - stringPtr), useQuote: false); if (result <= 0 || result >= ushort.MaxValue) { return(null); } *(ushort *)(destination + (i * 4) + 2) = (ushort)result; stringPtr += result; } return(new Lookup(destination, stringsStart, stringPtr, LookupTypes.Indexed)); }
public static Lookup?GenerateSortedLookup(KeyValuePair <ulong, string>[] values, byte *destination, int available) { if (values.Length == 0) { return(null); } var maxValue = values[values.Length - 1].Key; if (maxValue > uint.MaxValue) { return(null); } byte *endStrings = destination + available; byte *stringPtr = (byte *)(destination + (values.Length * 8)); var stringsStart = stringPtr; if (stringPtr >= destination + available) { return(null); } int ix = 0; foreach (var value in values) { long offset = stringPtr - stringsStart; if (offset > ushort.MaxValue) { return(null); } *(uint *)(destination + ix) = (uint)value.Key; *(ushort *)(destination + ix + 4) = (ushort)offset; int result = ConvertUTF.WriteStringUtf8(value.Value, stringPtr, (int)(endStrings - stringPtr), useQuote: false); if (result <= 0 || result >= ushort.MaxValue) { return(null); } *(ushort *)(destination + ix + 6) = (ushort)result; stringPtr += result; ix += 8; } return(new Lookup(destination, stringsStart, stringPtr, LookupTypes.Sorted)); }
public static Lookup?GenerateVerboseLookup(KeyValuePair <ulong, string>[] values, byte *destination, int available) { if (values.Length == 0) { return(null); } byte *endStrings = destination + available; byte *stringPtr = (byte *)(destination + (values.Length * 16)); var stringsStart = stringPtr; if (stringPtr >= destination + available) { return(null); } int ix = 0; foreach (var value in values) { long offset = stringPtr - stringsStart; if (offset > ushort.MaxValue) { return(null); } int result = ConvertUTF.WriteStringUtf8(value.Value, stringPtr, (int)(endStrings - stringPtr), useQuote: false); if (result <= 0 || result >= ushort.MaxValue) { return(null); } var verbose = (VerboseEnum *)(destination + ix); bool inlined = verbose->Init(stringsStart, value.Key, stringPtr, result); if (!inlined) { stringPtr += result; } ix += 16; } return(new Lookup(destination, stringsStart, stringPtr, LookupTypes.Verbose)); }