@@ -4,7 +4,7 @@ import type {BinaryJsonEncoder} from '../types';
44/**
55 * XDR (External Data Representation) binary encoder for basic value encoding.
66 * Implements XDR binary encoding according to RFC 4506.
7- *
7+ *
88 * Key XDR encoding principles:
99 * - All data types are aligned to 4-byte boundaries
1010 * - Multi-byte quantities are transmitted in big-endian byte order
@@ -40,10 +40,6 @@ export class XdrEncoder implements BinaryJsonEncoder {
4040 if ( value === null ) return this . writeVoid ( ) ;
4141 const constructor = value . constructor ;
4242 switch ( constructor ) {
43- case Object :
44- return this . writeObj ( value as Record < string , unknown > ) ;
45- case Array :
46- return this . writeArr ( value as unknown [ ] ) ;
4743 case Uint8Array :
4844 return this . writeBin ( value as Uint8Array ) ;
4945 default :
@@ -106,11 +102,11 @@ export class XdrEncoder implements BinaryJsonEncoder {
106102 public writeHyper ( hyper : number | bigint ) : void {
107103 const writer = this . writer ;
108104 writer . ensureCapacity ( 8 ) ;
109-
105+
110106 if ( typeof hyper === 'bigint' ) {
111107 // Convert bigint to two 32-bit values for big-endian encoding
112- const high = Number ( ( hyper >> BigInt ( 32 ) ) & BigInt ( 0xFFFFFFFF ) ) ;
113- const low = Number ( hyper & BigInt ( 0xFFFFFFFF ) ) ;
108+ const high = Number ( ( hyper >> BigInt ( 32 ) ) & BigInt ( 0xffffffff ) ) ;
109+ const low = Number ( hyper & BigInt ( 0xffffffff ) ) ;
114110 writer . view . setInt32 ( writer . x , high , false ) ; // high 32 bits
115111 writer . view . setUint32 ( writer . x + 4 , low , false ) ; // low 32 bits
116112 } else {
@@ -129,11 +125,11 @@ export class XdrEncoder implements BinaryJsonEncoder {
129125 public writeUnsignedHyper ( uhyper : number | bigint ) : void {
130126 const writer = this . writer ;
131127 writer . ensureCapacity ( 8 ) ;
132-
128+
133129 if ( typeof uhyper === 'bigint' ) {
134130 // Convert bigint to two 32-bit values for big-endian encoding
135- const high = Number ( ( uhyper >> BigInt ( 32 ) ) & BigInt ( 0xFFFFFFFF ) ) ;
136- const low = Number ( uhyper & BigInt ( 0xFFFFFFFF ) ) ;
131+ const high = Number ( ( uhyper >> BigInt ( 32 ) ) & BigInt ( 0xffffffff ) ) ;
132+ const low = Number ( uhyper & BigInt ( 0xffffffff ) ) ;
137133 writer . view . setUint32 ( writer . x , high , false ) ; // high 32 bits
138134 writer . view . setUint32 ( writer . x + 4 , low , false ) ; // low 32 bits
139135 } else {
@@ -168,12 +164,10 @@ export class XdrEncoder implements BinaryJsonEncoder {
168164
169165 /**
170166 * Writes an XDR quadruple value (128-bit float).
171- * Note: JavaScript doesn't have native 128-bit float support, so this is a placeholder .
167+ * Note: JavaScript doesn't have native 128-bit float support.
172168 */
173169 public writeQuadruple ( quad : number ) : void {
174- // Write as two doubles for now (this is not standard XDR)
175- this . writeDouble ( quad ) ;
176- this . writeDouble ( 0 ) ; // padding
170+ throw new Error ( 'not implemented' ) ;
177171 }
178172
179173 /**
@@ -184,14 +178,14 @@ export class XdrEncoder implements BinaryJsonEncoder {
184178 if ( data . length !== size ) {
185179 throw new Error ( `Opaque data length ${ data . length } does not match expected size ${ size } ` ) ;
186180 }
187-
181+
188182 const writer = this . writer ;
189- const paddedSize = this . getPaddedSize ( size ) ;
183+ const paddedSize = Math . ceil ( size / 4 ) * 4 ;
190184 writer . ensureCapacity ( paddedSize ) ;
191-
185+
192186 // Write data
193187 writer . buf ( data , size ) ;
194-
188+
195189 // Write padding bytes
196190 const padding = paddedSize - size ;
197191 for ( let i = 0 ; i < padding ; i ++ ) {
@@ -205,14 +199,14 @@ export class XdrEncoder implements BinaryJsonEncoder {
205199 */
206200 public writeVarlenOpaque ( data : Uint8Array ) : void {
207201 this . writeUnsignedInt ( data . length ) ;
208-
202+
209203 const writer = this . writer ;
210- const paddedSize = this . getPaddedSize ( data . length ) ;
204+ const paddedSize = Math . ceil ( data . length / 4 ) * 4 ;
211205 writer . ensureCapacity ( paddedSize ) ;
212-
206+
213207 // Write data
214208 writer . buf ( data , data . length ) ;
215-
209+
216210 // Write padding bytes
217211 const padding = paddedSize - data . length ;
218212 for ( let i = 0 ; i < padding ; i ++ ) {
@@ -226,47 +220,32 @@ export class XdrEncoder implements BinaryJsonEncoder {
226220 */
227221 public writeStr ( str : string ) : void {
228222 const writer = this . writer ;
229- const encoder = new TextEncoder ( ) ;
230- const utf8Bytes = encoder . encode ( str ) ;
231-
232- // Write length
233- this . writeUnsignedInt ( utf8Bytes . length ) ;
234-
235- // Write string data with padding
236- const paddedSize = this . getPaddedSize ( utf8Bytes . length ) ;
237- writer . ensureCapacity ( paddedSize ) ;
238-
239- // Write UTF-8 bytes
240- writer . buf ( utf8Bytes , utf8Bytes . length ) ;
241-
242- // Write padding bytes
243- const padding = paddedSize - utf8Bytes . length ;
223+
224+ // Write string using writer's UTF-8 method and get actual byte count
225+ const lengthOffset = writer . x ;
226+ writer . x += 4 ; // Reserve space for length
227+ const bytesWritten = writer . utf8 ( str ) ;
228+
229+ // Calculate and write padding
230+ const paddedSize = Math . ceil ( bytesWritten / 4 ) * 4 ;
231+ const padding = paddedSize - bytesWritten ;
244232 for ( let i = 0 ; i < padding ; i ++ ) {
245233 writer . u8 ( 0 ) ;
246234 }
235+
236+ // Go back and write the actual byte length
237+ const currentPos = writer . x ;
238+ writer . x = lengthOffset ;
239+ this . writeUnsignedInt ( bytesWritten ) ;
240+ writer . x = currentPos ;
247241 }
248242
249- /**
250- * Writes XDR variable-length array.
251- * Length is written first, followed by array elements.
252- */
253243 public writeArr ( arr : unknown [ ] ) : void {
254- this . writeUnsignedInt ( arr . length ) ;
255- for ( const item of arr ) {
256- this . writeAny ( item ) ;
257- }
244+ throw new Error ( 'writeArr not implemented in XDR encoder' ) ;
258245 }
259246
260- /**
261- * Writes XDR structure as a simple mapping (not standard XDR, for compatibility).
262- */
263247 public writeObj ( obj : Record < string , unknown > ) : void {
264- const entries = Object . entries ( obj ) ;
265- this . writeUnsignedInt ( entries . length ) ;
266- for ( const [ key , value ] of entries ) {
267- this . writeStr ( key ) ;
268- this . writeAny ( value ) ;
269- }
248+ throw new Error ( 'writeObj not implemented in XDR encoder' ) ;
270249 }
271250
272251 // BinaryJsonEncoder interface methods
@@ -313,11 +292,4 @@ export class XdrEncoder implements BinaryJsonEncoder {
313292 public writeAsciiStr ( str : string ) : void {
314293 this . writeStr ( str ) ;
315294 }
316-
317- /**
318- * Calculates the padded size for 4-byte alignment.
319- */
320- private getPaddedSize ( size : number ) : number {
321- return Math . ceil ( size / 4 ) * 4 ;
322- }
323- }
295+ }
0 commit comments