(file) Return to tvfs.c CVS log (file) (dir) Up to [RizwankCVS] / group3 / wine / dlls / cabinet / tests

  1 rizwank 1.1 /*--------------------------------------------------------------------------
  2             Trivial virtual file system for cabinet conformance test.
  3 rizwank 1.2 (C) 2005 Dan Kegel and Rizwan Kassim
  4             LGPL License
  5 rizwank 1.1 --------------------------------------------------------------------------*/
  6             
  7             #include "tvfs.h"
  8             #include <string.h>
  9             
 10 rizwank 1.9 #define MAXFILES 20
 11             #define MAXHANDLES 20
 12 rizwank 1.1 #define MAXFNAME 255
 13 rizwank 1.9 #define MAXFLEN 65536*2
 14 rizwank 1.1 
 15 rizwank 1.4 #include <fcntl.h>
 16 rizwank 1.7 #include <stdlib.h> 
 17 rizwank 1.4 #include <stdio.h>
 18             #include <malloc.h>
 19 rizwank 1.8 #include <stdio.h>
 20             #include <stdarg.h>
 21             
 22 rizwank 1.7 /*
 23 rizwank 1.8 #define TVFS_MAIN 
 24             #define TVFS_DEBUG
 25 rizwank 1.7 */
 26 rizwank 1.8 
 27 rizwank 1.4 #define SEEK_SET 0
 28             #define SEEK_CUR 1
 29             #define SEEK_END 2
 30 rizwank 1.2 
 31 rizwank 1.8 #ifndef _O_BINARY
 32             #define _O_BINARY 0
 33             #endif
 34             
 35             #ifndef STANDALONE
 36             #else
 37             static void trace(const char *s, ...)
 38             {
 39                 va_list elipsis;
 40                 va_start (elipsis, s);
 41                 vprintf(s, elipsis);
 42                 va_end(elipsis);
 43             }
 44             #endif 
 45             
 46 rizwank 1.1 struct tvfs_file {
 47 rizwank 1.8     char fname[MAXFNAME];
 48                 int bytes_used;
 49                 char buf[MAXFLEN];
 50 rizwank 1.1 };
 51             static struct tvfs_file *files[MAXFILES];
 52             
 53             struct tvfs_fcb {
 54 rizwank 1.8     int pos;
 55                 int inode;
 56 rizwank 1.1 };
 57             static struct tvfs_fcb *handles[MAXHANDLES];
 58 rizwank 1.8 
 59 rizwank 1.1 int nhandles = 0;
 60 rizwank 1.8 int nfiles = 0;
 61 rizwank 1.1 
 62 rizwank 1.2 /* tvfs_create does NOT correspond to _creat - it is an internal function
 63             use to put a file directly into our virtual filesystem. */
 64             
 65 rizwank 1.1 int tvfs_create(const char *fname, const char *buf, int len)
 66             {
 67 rizwank 1.8     int inode;
 68                 struct tvfs_file *f;
 69             
 70                 #ifdef TVFS_DEBUG
 71                 trace("tvfs_create called with %s, %d, %d\n", fname, buf, len);
 72                 #endif 
 73                 
 74                 if (nfiles >= MAXFILES)
 75                     return -1;
 76                 inode = nfiles++;
 77 rizwank 1.4 
 78 rizwank 1.8     f = malloc(sizeof(struct tvfs_file));
 79                 strcpy(f->fname, fname);
 80                 f->bytes_used = len;
 81             
 82                 if (buf)
 83                     memcpy(f->buf, buf, len);
 84                 
 85                 files[inode] = f;
 86                 return inode;
 87 rizwank 1.1 }
 88             
 89             int tvfs_open(const char *fname, int flags, int mode)
 90             {
 91 rizwank 1.4 
 92 rizwank 1.8     /* mode and flags are not handled */
 93                 int h;
 94                 int inode;
 95                 struct tvfs_fcb *handler;
 96                 
 97                 #ifdef TVFS_DEBUG
 98                 trace("tvfs_open called with %s, %d, %d\n", fname, flags, mode);
 99                 #endif 
100             
101                 /* Existing file? */
102                 for (inode=0; inode<nfiles; inode++) {
103                     if (!files[inode])
104                         continue;
105                     if (!strcmp(files[inode]->fname, fname))
106                         break;    
107                 }
108                 
109                 if (inode == nfiles) {
110                     /* File did not exist */
111                     if ((flags & O_CREAT) == 0) {
112                         /* ENOENT */
113 rizwank 1.8             #ifdef TVFS_DEBUG
114                         trace("tvfs_open returning -1\n");
115                         #endif 
116                     return -1;
117                     }
118             
119                     inode = tvfs_create(fname, 0, 0);
120                 }
121 rizwank 1.9 
122 rizwank 1.8     handler = malloc(sizeof(struct tvfs_fcb));
123                 handler->inode = inode;
124                 handler->pos=0;
125 rizwank 1.9     h = nhandles++;
126 rizwank 1.8     handles[h] = handler;
127                 
128                 #ifdef TVFS_DEBUG
129                 trace("tvfs_open returning with %d\n", h);
130                 #endif 
131                 
132                 return h;
133 rizwank 1.1 }
134 rizwank 1.2    
135 rizwank 1.1 unsigned int tvfs_read(int h, void *buf, unsigned int len)
136             {
137 rizwank 1.8     int inode = handles[h]->inode;
138                 int pos = handles[h]->pos;
139                 int size = files[inode]->bytes_used;
140             
141                 #ifdef TVFS_DEBUG
142                 trace("tvfs_read called with %d, %d, %d\n", h, buf, len);
143                 #endif  
144                 
145                 /* Edge Case 1 : Request beyond boundary of file */
146                 if (pos + len > size) {
147                     len = size-pos;
148                 }
149                 
150                 memcpy(buf, files[inode]->buf+pos, len);
151                 handles[h]->pos += len;
152 rizwank 1.1 
153 rizwank 1.8     return len;
154 rizwank 1.1 }
155 rizwank 1.2 
156 rizwank 1.8 void tvfs_free()
157             {
158                 int inode;
159 rizwank 1.9     int handle;
160 rizwank 1.4 
161 rizwank 1.8     #ifdef TVFS_DEBUG
162                 trace("tvfs_free\n");
163                 #endif 
164                 
165                 nfiles=0;
166                 nhandles=0;
167 rizwank 1.9 
168 rizwank 1.4     for (inode=0; inode<nfiles; inode++) {
169 rizwank 1.8         if (!files[inode])
170                         continue;
171                     free(files[inode]);
172                     }
173 rizwank 1.9 
174                 for (handle=0; handle<nhandles; handle++) {
175                     if (!handles[handle])
176                         continue;
177                     free(handles[handle]);
178                 }
179                 
180 rizwank 1.8 }
181 rizwank 1.2 
182 rizwank 1.4 /* Compare given file with given contents, return 0 on equal, else nonzero */
183 rizwank 1.8 int tvfs_compare(const char *fname, const char *buf, int len)
184             {
185                 
186                 int inode;
187             
188                 #ifdef TVFS_DEBUG
189                 trace("tvfs_compare called with %s, %d, %d\n", fname, buf, len);
190                 #endif 
191                 
192                 for (inode=0; inode<nfiles; inode++) {
193                     if (!files[inode])
194                         continue;
195                     if (!strcmp(files[inode]->fname, fname))
196                     break;
197                 }    
198 rizwank 1.9     
199 rizwank 1.7     if (inode == nfiles) {
200 rizwank 1.8         /* File did not exist */
201                     #ifdef TVFS_DEBUG
202                     trace("tvfs_compare returning -1 (FAILURE)\n");
203                     #endif 
204 rizwank 1.7         return -1;
205                 }
206             
207 rizwank 1.8     return (memcmp(files[inode]->buf,buf,len));
208                 /* doesnt check for out of bound */
209 rizwank 1.4 }
210 rizwank 1.2 
211 rizwank 1.8 long tvfs_lseek(int h, long whence, int whither )
212             {
213 rizwank 1.2 
214 rizwank 1.8     int inode = handles[h]->inode;
215                 int size = files[inode]->bytes_used;  
216                 #ifdef TVFS_DEBUG
217                 trace("tvfs_lseek called with %d, %d, %d\n", h, whither, whence);
218                 #endif   
219                 
220             /*  if (whence > size) 
221                 whence = size;*/
222             /*  Legit lseek does NOT do boundry checking */    
223                 
224                 switch(whither) {
225                 case SEEK_SET: {
226                 handles[h]->pos = whence;
227                 break;
228                 }
229                 case SEEK_CUR: {
230                 handles[h]->pos += whence;
231                 break;
232                 }
233                 case SEEK_END: {
234                 handles[h]->pos = size+whence;
235 rizwank 1.8     break;
236                 }
237                 case 5: {
238                 handles[h]->pos = size+whence;
239                 break;
240                 }    
241                 case 44: {
242                 handles[h]->pos = size+whence;
243                 break;
244                 }    
245                 default:
246                 {
247                 trace("lseek was called with an invalid whither %d\n",whither);
248                 return -1;
249                 }
250                 }
251                 return handles[h]->pos;
252 rizwank 1.4   }
253             
254             int tvfs_close(int h){
255 rizwank 1.8     int inode = handles[h]->inode;
256                 #ifdef TVFS_DEBUG
257                 trace("tvfs_close called with %d\n", h);
258                 #endif 
259                 if (!files[inode]){
260                 return -1;
261                 }
262                 free(handles[h]);
263                 /* Currently does NOT enabled open to reuse this handle */
264                 return 0;
265 rizwank 1.4  }
266              
267             unsigned int tvfs_write(int h, void *buf, unsigned int len)
268             {
269 rizwank 1.8     
270                 int inode = handles[h]->inode;
271                 int pos = handles[h]->pos;
272                 #ifdef TVFS_DEBUG
273                 trace("tvfs_write called with %d, %d, %d\n", h, buf, len);
274                 #endif    
275                 memcpy(files[inode]->buf+pos, buf, len);
276                 files[inode]->bytes_used += len;
277 rizwank 1.9     handles[h]->pos += len;
278              
279 rizwank 1.8     return len;
280                 /* return -1 to simulate diskfull or some other error */
281 rizwank 1.4 }
282 rizwank 1.8     
283                 
284                 
285 rizwank 1.4   
286 rizwank 1.2 
287             #ifdef TVFS_MAIN
288 rizwank 1.4 
289 rizwank 1.3 const static char name_test_txt[] = "test.txt";
290             const static char file_test_txt[] = "This is a test. Don't Panic!";
291 rizwank 1.4 const static int size_test_txt = sizeof(file_test_txt);
292 rizwank 1.2 
293             main(){
294 rizwank 1.8     int result;
295                 int active_handler;
296 rizwank 1.2 
297 rizwank 1.8     char *filebuf;
298                 
299                 char dummy_filename[] = "dummy.txt";
300                 char bad_filename[] = "chicken.txt";
301             
302                 filebuf = malloc(MAXFLEN);
303                 
304                 printf("Testing TVFS implementation, creating %s\n",name_test_txt);
305                 result = tvfs_create( dummy_filename, file_test_txt, size_test_txt);
306                 result = tvfs_create( name_test_txt, file_test_txt,size_test_txt); 
307                 printf("Created virtual file with inode %d\n",result);
308                 
309                 printf("Attempting to open non-existant file\n");
310                 result = tvfs_open(bad_filename, _O_BINARY, 0 ); 
311                 printf("Result code %d\n",result); 
312                 printf("Attempting to open existant file\n");    
313                 result = tvfs_open(name_test_txt, _O_BINARY, 0 );
314                 printf("Result code %d\n",result); 
315             
316                 active_handler = result;
317             
318 rizwank 1.8     memset (filebuf,0,MAXFLEN);
319             
320                 printf("Testing reading from file %s\n",name_test_txt);
321                 result = tvfs_read(active_handler, filebuf, 9);
322                 printf("Read _%s_\n", filebuf);
323                 if ( strcmp(filebuf,"This is a")) 
324                 printf("File read check failed!\n");    
325             
326                 printf("Testing sequential reading from file %s\n",name_test_txt);
327                 result = tvfs_read(active_handler, filebuf, 12);
328                 printf("Read _%s_\n", filebuf);
329                 if ( strcmp(filebuf," test. Don't")) 
330                 printf("File read check failed!\n");
331                 
332                 printf("Testing edge reading from file %s\n",name_test_txt);
333                 result = tvfs_read(active_handler, filebuf, 42);
334                 printf("Read %d bytes - _%s_\n", result, filebuf);
335                 if ( result != 8 ) 
336                 printf("File read check failed!\n");
337                 
338                 printf("Testing direct file compare and lseek of %s\n", name_test_txt);
339 rizwank 1.8     printf("Seeking to 0 (not needed) - ");
340                 tvfs_lseek( active_handler, SEEK_SET, 0);
341                 printf("Comparing file\n");
342                 result = tvfs_compare( name_test_txt , file_test_txt, size_test_txt);
343                 if (result)
344                 printf ("File compare failed!\n"); 
345             
346                 
347                 printf("Closing %s\n",name_test_txt);
348                 tvfs_close(active_handler);
349                 if (result)
350                 printf ("File close failed!\n");
351                 
352                 tvfs_free();
353                 free(filebuf);
354                 
355 rizwank 1.2 }
356             
357             #endif

Rizwan Kassim
Powered by
ViewCVS 0.9.2