/// <summary> /// Store a new string at the end of memory, and return a string pointer token for it /// </summary> public double StoreStringAndGetReference(string str) { // short strings are stack/scope values if (str.Length <= 6) { return(NanTags.EncodeShortStr(str)); } // Longer strings need to be allocated var location = encodedTokens.Count; var bytes = Encoding.ASCII.GetBytes(str); var headerOpCode = NanTags.EncodeUInt32((uint)bytes.Length); encodedTokens.Add(headerOpCode); unchecked { ulong pack = 0; int rem = 0; for (int i = 0; i < bytes.Length; i++) { pack += ((ulong)bytes[i]) << rem; rem += 8; if (rem > 56) { encodedTokens.Add(BitConverter.Int64BitsToDouble((long)pack)); rem = 0; pack = 0; } } if (rem != 0) { for (; rem < 64; rem += 8) { pack += ((ulong)'_') << rem; } encodedTokens.Add(BitConverter.Int64BitsToDouble((long)pack)); } } var token = NanTags.EncodePointer(location, DataType.PtrString); Variables.PotentialGarbage.Add(token); return(token); }
public void pointer_encoding_survives_a_round_trip() { var rnd = new Random(); for (int i = 0; i < 10000; i++) { long target = rnd.Next() + ((long)rnd.Next() << 15); var type = DataType.PtrArray_String; var enc = NanTags.EncodePointer(target, type); NanTags.DecodePointer(enc, out var newTarget, out var newType); Assert.That(newTarget, Is.EqualTo(target), "Multiplier: " + i); Assert.That(newType, Is.EqualTo(type)); } }