1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public class BinaryWriter
 11     {
 12         public nothrow BinaryWriter(const SharedPtr<Stream>& stream_) : stream(stream_)
 13         {
 14         }
 15         public void Write(bool x)
 16         {
 17             Write(cast<byte>(x));
 18         }
 19         public void Write(char x)
 20         {
 21             Write(cast<byte>(x));
 22         }
 23         public void Write(wchar x)
 24         {
 25             Write(cast<ushort>(x));
 26         }
 27         public void Write(uchar x)
 28         {
 29             Write(cast<uint>(x));
 30         }
 31         public void Write(sbyte x)
 32         {
 33             Write(cast<byte>(x));
 34         }
 35         public void Write(byte x)
 36         {
 37             stream->Write(x);
 38         }
 39         public void Write(short x)
 40         {
 41             Write(cast<ushort>(x));
 42         }
 43         public void Write(ushort x)
 44         {
 45             byte x0 = cast<byte>(x >> 8u);
 46             byte x1 = cast<byte>(x);
 47             Write(x0);
 48             Write(x1);
 49         }
 50         public void Write(int x)
 51         {
 52             Write(cast<uint>(x));
 53         }
 54         public void Write(uint x)
 55         {
 56             byte x0 = cast<byte>(x >> 24u);
 57             byte x1 = cast<byte>(x >> 16u);
 58             byte x2 = cast<byte>(x >> 8u);
 59             byte x3 = cast<byte>(x);
 60             Write(x0);
 61             Write(x1);
 62             Write(x2);
 63             Write(x3);
 64         }
 65         public void Write(long x)
 66         {
 67             Write(cast<ulong>(x));
 68         }
 69         public void Write(ulong x)
 70         {
 71             byte x0 = cast<byte>(x >> 56u);
 72             byte x1 = cast<byte>(x >> 48u);
 73             byte x2 = cast<byte>(x >> 40u);
 74             byte x3 = cast<byte>(x >> 32u);
 75             byte x4 = cast<byte>(x >> 24u);
 76             byte x5 = cast<byte>(x >> 16u);
 77             byte x6 = cast<byte>(x >> 8u);
 78             byte x7 = cast<byte>(x);
 79             Write(x0);
 80             Write(x1);
 81             Write(x2);
 82             Write(x3);
 83             Write(x4);
 84             Write(x5);
 85             Write(x6);
 86             Write(x7);
 87         }
 88         public void Write(float x)
 89         {
 90             void* v = &x;
 91             uint* u = cast<uint*>(v);
 92             Write(*u);
 93         }
 94         public void Write(double x)
 95         {
 96             void* v = &x;
 97             ulong* u = cast<ulong*>(v);
 98             Write(*u);
 99         }
100         public void WriteULEB128UInt(uint x)
101         {
102             do
103             {
104                 byte b = cast<byte>(x & 0x7Fu);
105                 x = x >> 7u;
106                 if (x != 0u)
107                 {
108                     b = b | 0x80u;
109                 }
110                 Write(b);
111             }
112             while (x != 0u);
113         }
114         public void WriteULEB128ULong(ulong x)
115         {
116             do
117             {
118                 byte b = cast<byte>(x & 0x7Fu);
119                 x = x >> 7u;
120                 if (x != 0u)
121                 {
122                     b = b | 0x80u;
123                 }
124                 Write(b);
125             }
126             while (x != 0u);
127         }
128         public void WriteSLEB128Int(int x)
129         {
130             bool more = true;
131             bool negative = x < 0;
132             while (more)
133             {
134                 byte b = cast<byte>(x & 0x7F);
135                 x = x >> 7;
136                 if (negative)
137                 {
138                     x = x | (~int(0) << (32 - 7));
139                 }
140                 if (x == 0 && (b & 0x40u) == 0u || x == -1 && (b & 0x40u) != 0u)
141                 {
142                     more = false;
143                 }
144                 else
145                 {
146                     b = b | 0x80u;
147                 }
148                 Write(b);
149             }
150         }
151         public void WriteSLEB128Long(long x)
152         {
153             bool more = true;
154             bool negative = x < 0;
155             while (more)
156             {
157                 byte b = cast<byte>(x & 0x7F);
158                 x = x >> 7;
159                 if (negative)
160                 {
161                     x = x | (~long(0) << (64 - 7));
162                 }
163                 if (x == 0 && (b & 0x40u) == 0u || x == -1 && (b & 0x40u) != 0u)
164                 {
165                     more = false;
166                 }
167                 else
168                 {
169                     b = b | 0x80u;
170                 }
171                 Write(b);
172             }
173         }
174         public void Write(const string& x)
175         {
176             for (char c : x)
177             {
178                 Write(c);
179             }
180             Write('\0');
181         }
182         public void Write(const wstring& x)
183         {
184             Write(ToUtf8(x));
185         }
186         public void Write(const ustring& x)
187         {
188             Write(ToUtf8(x));
189         }
190         public void Write(const Uuid& uuid)
191         {
192             for (byte b : uuid)
193             {
194                 Write(b);
195             }
196         }
197         public void Seek(long posOrigin origin)
198         {
199             stream->Seek(posorigin);
200         }
201         public long Tell()
202         {
203             return stream->Tell();
204         }
205         public nothrow const SharedPtr<Stream>& GetStream()
206         {
207             return stream;
208         }
209         private SharedPtr<Stream> stream;
210     }
211 }