@@ -243,6 +243,25 @@ function parseFileInfo(r: UnparsedFileInfo): FileInfo {
243
243
}
244
244
}
245
245
246
+ // https://mstn.github.io/2018/06/08/fixed-size-arrays-in-typescript/
247
+ type FixedSizeArray < T , N extends number > = ReadonlyArray < T > & {
248
+ length : N
249
+ }
250
+
251
+ // https://gist.github.com/zapthedingbat/38ebfbedd98396624e5b5f2ff462611d
252
+ /** Converts a big-endian eight byte array to number */
253
+ function fromBytes ( buffer : FixedSizeArray < number , 8 > ) : number {
254
+ const bytes = new Uint8ClampedArray ( buffer )
255
+ const size = bytes . byteLength
256
+ let x = 0
257
+ for ( let i = 0 ; i < size ; i ++ ) {
258
+ const byte = bytes [ i ]
259
+ x *= 0x100
260
+ x += byte
261
+ }
262
+ return x
263
+ }
264
+
246
265
/**
247
266
* The Tauri abstraction for reading and writing files.
248
267
*
@@ -285,12 +304,20 @@ class FileHandle extends Resource {
285
304
return 0
286
305
}
287
306
288
- const [ data , nread ] = await invoke < [ number [ ] , number ] > ( 'plugin:fs|read' , {
307
+ const data = await invoke < ArrayBuffer | number [ ] > ( 'plugin:fs|read' , {
289
308
rid : this . rid ,
290
309
len : buffer . byteLength
291
310
} )
292
311
293
- buffer . set ( data )
312
+ // Rust side will never return an empty array for this command and
313
+ // ensure there is at least 8 elements there.
314
+ //
315
+ // This is an optimization to include the number of read bytes (as bigendian bytes)
316
+ // at the end of returned array to avoid serialization overhead of separate values.
317
+ const nread = fromBytes ( data . slice ( - 8 ) as FixedSizeArray < number , 8 > )
318
+
319
+ const bytes = data instanceof ArrayBuffer ? new Uint8Array ( data ) : data
320
+ buffer . set ( bytes . slice ( 0 , bytes . length - 8 ) )
294
321
295
322
return nread === 0 ? null : nread
296
323
}
@@ -1041,10 +1068,13 @@ async function writeTextFile(
1041
1068
throw new TypeError ( 'Must be a file URL.' )
1042
1069
}
1043
1070
1044
- await invoke ( 'plugin:fs|write_text_file' , {
1045
- path : path instanceof URL ? path . toString ( ) : path ,
1046
- data,
1047
- options
1071
+ const encoder = new TextEncoder ( )
1072
+
1073
+ await invoke ( 'plugin:fs|write_text_file' , encoder . encode ( data ) , {
1074
+ headers : {
1075
+ path : path instanceof URL ? path . toString ( ) : path ,
1076
+ options : JSON . stringify ( options )
1077
+ }
1048
1078
} )
1049
1079
}
1050
1080
0 commit comments