Menu

[8dce06]: / joe / vfile.h  Maximize  Restore  History

Download this file

380 lines (306 with data), 9.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
/*
* Software virtual memory system
* Copyright
* (C) 1992 Joseph H. Allen
*
* This file is part of JOE (Joe's Own Editor)
*/
/* Page header */
struct vpage {
VPAGE *next; /* Next page with same hash value */
VFILE *vfile; /* Owner vfile */
off_t addr; /* Address of this page */
int count; /* Reference count */
int dirty; /* Set if page changed */
char *data; /* The data in the page */
};
/* File structure */
struct vfile {
LINK(VFILE) link; /* Doubly linked list of vfiles */
off_t size; /* Number of bytes in physical file */
off_t alloc; /* Number of bytes allocated to file */
int fd; /* Physical file */
int writeable; /* Set if we can write */
char *name; /* File name. 0 if unnamed */
int flags; /* Set if this is only a temporary file */
/* For array I/O */
char *vpage1; /* Page address */
off_t addr; /* File address of above page */
/* For stream I/O */
char *bufp; /* Buffer pointer */
char *vpage; /* Buffer pointer points in here */
ptrdiff_t left; /* Space left in bufp */
ptrdiff_t lv; /* Amount of append space at end of buffer */
};
/* Additions:
*
* Should we remove size checking from rc()? Would make it faster...
*
* Should be able to open more than one stream on a file so that vseek
* doesn't have to get called so much when more than one user is involed
*
* Also should have dupopen call to make more streams for a file
*
* Make vputs faster
*
* Should have a version which will use memory mapped files, if they exist
* in the os.
*
* Would be nice if we could transparantly open non-file streams and pipes.
* Should there be an buffering option for that? So we can seek on pipes to
* get previously read data?
*/
extern char *vbase; /* Data first entry in vheader refers to */
extern VPAGE **vheaders; /* Array of headers */
/* VFILE *vtmp(V);
*
* Open a temporary virtual file. File goes away when closed. No actual
* file is generated if everything fits in memory.
*/
VFILE *vtmp(void);
#ifdef junk
/* VFILE *vopen(char *name);
*
* Open a file for reading and if possible, writing. If the file could not
* be opened, NULL is returned.
*/
VFILE *vopen();
#endif
/* off_t vsize(VFILE *);
*
* Return size of file
*/
#define vsize(vfile) \
( \
(vfile)->left<(vfile)->lv ? \
(vfile)->alloc+(vfile)->lv-(vfile)->left \
: \
(vfile)->alloc \
)
/* void vclose(VFILE *vfile);
*
* Close a file.
*/
void vclose(VFILE *vfile);
#ifdef junk
/* void vlimit(long amount);
*
* Set limit (in bytes) on amount of memory the virtual file system may
* use. This limit can be exceeded if all existing vpages are being referenced
* and a new vpage is requested.
*
* When vlimit is called, the limit is immediatly enforced by elimiting
* non-referenced vpages.
*/
void vlimit();
#endif
/* void vflsh(void);
*
* Write all changed pages to the disk
*/
void vflsh(void);
/* void vflshf(VFILE *vfile);
*
* Write changed pages for a specific file to the disk
*/
void vflshf(VFILE *vfile);
/* char *vlock(VFILE *vfile,off_t addr);
*
* Translate virtual address to physical address. 'addr' does not have
* to be on any particular alignment, but if you wish to access more than
* a single byte, you have to be aware of where page boundaries are (virtual
* address multiples of PGSIZE).
*
* The page containing the data is locked in memory (so that it won't be
* freed or used for something else) until 'vunlock' is used.
*
* Warning: If you allocate more than one page and use (change) them out of
* order, vflsh will screw up if writing past the end of a file is illegal
* in the host filesystem.
*
* Also: This function does not allocate space to the file. Use valloc()
* for that. You can vlock() pages past the allocated size of the file, but
* be careful when you do this (you normally shouldn't- the only time you
* ever might want to is to implement your own version of valloc()).
*/
char *vlock(VFILE *vfile, off_t addr);
/* VPAGE *vheader(char *);
* Return address of page header for given page
*/
#define vheader(p) (vheaders[(physical((char *)(p))-physical(vbase))>>LPGSIZE])
/* void vchanged(char *);
*
* Indicate that a vpage was changed so that it will be written back to the
* file. Any physical address which falls within the page may be given.
*/
#define vchanged(vpage) ( vheader(vpage)->dirty=1 )
/* void vunlock(char *);
* Unreference a vpage (call one vunlock for every vlock)
* Any physical address which falls within the page may be given.
*/
#define vunlock(vpage) ( --vheader(vpage)->count )
/* void vupcount(char *);
* Indicate that another reference is being made to a vpage
*/
#define vupcount(vpage) ( ++vheader(vpage)->count )
/* long valloc(VFILE *vfile,long size);
*
* Allocate space at end of file
*
* Returns file address of beginning of allocated space
*/
off_t my_valloc(VFILE *vfile, off_t size);
#ifdef junk
/******************************************************************************
* The folloing functions implement stream I/O on top of the above software *
* virtual memory system *
******************************************************************************/
/* void vseek(VFILE *vfile,long addr);
*
* Seek to a file address. Allocates space to the file if you seek past the
* end.
*/
void vseek();
/* int vrgetc(VFILE *);
* int vgetc(VFILE *);
*
* Get next character / Get previous character functions.
* They return NO_MORE_DATA for end of file / beginning of file.
*/
int _vgetc();
int _vrgetc();
#define vrgetc(v) \
( (v)->left!=PGSIZE ? ( ++(v)->left, (int)(unsigned char)*(--(v)->bufp) ) : _vrgetc(v) )
#define vgetc(v) \
( (v)->left>(v)->lv ? ( --(v)->left, (int)(unsigned char)*((v)->bufp++) ) : _vgetc(v) )
/* int vputc(VFILE *,I);
*
* Put character. Returns character which is written.
*/
int _vputc();
#define vputc(v,c) \
( \
(v)->left ? \
( \
--(v)->left, \
vchanged((v)->vpage), \
(int)(unsigned char)(*((v)->bufp++)=(c)) \
) \
: \
_vputc((v),(c)) \
)
/* long vtell(VFILE *);
*
* Return current file position
*/
#define vtell(v) \
( \
(v)->vpage ? \
( vheader((v)->vpage)->addr+(v)->bufp-(v)->vpage ) \
: \
0L \
)
/* long vgetl(VFILE *);
*
* Get long. No alignment requirements. Returns -1 if goes past end of file.
*/
long vgetl();
/* short vgetw(VFILE *);
*
* Get short. No alignment requirements. Returns -1 if goes past end of file.
*/
short vgetw();
/* long vputl(VFILE *,long);
*
* Put long. No alignment requirements.
* Returns value written.
*/
long vputl();
/* short vputw(VFILE *,short);
*
* Put long. No alignement requirements.
* Returns value written.
*/
short vputw();
/* char *vgets(VFILE *v,char *s);
*
* Read up to next '\n' or end of file into a variable length string. If 's'
* is 0, a new string is created. The \n is not copied into the string.
*
* Eliminates the variable length string and returns NULL if
* vgets is called on the end of the file.
*
* This requires that you use the 'vs.h' / 'vs.c' library.
*/
char *vgets();
/* void vputs(VFILE *v,char *s);
*
* Write zero terminated string. \n is not appended */
void vputs();
/* void vread(VFILE *,char *,int size);
*
* Read bytes from a virtual file into a local data block
*/
void vread();
/* void vwrite(VFILE *,char *,int size);
*
* Write bytes from a local data block into a virtual file
*/
void vwrite();
/***************************************************************************
* The following functions implement array I/O on top of the above virtual *
* memory system (cheap memory mapped files) *
***************************************************************************/
/* int rc(VFILE *vfile,long addr);
*
* Read character. Returns NO_MORE_DATA if past end of file.
*/
int _rc();
#define rc(v,a) \
( \
(a)>=vsize(v) ? NO_MORE_DATA : \
( \
(v)->addr==((a)&~(PGSIZE-1)) ? \
(v)->vpage1[(a)&(PGSIZE-1)] \
: \
_rc((v),(a)) \
) \
)
/* int wc(VFILE *vfile,long addr,char c);
*
* Write character. Return character written. This automatically allocates
* space to the file.
*/
int _wc();
#define wc(v,a,c) \
( \
(v)->addr==((a)&~(PGSIZE-1)) ? \
( \
vheader((v)->vpage1)->dirty=1, \
((a)+1>vsize(v) && my_valloc(v,(a)+1-vsize(v))), \
(v)->vpage1[(a)&(PGSIZE-1)]=(c) \
) \
: \
_wc((v),(a),(c)) \
)
/* long rl(VFILE *vfile,long addr);
* Read big-endian long. No alignment requirements. Returns -1 if goes past
* end of file.
*/
long rl();
/* long wl(VFILE *vfile,long addr,long c);
* Write big-endian long. No alignment requirements. Automatically expands
* file if necessary.
*/
long wl();
/* short rw(VFILE *vfile,long addr);
* Read big-endian short. No alignment requirements. Returns -1 if goes past
* end of file.
*/
short rw();
/* short ww(VFILE *vfile,long addr,short c);
* Write big-endian short. No alignment requirements. Automatically expands
* file if necessary.
*/
short ww();
#endif /* junk */
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.