1+ import  *  as  bigInt  from  'big-integer' ; 
2+ import  { Encoding }  from  "./Encoding" ; 
3+ import  { writeUtf8StringFromCodePoints }  from  "./Utf8" ; 
4+ 
5+ export  class  BinaryWriter 
6+ { 
7+ private  _stream : number [ ] ; 
8+ private  _position : number ; 
9+ 
10+ public  constructor ( ) 
11+ { 
12+ this . _stream  =  [ ] ; 
13+ this . _position  =  0 ; 
14+ } 
15+ 
16+ public  writeBoolean ( value : boolean ) : void 
17+ { 
18+ this . writeBytes ( value  ? 1  : 0 ) ; 
19+ } 
20+ 
21+ public  writeByte ( value : number ) : void 
22+ { 
23+ this . _stream [ this . _position ++ ]  =  value ; 
24+ } 
25+ 
26+ public  writeSignedByte ( value : number ) : void 
27+ { 
28+ this . _stream [ this . _position ++ ]  =  value  <  0  ? value  +  256  : value ; 
29+ } 
30+ 
31+ public  writeShort ( value : number ) : void 
32+ { 
33+ this . _stream [ this . _position ++ ]  =  value  &  0xFF ; 
34+ this . _stream [ this . _position ++ ]  =  ( value  >>  8  &  0xFF ) ; 
35+ } 
36+ 
37+ public  writeUnsignedShort ( value : number ) : void 
38+ { 
39+ this . _stream [ this . _position ++ ]  =  value  &  0xFF ; 
40+ this . _stream [ this . _position ++ ]  =  ( value  >>  8  &  0xFF ) ; 
41+ } 
42+ 
43+ public  writeInt ( value : number ) : void 
44+ { 
45+ this . _stream [ this . _position ++ ]  =  value  &  0xFF ; 
46+ this . _stream [ this . _position ++ ]  =  ( value  >>  8  &  0xFF ) ; 
47+ this . _stream [ this . _position ++ ]  =  ( value  >>  16  &  0xFF ) ; 
48+ this . _stream [ this . _position ++ ]  =  ( value  >>  24  &  0xFF ) ; 
49+ } 
50+ 
51+ public  writeUnsignedInt ( value : number ) : void 
52+ { 
53+ this . _stream [ this . _position ++ ]  =  value  &  0xFF ; 
54+ this . _stream [ this . _position ++ ]  =  ( value  >>  8  &  0xFF ) ; 
55+ this . _stream [ this . _position ++ ]  =  ( value  >>  16  &  0xFF ) ; 
56+ this . _stream [ this . _position ++ ]  =  ( value  >>  24  &  0xFF ) ; 
57+ } 
58+ 
59+ public  writeLong ( value : number  |  string ) : void 
60+ { 
61+ const  bigint  =  typeof  value  ===  "number" 
62+ ? bigInt ( value ) 
63+ : bigInt ( value ) ; 
64+ 
65+ const  leftHalf  =  bigint . and ( 0xFFFFFFFF ) . toJSNumber ( ) ; 
66+ const  rightHalf  =  bigint . shiftRight ( 32 ) . and ( 0xFFFFFFFF ) . toJSNumber ( ) ; 
67+ 
68+ this . _stream [ this . _position ++ ]  =  leftHalf  &  0xFF ; 
69+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  8  &  0xFF ) ; 
70+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  16  &  0xFF ) ; 
71+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  24  &  0xFF ) ; 
72+ 
73+ this . _stream [ this . _position ++ ]  =  rightHalf  &  0xFF ; 
74+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  8  &  0xFF ) ; 
75+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  16  &  0xFF ) ; 
76+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  24  &  0xFF ) ; 
77+ } 
78+ 
79+ public  writeUnsignedLong ( value : number  |  string ) : void 
80+ { 
81+ const  bigint  =  typeof  value  ===  "number" 
82+ ? bigInt ( value ) 
83+ : bigInt ( value ) ; 
84+ 
85+ const  leftHalf  =  bigint . and ( 0xFFFFFFFF ) . toJSNumber ( ) ; 
86+ const  rightHalf  =  bigint . shiftRight ( 32 ) . and ( 0xFFFFFFFF ) . toJSNumber ( ) ; 
87+ 
88+ this . _stream [ this . _position ++ ]  =  leftHalf  &  0xFF ; 
89+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  8  &  0xFF ) ; 
90+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  16  &  0xFF ) ; 
91+ this . _stream [ this . _position ++ ]  =  ( leftHalf  >>  24  &  0xFF ) ; 
92+ 
93+ this . _stream [ this . _position ++ ]  =  rightHalf  &  0xFF ; 
94+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  8  &  0xFF ) ; 
95+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  16  &  0xFF ) ; 
96+ this . _stream [ this . _position ++ ]  =  ( rightHalf  >>  24  &  0xFF ) ; 
97+ } 
98+ 
99+ public  writeFloat ( value : number ) : void 
100+ { 
101+ if  ( Number . isNaN ( value ) )  { 
102+ this . _stream [ this . _position ++ ]  =  0x00 ; 
103+ this . _stream [ this . _position ++ ]  =  0x00 ; 
104+ this . _stream [ this . _position ++ ]  =  0xc0 ; 
105+ this . _stream [ this . _position ++ ]  =  0xff ; 
106+ return ; 
107+ } 
108+ 
109+ const  floatBuffer  =  new  Float32Array ( [ value ] ) ; 
110+ const  uintBuffer  =  new  Uint8Array ( floatBuffer . buffer ,  floatBuffer . byteOffset ,  4 ) ; 
111+ 
112+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 0 ] ; 
113+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 1 ] ; 
114+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 2 ] ; 
115+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 3 ] ; 
116+ } 
117+ 
118+ public  writeDouble ( value : number ) : void 
119+ { 
120+ if  ( Number . isNaN ( value ) )  { 
121+ this . _stream [ this . _position ++ ]  =  0x00 ; 
122+ this . _stream [ this . _position ++ ]  =  0x00 ; 
123+ this . _stream [ this . _position ++ ]  =  0x00 ; 
124+ this . _stream [ this . _position ++ ]  =  0x00 ; 
125+ this . _stream [ this . _position ++ ]  =  0x00 ; 
126+ this . _stream [ this . _position ++ ]  =  0x00 ; 
127+ this . _stream [ this . _position ++ ]  =  0xf8 ; 
128+ this . _stream [ this . _position ++ ]  =  0xff ; 
129+ return ; 
130+ } 
131+ 
132+ const  floatBuffer  =  new  Float64Array ( [ value ] ) ; 
133+ const  uintBuffer  =  new  Uint8Array ( floatBuffer . buffer ,  floatBuffer . byteOffset ,  8 ) ; 
134+ 
135+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 0 ] ; 
136+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 1 ] ; 
137+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 2 ] ; 
138+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 3 ] ; 
139+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 4 ] ; 
140+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 5 ] ; 
141+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 6 ] ; 
142+ this . _stream [ this . _position ++ ]  =  uintBuffer [ 7 ] ; 
143+ } 
144+ 
145+ public  writeChar ( value : number  |  string ,  encoding : Encoding ) : void 
146+ { 
147+ this . _position  =  writeUtf8StringFromCodePoints ( this . _stream ,  this . _position ,  typeof  value  ===  "number"  ? [ value ]  : value ) ; 
148+ } 
149+ 
150+ public  writeChars ( value : number [ ]  |  string ,  encoding : Encoding ) : void 
151+ { 
152+ this . _position  =  writeUtf8StringFromCodePoints ( this . _stream ,  this . _position ,  value ) ; 
153+ } 
154+ 
155+ public  writeString ( value : number [ ]  |  string ,  encoding : Encoding ) : void 
156+ { 
157+ const  tempBuffer : number [ ]  =  [ ] ; 
158+ writeUtf8StringFromCodePoints ( tempBuffer ,  0 ,  value ) ; 
159+ 
160+ let  length  =  tempBuffer . length ; 
161+ while  ( length  >=  0x80 )  { 
162+ this . _stream [ this . _position ++ ]  =  ( length  &  0xFF )  |  0x80 ; 
163+ length  >>=  7 ; 
164+ } 
165+ this . _stream [ this . _position ++ ]  =  length ; 
166+ 
167+ for ( let  i  =  0 ;  i  <  tempBuffer . length ;  i ++ )  { 
168+ this . _stream [ this . _position ++ ]  =  tempBuffer [ i ] ; 
169+ } 
170+ } 
171+ 
172+ public  clear ( ) : void 
173+ { 
174+ this . _position  =  0 ; 
175+ this . _stream . length  =  0 ; 
176+ } 
177+ 
178+ public  toArray ( ) : number [ ] 
179+ { 
180+ return  this . _stream . concat ( ) ; 
181+ } 
182+ 
183+ private  writeBytes ( ...bytes : number [ ] ) : void 
184+ { 
185+ for ( let  i  =  0 ;  i  <  bytes . length ;  i ++ )  { 
186+ this . _stream [ this . _position ++ ]  =  bytes [ i ] ; 
187+ } 
188+ } 
189+ } 
0 commit comments