(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             #define MAXFILES 10
 11             #define MAXHANDLES 10
 12             #define MAXFNAME 255
 13             #define MAXFLEN 65536
 14             
 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                 
122                 handler = malloc(sizeof(struct tvfs_fcb));
123                 handler->inode = inode;
124                 handler->pos=0;
125                 h = nfiles++;
126                 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 rizwank 1.4 
159 rizwank 1.8     int inode;
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                 
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             }
174 rizwank 1.2 
175 rizwank 1.4 /* Compare given file with given contents, return 0 on equal, else nonzero */
176 rizwank 1.8 int tvfs_compare(const char *fname, const char *buf, int len)
177             {
178                 
179                 int inode;
180             
181                 #ifdef TVFS_DEBUG
182                 trace("tvfs_compare called with %s, %d, %d\n", fname, buf, len);
183                 #endif 
184                 
185                 for (inode=0; inode<nfiles; inode++) {
186                     if (!files[inode])
187                         continue;
188                     if (!strcmp(files[inode]->fname, fname))
189                     break;
190                 }    
191 rizwank 1.7     if (inode == nfiles) {
192 rizwank 1.8         /* File did not exist */
193                     #ifdef TVFS_DEBUG
194                     trace("tvfs_compare returning -1 (FAILURE)\n");
195                     #endif 
196 rizwank 1.7         return -1;
197                 }
198             
199 rizwank 1.8     return (memcmp(files[inode]->buf,buf,len));
200                 /* doesnt check for out of bound */
201 rizwank 1.4 }
202 rizwank 1.2 
203 rizwank 1.8 long tvfs_lseek(int h, long whence, int whither )
204             {
205 rizwank 1.2 
206 rizwank 1.8     int inode = handles[h]->inode;
207                 int size = files[inode]->bytes_used;  
208                 #ifdef TVFS_DEBUG
209                 trace("tvfs_lseek called with %d, %d, %d\n", h, whither, whence);
210                 #endif   
211                 
212             /*  if (whence > size) 
213                 whence = size;*/
214             /*  Legit lseek does NOT do boundry checking */    
215                 
216                 switch(whither) {
217                 case SEEK_SET: {
218                 handles[h]->pos = whence;
219                 break;
220                 }
221                 case SEEK_CUR: {
222                 handles[h]->pos += whence;
223                 break;
224                 }
225                 case SEEK_END: {
226                 handles[h]->pos = size+whence;
227 rizwank 1.8     break;
228                 }
229                 case 5: {
230                 handles[h]->pos = size+whence;
231                 break;
232                 }    
233                 case 44: {
234                 handles[h]->pos = size+whence;
235                 break;
236                 }    
237                 default:
238                 {
239                 trace("lseek was called with an invalid whither %d\n",whither);
240                 return -1;
241                 }
242                 }
243                 return handles[h]->pos;
244 rizwank 1.4   }
245             
246             int tvfs_close(int h){
247 rizwank 1.8     int inode = handles[h]->inode;
248                 #ifdef TVFS_DEBUG
249                 trace("tvfs_close called with %d\n", h);
250                 #endif 
251                 if (!files[inode]){
252                 return -1;
253                 }
254                 free(handles[h]);
255                 /* Currently does NOT enabled open to reuse this handle */
256                 return 0;
257 rizwank 1.4  }
258              
259             unsigned int tvfs_write(int h, void *buf, unsigned int len)
260             {
261 rizwank 1.8     
262                 int inode = handles[h]->inode;
263                 int pos = handles[h]->pos;
264                 #ifdef TVFS_DEBUG
265                 trace("tvfs_write called with %d, %d, %d\n", h, buf, len);
266                 #endif    
267                 memcpy(files[inode]->buf+pos, buf, len);
268                 files[inode]->bytes_used += len;
269                 
270                 return len;
271                 /* return -1 to simulate diskfull or some other error */
272 rizwank 1.4 }
273 rizwank 1.8     
274                 
275                 
276 rizwank 1.4   
277 rizwank 1.2 
278             #ifdef TVFS_MAIN
279 rizwank 1.4 
280 rizwank 1.3 const static char name_test_txt[] = "test.txt";
281             const static char file_test_txt[] = "This is a test. Don't Panic!";
282 rizwank 1.4 const static int size_test_txt = sizeof(file_test_txt);
283 rizwank 1.2 
284             main(){
285 rizwank 1.8     int result;
286                 int active_handler;
287 rizwank 1.2 
288 rizwank 1.8     char *filebuf;
289                 
290                 char dummy_filename[] = "dummy.txt";
291                 char bad_filename[] = "chicken.txt";
292             
293                 filebuf = malloc(MAXFLEN);
294                 
295                 printf("Testing TVFS implementation, creating %s\n",name_test_txt);
296                 result = tvfs_create( dummy_filename, file_test_txt, size_test_txt);
297                 result = tvfs_create( name_test_txt, file_test_txt,size_test_txt); 
298                 printf("Created virtual file with inode %d\n",result);
299                 
300                 printf("Attempting to open non-existant file\n");
301                 result = tvfs_open(bad_filename, _O_BINARY, 0 ); 
302                 printf("Result code %d\n",result); 
303                 printf("Attempting to open existant file\n");    
304                 result = tvfs_open(name_test_txt, _O_BINARY, 0 );
305                 printf("Result code %d\n",result); 
306             
307                 active_handler = result;
308             
309 rizwank 1.8     memset (filebuf,0,MAXFLEN);
310             
311                 printf("Testing reading from file %s\n",name_test_txt);
312                 result = tvfs_read(active_handler, filebuf, 9);
313                 printf("Read _%s_\n", filebuf);
314                 if ( strcmp(filebuf,"This is a")) 
315                 printf("File read check failed!\n");    
316             
317                 printf("Testing sequential reading from file %s\n",name_test_txt);
318                 result = tvfs_read(active_handler, filebuf, 12);
319                 printf("Read _%s_\n", filebuf);
320                 if ( strcmp(filebuf," test. Don't")) 
321                 printf("File read check failed!\n");
322                 
323                 printf("Testing edge reading from file %s\n",name_test_txt);
324                 result = tvfs_read(active_handler, filebuf, 42);
325                 printf("Read %d bytes - _%s_\n", result, filebuf);
326                 if ( result != 8 ) 
327                 printf("File read check failed!\n");
328                 
329                 printf("Testing direct file compare and lseek of %s\n", name_test_txt);
330 rizwank 1.8     printf("Seeking to 0 (not needed) - ");
331                 tvfs_lseek( active_handler, SEEK_SET, 0);
332                 printf("Comparing file\n");
333                 result = tvfs_compare( name_test_txt , file_test_txt, size_test_txt);
334                 if (result)
335                 printf ("File compare failed!\n"); 
336             
337                 
338                 printf("Closing %s\n",name_test_txt);
339                 tvfs_close(active_handler);
340                 if (result)
341                 printf ("File close failed!\n");
342                 
343                 tvfs_free();
344                 free(filebuf);
345                 
346 rizwank 1.2 }
347             
348             #endif

Rizwan Kassim
Powered by
ViewCVS 0.9.2