1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public class BinaryReader
 11     {
 12         public nothrow BinaryReader(const SharedPtr<ByteStream>& stream_) : stream(stream_)
 13         {
 14         }
 15         public bool ReadBool()
 16         {
 17             byte x = ReadByte();
 18             return cast<bool>(x);
 19         }
 20         public char ReadChar()
 21         {
 22             byte x = ReadByte();
 23             return cast<char>(x);
 24         }
 25         public wchar ReadWChar()
 26         {
 27             ushort x = ReadUShort();
 28             return cast<wchar>(x);
 29         }
 30         public uchar ReadUChar()
 31         {
 32             uint x = ReadUInt();
 33             return cast<uchar>(x);
 34         }
 35         public sbyte ReadSByte()
 36         {
 37             byte x = ReadByte();
 38             return cast<sbyte>(x);
 39         }
 40         public int ReadByteOrEnd()
 41         {
 42             return stream->ReadByte();
 43         }
 44         public byte ReadByte()
 45         {
 46             int x = stream->ReadByte();
 47             if (x == -1)
 48             {
 49                 throw FileSystemException("unexpected end of binary byte stream");
 50             }
 51             return cast<byte>(x);
 52         }
 53         public short ReadShort()
 54         {
 55             ushort x = ReadUShort();
 56             return cast<short>(x);
 57         }
 58         public ushort ReadUShort()
 59         {
 60             byte x0 = ReadByte();
 61             byte x1 = ReadByte();
 62             ushort x = cast<ushort>(x0) << 8u | cast<ushort>(x1);
 63             return x;
 64         }
 65         public int ReadInt()
 66         {
 67             uint x = ReadUInt();
 68             return cast<int>(x);
 69         }
 70         public uint ReadUInt()
 71         {
 72             byte x0 = ReadByte();
 73             byte x1 = ReadByte();
 74             byte x2 = ReadByte();
 75             byte x3 = ReadByte();
 76             uint x = cast<uint>(x0) << 24u | cast<uint>(x1) << 16u | cast<uint>(x2) << 8u | cast<uint>(x3);
 77             return x;
 78         }
 79         public long ReadLong()
 80         {
 81             ulong x = ReadULong();
 82             return cast<long>(x);
 83         }
 84         public ulong ReadULong()
 85         {
 86             byte x0 = ReadByte();
 87             byte x1 = ReadByte();
 88             byte x2 = ReadByte();
 89             byte x3 = ReadByte();
 90             byte x4 = ReadByte();
 91             byte x5 = ReadByte();
 92             byte x6 = ReadByte();
 93             byte x7 = ReadByte();
 94             ulong x = cast<ulong>(x0) << 56u | cast<ulong>(x1) << 48u | cast<ulong>(x2) << 40u | cast<ulong>(x3) << 32u | 
 95                 cast<ulong>(x4) << 24u | cast<ulong>(x5) << 16u | cast<ulong>(x6) << 8u | cast<ulong>(x7);
 96             return x;
 97         }
 98         public float ReadFloat()
 99         {
100             uint x = ReadUInt();
101             void* u = &x;
102             return *cast<float*>(u);
103         }
104         public double ReadDouble()
105         {
106             ulong x = ReadULong();
107             void* u = &x;
108             return *cast<double*>(u);
109         }
110         public string ReadString()
111         {
112             string s;
113             char c = ReadChar();
114             while (c != '\0')
115             {
116                 s.Append(c);
117                 c = ReadChar();
118             }
119             return s;
120         }
121         public wstring ReadWString()
122         {
123             string s = ReadString();
124             return ToUtf16(s);
125         }
126         public ustring ReadUString()
127         {
128             string s = ReadString();
129             return ToUtf32(s);
130         }
131         public uint ReadULEB128UInt()
132         {
133             uint result = 0u;
134             uint shift = 0u;
135             while (true)
136             {
137                 byte b = ReadByte();
138                 result = result | ((b & 0x7Fu) << shift);
139                 if ((b & 0x80u) == 0u) break;
140                 shift = shift + 7u;
141             }
142             return result;
143         }
144         public ulong ReadULEB128ULong()
145         {
146             ulong result = 0u;
147             ulong shift = 0u;
148             while (true)
149             {
150                 byte b = ReadByte();
151                 result = result | ((b & 0x7Fu) << shift);
152                 if ((b & 0x80u) == 0u) break;
153                 shift = shift + 7u;
154             }
155             return result;
156         }
157         public int ReadSLEB128Int()
158         {
159             int result = 0;
160             int shift = 0;
161             byte b = 0u;
162             do
163             {
164                 b = ReadByte();
165                 result = result | ((b & 0x7Fu) << shift);
166                 shift = shift + 7;
167             }
168             while ((b & 0x80u) != 0u);
169             if ((shift < 32) && (b & 0x40u) != 0u)
170             {
171                 result = result | ~cast<int>(0) << shift;
172             }
173             return result;
174         }
175         public long ReadSLEB128Long()
176         {
177             long result = 0;
178             long shift = 0;
179             byte b = 0u;
180             do
181             {
182                 b = ReadByte();
183                 result = result | ((b & 0x7Fu) << shift);
184                 shift = shift + 7;
185             }
186             while ((b & 0x80u) != 0u);
187             if ((shift < 64) && (b & 0x40u) != 0u)
188             {
189                 result = result | ~cast<long>(0) << shift;
190             }
191             return result;
192         }
193         public Uuid ReadUuid()
194         {
195             Uuid uuid;
196             for (byte& b : uuid)
197             {
198                 b = ReadByte();
199             }
200             return uuid;
201         }
202         public void Read(byte* bufferint size)
203         {
204             for (int i = 0; i < size; ++i;)
205             {
206                 buffer[i] = ReadByte();
207             }
208         }
209         public void Seek(long posOrigin origin)
210         {
211             stream->Seek(posorigin);
212         }
213         public long Tell()
214         {
215             return stream->Tell();
216         }
217         public long Size()
218         {
219             long pos = Tell();
220             Seek(0Origin.seekEnd);
221             long size = Tell();
222             Seek(posOrigin.seekSet);
223             return size;
224         }
225         public nothrow const SharedPtr<ByteStream>& ContainedStream()
226         {
227             return stream;
228         }
229         private SharedPtr<ByteStream> stream;
230     }
231 }