using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Drawing;
namespace BlittableStructure {
static class Program {
static class Blittable<T> where T : struct {
public static readonly int Size = Marshal.SizeOf(typeof(T));
[ThreadStatic]
public static readonly byte[] SrcBuffer = new byte[Size];
[ThreadStatic]
public static readonly T[] DestBuffer = new T[1];
}
static T Read<T>(this Stream input) where T : struct {
var size = Blittable<T>.Size;
var srcbuf = Blittable<T>.SrcBuffer;
var destbuf = Blittable<T>.DestBuffer;
if (input.Read(srcbuf, 0, size) < size)
throw new EndOfStreamException();
var desthandle = GCHandle.Alloc(destbuf, GCHandleType.Pinned);
try {
var destptr = desthandle.AddrOfPinnedObject();
Marshal.Copy(srcbuf, 0, destptr, size);
return destbuf[0];
} finally {
desthandle.Free();
}
}
public static void Main() {
var data = new byte[] { 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x13, 0x45 };
using (var stream = new MemoryStream(data)) {
var point = stream.Read<Point>();
Console.WriteLine("{0:X},{1:X}", point.X, point.Y);
}
}
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uRGlhZ25vc3RpY3M7CnVzaW5nIFN5c3RlbS5JTzsKdXNpbmcgU3lzdGVtLlJlZmxlY3Rpb247CnVzaW5nIFN5c3RlbS5SdW50aW1lLkNvbXBpbGVyU2VydmljZXM7CnVzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlczsKdXNpbmcgU3lzdGVtLkRyYXdpbmc7CgpuYW1lc3BhY2UgQmxpdHRhYmxlU3RydWN0dXJlIHsKCXN0YXRpYyBjbGFzcyBQcm9ncmFtIHsKCQlzdGF0aWMgY2xhc3MgQmxpdHRhYmxlPFQ+IHdoZXJlIFQgOiBzdHJ1Y3QgewoJCQlwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGludCBTaXplID0gTWFyc2hhbC5TaXplT2YodHlwZW9mKFQpKTsKCQkJCgkJCVtUaHJlYWRTdGF0aWNdCgkJCXB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgYnl0ZVtdIFNyY0J1ZmZlciA9IG5ldyBieXRlW1NpemVdOwoJCQkKCQkJW1RocmVhZFN0YXRpY10KCQkJcHVibGljIHN0YXRpYyByZWFkb25seSBUW10gRGVzdEJ1ZmZlciA9IG5ldyBUWzFdOwoJCX0KCgkJc3RhdGljIFQgUmVhZDxUPih0aGlzIFN0cmVhbSBpbnB1dCkgd2hlcmUgVCA6IHN0cnVjdCB7CgkJCXZhciBzaXplID0gQmxpdHRhYmxlPFQ+LlNpemU7CgkJCXZhciBzcmNidWYgPSBCbGl0dGFibGU8VD4uU3JjQnVmZmVyOwoJCQl2YXIgZGVzdGJ1ZiA9IEJsaXR0YWJsZTxUPi5EZXN0QnVmZmVyOwoJCQlpZiAoaW5wdXQuUmVhZChzcmNidWYsIDAsIHNpemUpIDwgc2l6ZSkKCQkJCXRocm93IG5ldyBFbmRPZlN0cmVhbUV4Y2VwdGlvbigpOwoJCQl2YXIgZGVzdGhhbmRsZSA9IEdDSGFuZGxlLkFsbG9jKGRlc3RidWYsIEdDSGFuZGxlVHlwZS5QaW5uZWQpOwoJCQl0cnkgewoJCQkJdmFyIGRlc3RwdHIgPSBkZXN0aGFuZGxlLkFkZHJPZlBpbm5lZE9iamVjdCgpOwoJCQkJTWFyc2hhbC5Db3B5KHNyY2J1ZiwgMCwgZGVzdHB0ciwgc2l6ZSk7CgkJCQlyZXR1cm4gZGVzdGJ1ZlswXTsKCQkJfSBmaW5hbGx5IHsKCQkJCWRlc3RoYW5kbGUuRnJlZSgpOwoJCQl9CgkJfQoJCQoJCXB1YmxpYyBzdGF0aWMgdm9pZCBNYWluKCkgewoJCQl2YXIgZGF0YSA9IG5ldyBieXRlW10geyAweDEyLCAweDM0LCAweDU2LCAweDc4LCAweDkwLCAweDEyLCAweDEzLCAweDQ1IH07CgkJCXVzaW5nICh2YXIgc3RyZWFtID0gbmV3IE1lbW9yeVN0cmVhbShkYXRhKSkgewoJCQkJdmFyIHBvaW50ID0gc3RyZWFtLlJlYWQ8UG9pbnQ+KCk7CgkJCQlDb25zb2xlLldyaXRlTGluZSgiezA6WH0sezE6WH0iLCBwb2ludC5YLCBwb2ludC5ZKTsKCQkJfQoJCX0KCX0KfQo=