(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 rizwank 1.10     va_list ellipsis;
 40                  va_start (ellipsis, s);
 41                  vprintf(s, ellipsis);
 42                  va_end(ellipsis);
 43 rizwank 1.8  }
 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 rizwank 1.10 use to put a file directly into our virtual file system. */
 64 rizwank 1.2  
 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 rizwank 1.10 #ifdef TVFS_DEBUG
 71 rizwank 1.8      trace("tvfs_create called with %s, %d, %d\n", fname, buf, len);
 72 rizwank 1.10 #endif 
 73 rizwank 1.8      
 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 rizwank 1.10 #ifdef TVFS_DEBUG
 98 rizwank 1.8      trace("tvfs_open called with %s, %d, %d\n", fname, flags, mode);
 99 rizwank 1.10 #endif 
100 rizwank 1.8  
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.10 #ifdef TVFS_DEBUG
114 rizwank 1.8              trace("tvfs_open returning -1\n");
115 rizwank 1.10 #endif 
116 rizwank 1.8          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 rizwank 1.10 #ifdef TVFS_DEBUG
129 rizwank 1.8      trace("tvfs_open returning with %d\n", h);
130 rizwank 1.10 #endif 
131 rizwank 1.8      
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 rizwank 1.10 #ifdef TVFS_DEBUG
142 rizwank 1.8      trace("tvfs_read called with %d, %d, %d\n", h, buf, len);
143 rizwank 1.10 #endif  
144 rizwank 1.8      
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.10 #ifdef TVFS_DEBUG
162 rizwank 1.8      trace("tvfs_free\n");
163 rizwank 1.10 #endif 
164 rizwank 1.8      
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 rizwank 1.10 #ifdef TVFS_DEBUG
189 rizwank 1.8      trace("tvfs_compare called with %s, %d, %d\n", fname, buf, len);
190 rizwank 1.10 #endif 
191 rizwank 1.8      
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 rizwank 1.10 #ifdef TVFS_DEBUG
202 rizwank 1.8          trace("tvfs_compare returning -1 (FAILURE)\n");
203 rizwank 1.10 #endif 
204 rizwank 1.7          return -1;
205                  }
206              
207 rizwank 1.8      return (memcmp(files[inode]->buf,buf,len));
208 rizwank 1.10     /* does not 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 rizwank 1.10 #ifdef TVFS_DEBUG
217 rizwank 1.8      trace("tvfs_lseek called with %d, %d, %d\n", h, whither, whence);
218 rizwank 1.10 #endif   
219 rizwank 1.8      
220              /*  if (whence > size) 
221                  whence = size;*/
222 rizwank 1.10 /*  Legit lseek does NOT do boundary checking */    
223 rizwank 1.8      
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                  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 rizwank 1.8      }    
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 rizwank 1.10 #ifdef TVFS_DEBUG
257 rizwank 1.8      trace("tvfs_close called with %d\n", h);
258 rizwank 1.10 #endif 
259 rizwank 1.8      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 rizwank 1.10 #ifdef TVFS_DEBUG
273 rizwank 1.8      trace("tvfs_write called with %d, %d, %d\n", h, buf, len);
274 rizwank 1.10 #endif    
275 rizwank 1.8      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 rizwank 1.10     trace("Testing TVFS implementation, creating %s\n",name_test_txt);
305 rizwank 1.8      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 rizwank 1.10     trace("Created virtual file with inode %d\n",result);
308 rizwank 1.8      
309 rizwank 1.10     trace("Attempting to open non-existent file\n");
310 rizwank 1.8      result = tvfs_open(bad_filename, _O_BINARY, 0 ); 
311 rizwank 1.10     trace("Result code %d\n",result); 
312                  trace("Attempting to open existent file\n");    
313 rizwank 1.8      result = tvfs_open(name_test_txt, _O_BINARY, 0 );
314 rizwank 1.10     trace("Result code %d\n",result); 
315 rizwank 1.8  
316                  active_handler = result;
317              
318                  memset (filebuf,0,MAXFLEN);
319              
320 rizwank 1.10     trace("Testing reading from file %s\n",name_test_txt);
321 rizwank 1.8      result = tvfs_read(active_handler, filebuf, 9);
322 rizwank 1.10     trace("Read _%s_\n", filebuf);
323 rizwank 1.8      if ( strcmp(filebuf,"This is a")) 
324 rizwank 1.10     trace("File read check failed!\n");    
325 rizwank 1.8  
326 rizwank 1.10     trace("Testing sequential reading from file %s\n",name_test_txt);
327 rizwank 1.8      result = tvfs_read(active_handler, filebuf, 12);
328 rizwank 1.10     trace("Read _%s_\n", filebuf);
329 rizwank 1.8      if ( strcmp(filebuf," test. Don't")) 
330 rizwank 1.10     trace("File read check failed!\n");
331 rizwank 1.8      
332 rizwank 1.10     trace("Testing edge reading from file %s\n",name_test_txt);
333 rizwank 1.8      result = tvfs_read(active_handler, filebuf, 42);
334 rizwank 1.10     trace("Read %d bytes - _%s_\n", result, filebuf);
335 rizwank 1.8      if ( result != 8 ) 
336 rizwank 1.10     trace("File read check failed!\n");
337 rizwank 1.8      
338 rizwank 1.10     trace("Testing direct file compare and lseek of %s\n", name_test_txt);
339                  trace("Seeking to 0 (not needed) - ");
340 rizwank 1.8      tvfs_lseek( active_handler, SEEK_SET, 0);
341 rizwank 1.10     trace("Comparing file\n");
342 rizwank 1.8      result = tvfs_compare( name_test_txt , file_test_txt, size_test_txt);
343                  if (result)
344 rizwank 1.10     trace ("File compare failed!\n"); 
345 rizwank 1.8  
346                  
347 rizwank 1.10     trace("Closing %s\n",name_test_txt);
348 rizwank 1.8      tvfs_close(active_handler);
349                  if (result)
350 rizwank 1.10     trace ("File close failed!\n");
351 rizwank 1.8      
352                  tvfs_free();
353                  free(filebuf);
354                  
355 rizwank 1.2  }
356              
357              #endif

Rizwan Kassim
Powered by
ViewCVS 0.9.2