fork(1) download
  1. using System;
  2. using System.Diagnostics;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.Reflection;
  6. using System.Runtime.CompilerServices;
  7. using System.Runtime.InteropServices;
  8. using System.Text;
  9. using System.Windows.Forms;
  10.  
  11. namespace BlittableStructure {
  12. static class Program {
  13. delegate uint SizeOfType(Type type);
  14. static SizeOfType SizeOf = typeof(Marshal).GetMethod("SizeOfType", BindingFlags.NonPublic | BindingFlags.Static).CreateDelegate(typeof(SizeOfType)) as SizeOfType;
  15.  
  16. static class Blittable<T> where T : struct {
  17. public static readonly int Size = (int)SizeOf(typeof(T));
  18. public static readonly unsafe void* Handle = typeof(T).TypeHandle.Value.ToPointer();
  19. }
  20.  
  21. [FixedAddressValueType]
  22. static readonly unsafe void* handle = typeof(Array).TypeHandle.Value.ToPointer(),
  23. type = typeof(byte[]).TypeHandle.Value.ToPointer();
  24.  
  25. [MethodImpl(MethodImplOptions.AggressiveInlining, MethodCodeType = MethodCodeType.IL)]
  26. static unsafe T Read<T>(this Stream input) where T : struct {
  27. var size = Blittable<T>.Size;
  28. var tref = stackalloc byte[IntPtr.Size * 5 + size];
  29. var inst = (void**)tref + 3;
  30. inst[1] = (void*)size;
  31. inst[0] = handle;
  32. inst[-2] = type;
  33. inst[-3] = &inst;
  34. if(input.Read( __refvalue(*(TypedReference*)tref, byte[]), 0, size) < size) throw new EndOfStreamException();
  35. inst[-3] = inst + 2;
  36. inst[-2] = Blittable<T>.Handle;
  37. return __refvalue( *(TypedReference*)tref,T);
  38. }
  39. /// <summary>
  40. /// アプリケーションのメイン エントリ ポイントです。
  41. /// </summary>
  42. [STAThread]
  43. static unsafe void Main(string[] args) {
  44. Application.EnableVisualStyles();
  45. Application.SetCompatibleTextRenderingDefault(false);
  46. //Application.Run(new Form1());
  47. try {
  48. var i = 100000;
  49. var stack = stackalloc int[i];
  50. stack[1] = 1;
  51. stack[2] = 2;
  52. stack[3] = 3;
  53. stack[4] = 4;
  54. using(var mem = new UnmanagedMemoryStream((byte*)stack, sizeof(int) * i))
  55. using(var bin = new BinaryReader(mem, Encoding.ASCII, true)) {
  56. var sw = Stopwatch.StartNew();
  57. mem.Read<int>();
  58. Console.WriteLine(mem.Read<Rectangle>());
  59.  
  60. mem.Seek(0L, SeekOrigin.Begin);
  61. sw.Restart();
  62. while(--i >= 0) mem.Read<int>();
  63. Console.WriteLine(sw.ElapsedTicks);
  64.  
  65. i = 100000;
  66.  
  67. mem.Seek(0L, SeekOrigin.Begin);
  68. sw.Restart();
  69. while(--i >= 0) bin.ReadInt32();
  70. Console.WriteLine(sw.ElapsedTicks);
  71. }
  72. } catch(Exception e) {
  73. Console.WriteLine(e);
  74. }
  75. }
  76. }
  77. }
  78.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(18,27): error CS0227: Unsafe code requires the `unsafe' command line option to be specified
prog.cs(22,19): error CS0227: Unsafe code requires the `unsafe' command line option to be specified
prog.cs(26,10): error CS0227: Unsafe code requires the `unsafe' command line option to be specified
prog.cs(43,10): error CS0227: Unsafe code requires the `unsafe' command line option to be specified
Compilation failed: 4 error(s), 0 warnings
stdout
Standard output is empty