source: golgotha/src/i4/file/win32/win_file.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 7.8 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "file/file.hh"
10#include "memory/malloc.hh"
11#include "error/error.hh"
12#include "time/profile.hh"
13#include "error/error.hh"
14#include "file/buf_file.hh"
15#include "file/async.hh"
16#include "file/file_man.hh"
17#include "memory/array.hh"
18#include <windows.h>
19#include <stdio.h>
20#include <fcntl.h>
21#include <io.h>
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <direct.h>
25#include "string/string.hh"
26
27i4_profile_class pf_win32_seek("Win32File::Seek");
28
29i4_profile_class pf_win32_read("Win32File::Read");
30i4_profile_class pf_win32_write("Win32File::Write");
31
32class i4_win32_async_reader : public i4_async_reader
33{
34public:
35  i4_win32_async_reader(char *name) : i4_async_reader(name) {}
36  virtual w32 read(sw32 fd, void *buffer, w32 count)
37  {
38    w32 res = _read(fd,buffer,count);
39    return res;
40  }
41} i4_win32_async_instance("hd_async_reader_2");
42
43
44////////////////////////////////////////////////////////////////////////
45//
46//  Normal Win32 File Class
47//
48
49class i4_win32_file_class : public i4_file_class
50{
51protected:
52  w32 fd;
53public:
54
55  i4_win32_file_class(w32 fd) : fd(fd) {}
56
57  virtual w32 read (void *buffer, w32 size)
58  {
59    pf_win32_read.start();
60    w32 res = _read(fd,buffer,size);
61    pf_win32_read.stop();
62    return res;
63  }
64
65  virtual w32 write(const void *buffer, w32 size)
66  {
67    pf_win32_write.start();
68    w32 res = _write(fd,buffer,size);
69    pf_win32_write.stop();
70    return res;
71  }
72
73  virtual w32 seek (w32 offset)
74  { 
75    pf_win32_seek.start();
76    w32 res = lseek(fd, offset, SEEK_SET);
77    pf_win32_seek.stop();
78    return res;
79  }
80
81  virtual w32 size ()                       
82  {
83    w32 len = _filelength(fd);
84
85    /*
86    w32 cur = lseek(fd,0,SEEK_CUR);
87      ]  len = lseek(fd,0,SEEK_END);
88    lseek(fd,cur,SEEK_SET);
89    */
90    return len;
91  }
92
93  virtual w32 tell ()
94  {
95    return _tell(fd);
96  }
97
98  ~i4_win32_file_class()
99  {
100    _close(fd);
101  }
102
103
104  // returns i4_F if an immediate error occured
105  virtual i4_bool async_read (void *buffer, w32 size,
106                              async_callback call,
107                              void *context=0)
108  {
109    if (i4_threads_supported())
110      return i4_win32_async_instance.start_read(fd, buffer, size, call, context);
111    else
112      call(read(buffer,size),context);
113    return i4_T;
114  }
115
116};
117
118
119////////////////////////////////////////////////////////////////////////
120//
121//  File Manager Methods
122//
123
124
125
126
127
128
129
130
131
132
133// see file/file.hh for a description of what each of these functions do
134class i4_win32_file_manager_class : public i4_file_manager_class
135{
136public:   
137  virtual i4_file_class *open(const i4_const_str &name, w32 flags)
138  {
139    sw32 f=0;
140    i4_bool no_buffer=i4_F;
141   
142    flags &= ~I4_SUPPORT_ASYNC;     // don't have to do anything special for these
143   
144    if (flags & I4_NO_BUFFER)
145    {
146      flags=(flags & (~I4_NO_BUFFER));
147      no_buffer=i4_T;
148    }
149
150    f=O_BINARY;       // open all files in binary mode
151    char sbuf[256];
152
153    switch (flags)
154    {
155      case I4_READ:
156        f|=O_RDONLY;
157        break;
158
159      case I4_WRITE:
160        f |= O_WRONLY | O_CREAT;
161        _unlink(i4_os_string(name,sbuf,sizeof(sbuf)));
162        break;
163
164      case I4_WRITE|I4_READ:
165        f |= O_RDWR | O_CREAT;
166        _unlink(i4_os_string(name,sbuf,sizeof(sbuf)));
167        break;
168
169      case I4_APPEND:
170      case I4_WRITE|I4_APPEND:
171        f |= O_WRONLY|O_CREAT|O_APPEND;
172        break;
173
174      default:
175        i4_warning("i4_file_class::Bad open flags!");
176        return NULL;     
177    }
178
179    int fd;
180
181
182    fd=::_open(i4_os_string(name,sbuf,sizeof(sbuf)),f,_S_IREAD | _S_IWRITE);
183
184    if (fd<0)
185    {
186      i4_warning("i4_file_class::open failed for %s\n",i4_os_string(name,sbuf,sizeof(sbuf)));
187      return NULL;
188    }
189
190
191    i4_file_class *ret_fp;
192    if (!no_buffer)
193      ret_fp=new i4_buffered_file_class(new i4_win32_file_class(fd));
194    else
195      ret_fp=new i4_win32_file_class(fd);
196
197    return ret_fp;
198  }
199
200
201
202  virtual i4_bool unlink(const i4_const_str &name)
203  {
204    char buf[256];
205    return _unlink(i4_os_string(name,buf,sizeof(buf)))==0;
206  }
207
208
209  virtual i4_bool mkdir(const i4_const_str &name)
210  { 
211    char buf[256];
212    return ::_mkdir(i4_os_string(name,buf,sizeof(buf)))==0;
213  }
214
215  i4_bool get_status(const i4_const_str &filename, i4_file_status_struct &return_stat)
216  {
217    i4_bool error=i4_F;
218    struct _stat times;
219    char buf[256];
220
221    return_stat.flags=0;
222    if (_stat(i4_os_string(filename,buf,sizeof(buf)),&times)==0)     
223    {
224      return_stat.last_modified=times.st_mtime;
225      return_stat.last_accessed=times.st_atime;
226      return_stat.created=times.st_ctime;
227
228      if (times.st_mode &  _S_IFDIR)
229        return_stat.flags=I4_FILE_STATUS_DIRECTORY;     
230    }
231    else
232      error=i4_T;
233
234    return (i4_bool)(!error);
235  }
236
237  virtual i4_bool get_directory(const i4_const_str &path,
238                                i4_directory_struct &dir_struct,
239                                i4_bool get_status,
240                                i4_status_class *status)
241
242  {
243    _finddata_t fdat;
244    char os_str[255],buf[256];
245    sprintf(os_str,"%s/*.*",i4_os_string(path,buf,sizeof(buf)));
246
247    long handle=_findfirst(os_str,&fdat),done;
248    if (handle==-1)
249      return i4_F;
250 
251    i4_array<i4_file_status_struct> stats(64,64);
252
253    do
254    {
255      if (fdat.attrib & _A_SUBDIR)
256      {
257        dir_struct.tdirs++;
258        dir_struct.dirs=(i4_str **)i4_realloc(dir_struct.dirs,
259                                              sizeof(i4_str *)*dir_struct.tdirs,"dir list");
260        dir_struct.dirs[dir_struct.tdirs-1]=new i4_str(i4_const_str(fdat.name));
261      }
262      else
263      {
264        i4_file_status_struct *s=stats.add();
265        s->last_accessed=fdat.time_access;
266        s->last_modified=fdat.time_write;
267        s->created=fdat.time_create;
268
269        dir_struct.tfiles++;
270        dir_struct.files=(i4_str **)i4_realloc(dir_struct.files,
271                                               sizeof(i4_str *)*dir_struct.tfiles,"dir list");
272        dir_struct.files[dir_struct.tfiles-1]=new i4_str(i4_const_str(fdat.name));
273      }
274
275      done=_findnext(handle, &fdat);
276    } while (done!=-1);
277
278
279    if (get_status)
280    {   
281      if (dir_struct.tfiles)
282      {
283        i4_file_status_struct *sa;
284        sa=(i4_file_status_struct *)i4_malloc(sizeof(i4_file_status_struct)*dir_struct.tfiles,"");
285        for (int j=0; j<dir_struct.tfiles; j++)
286          sa[j]=stats[j];
287
288        dir_struct.file_status=sa;
289      }
290    }
291
292    return i4_T;
293  }
294
295  virtual i4_str *full_path(const i4_const_str &relative_name)
296  {
297    char buf[256], buf2[256];
298    ::_fullpath(i4_os_string(relative_name, buf, 256), buf2, 256);
299    return new i4_str(i4_const_str(buf2));
300  }
301
302  i4_win32_file_manager_class()
303  {
304    i4_add_file_manager(this, i4_F);   
305  }
306
307  ~i4_win32_file_manager_class()
308  {
309    i4_remove_file_manger(this);
310  }
311
312} i4_win32_file_man;
313
314
315i4_bool i4_rmdir(const i4_const_str &path)
316{
317  char p[256];
318  i4_os_string(path, p, 256);
319  if (_rmdir(p)==0)
320    return i4_T;
321  else return i4_F;
322}
323
324i4_bool i4_chdir(const i4_const_str &path)
325{
326  char p[256];
327  i4_os_string(path, p, 256);
328  if (_chdir(p)==0)
329    return i4_T;
330  else return i4_F;
331}
332
Note: See TracBrowser for help on using the repository browser.