// returns the length of serialized value when successful unsafe static int?CheckBoundary <T>(T value, int maxLength = 64) { const byte init = 255; var nJSON = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(value)); var buffer = new byte[maxLength + 2]; var emit = DelegateBuilder.CreatePointer <T>(Schema.Reflect(typeof(T))); string instructions; var del = (Serializer.WriteToPointer <T>)emit.CreateDelegate(typeof(Serializer.WriteToPointer <T>), out instructions); int? successLength = null; for (int i = 1; i <= maxLength; i++) { for (int j = 0; j < buffer.Length; j++) { buffer[j] = init; } int result; fixed(byte *ptr = buffer) { result = del.Invoke(ref value, ptr + 1, i); } // make sure we didn't go past the boundary Assert.Equal(init, buffer[0]); Assert.Equal(init, buffer[i + 1]); Assert.True(result <= i, "Don't exceed length"); if (result > 0) { Assert.Equal(nJSON, buffer.Skip(1).Take(result)); if (successLength == null) { successLength = i; } } } if (successLength.HasValue) { emit = DelegateBuilder.CreateStream <T>(Schema.Reflect(typeof(T))); var streamer = (Serializer.WriteToStream <T>)emit.CreateDelegate(typeof(Serializer.WriteToStream <T>), out instructions); var min = Math.Max(nJSON.Length / 2, 32); var ms = new MemoryStream(nJSON.Length); // do stuff with the stream version now for (int i = nJSON.Length; i >= min; i--) { ms.SetLength(0); buffer = new byte[i]; fixed(byte *ptr = buffer) { streamer.Invoke(ref value, ptr, ms, buffer); } Assert.Equal(nJSON, ms.GetBuffer().Take((int)ms.Length)); } } return(successLength); }