1
1
import * as wasi from "./wasi_defs.js" ;
2
- import { File , Directory } from "./fs_core.js" ;
2
+ import { File , Directory , SyncOPFSFile , FileSystemSyncAccessHandle } from "./fs_core.js" ;
3
3
import { Fd } from "./fd.js" ;
4
4
5
5
declare var TextEncoder : {
@@ -102,6 +102,87 @@ export class OpenFile extends Fd {
102
102
}
103
103
}
104
104
105
+ export class OpenSyncOPFSFile extends Fd {
106
+ handle : FileSystemSyncAccessHandle ;
107
+ position : bigint = 0n ;
108
+
109
+ constructor ( file : SyncOPFSFile ) {
110
+ super ( ) ;
111
+ this . handle = file . handle ;
112
+ } ;
113
+
114
+ fd_fdstat_get ( ) : { ret : number ; fdstat : wasi . Fdstat | null } {
115
+ return { ret : 0 , fdstat : new wasi . Fdstat ( wasi . FILETYPE_REGULAR_FILE , 0 ) } ;
116
+ }
117
+
118
+ fd_filestat_get ( ) : { ret : number ; filestat : wasi . Filestat } {
119
+ return { ret : 0 , filestat : new wasi . Filestat ( wasi . FILETYPE_REGULAR_FILE , BigInt ( this . handle . getSize ( ) ) ) } ;
120
+ }
121
+
122
+ fd_read ( view8 : Uint8Array , iovs : Array < wasi . Iovec > ) : { ret : number , nread : number } {
123
+ let nread = 0 ;
124
+ for ( let iovec of iovs ) {
125
+ if ( this . position < this . handle . getSize ( ) ) {
126
+ let buf = new Uint8Array ( view8 . buffer , iovec . buf , iovec . buf_len ) ;
127
+ let n = this . handle . read ( buf , { at : Number ( this . position ) } ) ;
128
+ this . position += BigInt ( n ) ;
129
+ nread += n ;
130
+ } else {
131
+ break ;
132
+ }
133
+ }
134
+ return { ret : 0 , nread } ;
135
+ }
136
+
137
+ fd_seek ( offset : number | bigint , whence : number ) : { ret : number , offset : bigint } {
138
+ let calculated_offset : bigint ;
139
+ switch ( whence ) {
140
+ case wasi . WHENCE_SET :
141
+ calculated_offset = BigInt ( offset ) ;
142
+ break ;
143
+ case wasi . WHENCE_CUR :
144
+ calculated_offset = this . position + BigInt ( offset ) ;
145
+ break ;
146
+ case wasi . WHENCE_END :
147
+ calculated_offset = BigInt ( this . handle . getSize ( ) ) + BigInt ( offset ) ;
148
+ break ;
149
+ default :
150
+ return { ret : wasi . ERRNO_INVAL , offset : 0n } ;
151
+ }
152
+ if ( calculated_offset < 0 ) {
153
+ return { ret : wasi . ERRNO_INVAL , offset : 0n } ;
154
+ }
155
+ this . position = calculated_offset ;
156
+ return { ret : wasi . ERRNO_SUCCESS , offset : this . position } ;
157
+ }
158
+
159
+ fd_write ( view8 : Uint8Array , iovs : Array < wasi . Iovec > ) : { ret : number , nwritten : number } {
160
+ let nwritten = 0 ;
161
+ for ( let iovec of iovs ) {
162
+ let buf = new Uint8Array ( view8 . buffer , iovec . buf , iovec . buf_len ) ;
163
+ // don't need to extend file manually, just write
164
+ let n = this . handle . write ( buf , { at : Number ( this . position ) } ) ;
165
+ this . position += BigInt ( n ) ;
166
+ nwritten += n ;
167
+ }
168
+ return { ret : wasi . ERRNO_SUCCESS , nwritten } ;
169
+ }
170
+
171
+ fd_datasync ( ) : number {
172
+ this . handle . flush ( ) ;
173
+ return wasi . ERRNO_SUCCESS ;
174
+ }
175
+
176
+ fd_sync ( ) : number {
177
+ return this . fd_datasync ( ) ;
178
+ }
179
+
180
+ fd_close ( ) : number {
181
+ return wasi . ERRNO_SUCCESS ;
182
+ }
183
+
184
+ }
185
+
105
186
export class OpenDirectory extends Fd {
106
187
dir : Directory ;
107
188
@@ -174,15 +255,7 @@ export class OpenDirectory extends Fd {
174
255
// @ts -ignore
175
256
entry . truncate ( ) ;
176
257
}
177
- // FIXME handle this more elegantly
178
- if ( entry instanceof File ) {
179
- // @ts -ignore
180
- return { ret : 0 , fd_obj : new OpenFile ( entry ) } ;
181
- } else if ( entry instanceof Directory ) {
182
- return { ret : 0 , fd_obj : new OpenDirectory ( entry ) } ;
183
- } else {
184
- throw "dir entry neither file nor dir" ;
185
- }
258
+ return { ret : 0 , fd_obj : entry . open ( fd_flags ) } ;
186
259
}
187
260
188
261
path_create_directory ( path : string ) : number {
@@ -193,7 +266,7 @@ export class OpenDirectory extends Fd {
193
266
export class PreopenDirectory extends OpenDirectory {
194
267
prestat_name : Uint8Array ;
195
268
196
- constructor ( name : string , contents : { [ key : string ] : File | Directory } ) {
269
+ constructor ( name : string , contents : { [ key : string ] : File | Directory | SyncOPFSFile } ) {
197
270
super ( new Directory ( contents ) ) ;
198
271
this . prestat_name = new TextEncoder ( "utf-8" ) . encode ( name ) ;
199
272
}
0 commit comments