Scid  4.6.5
mfile.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////
2 //
3 // FILE: mfile.cpp
4 // MFile class methods
5 //
6 // Part of: Scid (Shane's Chess Information Database)
7 // Version: 2.0
8 //
9 // Notice: Copyright (c) 2000 Shane Hudson. All rights reserved.
10 //
11 // Author: Shane Hudson (sgh@users.sourceforge.net)
12 //
13 //////////////////////////////////////////////////////////////////////
14 
15 #include "common.h"
16 #include "mfile.h"
17 #include "misc.h"
18 
19 // GZ_BUFFER_SIZE: number of bytes read from a Gzip file at a time.
20 const uint GZ_BUFFER_SIZE = 1024;
21 
22 void
23 MFile::Init ()
24 {
25  Handle = NULL;
26  GzHandle = NULL;
27  GzBuffer = NULL;
28  FileMode = FMODE_Both;
29  Type = MFILE_MEMORY;
30  Capacity = 0;
31  Location = 0;
32  SeqReadLocation = 0;
33  Data = NULL;
34  CurrentPtr = NULL;
35  FileName = NULL;
36 }
37 
38 void
39 MFile::Extend ()
40 {
41  ASSERT (Type == MFILE_MEMORY);
42  // Double Capacity, starting with at least 8 Kb:
43  uint oldCapacity = Capacity;
44  Capacity += Capacity;
45  if (Capacity < 8192) { Capacity = 8192; }
46  byte * oldData = Data;
47  Data = new byte [Capacity];
48  CurrentPtr = &(Data[Location]);
49  if (oldData != NULL) {
50  // Copy data to new array:
51  for (uint i=0; i < oldCapacity; i++) { Data[i] = oldData[i]; }
52  delete[] oldData;
53  }
54 }
55 
56 errorT
57 MFile::Seek (uint position)
58 {
59  if (Type == MFILE_MEMORY) {
60  while (position >= Capacity) { Extend(); }
61  CurrentPtr = &(Data[position]);
62  Location = position;
63  return OK;
64  }
65 
66  if (Type == MFILE_SEQREAD) {
67  Type = MFILE_REGULAR;
68  if (Data != NULL) delete[] Data;
69  Data = CurrentPtr = NULL;
70  Capacity = 0;
71  } else {
72  if (FileMode != FMODE_Both && Location == position) { return OK; }
73  }
74 
75  int result;
76  if (Type == MFILE_GZIP) {
77  result = gzseek (GzHandle, position, 0);
78  GzBuffer_Avail = 0;
79  } else {
80  result = fseek (Handle, position, 0);
81  }
82  if (result != 0) { return ERROR_FileSeek; }
83  Location = position;
84  return OK;
85 }
86 
87 errorT
89 {
90  if (Type != MFILE_REGULAR || FileMode == FMODE_ReadOnly) { return OK; }
91  return (fflush (Handle) == 0 ? OK : ERROR_FileWrite);
92 }
93 
94 errorT
95 MFile::Open (const char * name, fileModeT fmode)
96 {
97  ASSERT (Handle == NULL && GzHandle == NULL);
98  const char * modeStr = NULL;
99  switch (fmode) {
100  case FMODE_ReadOnly: modeStr = "rb"; break;
101  case FMODE_WriteOnly: modeStr = "wb"; break;
102  case FMODE_Both: modeStr = "r+b"; break;
103  default: return ERROR_FileMode;
104  }
105 
106  const char * suffix = strFileSuffix (name);
107  if (suffix != NULL && strEqual (suffix, GZIP_SUFFIX)) {
108  // We can only open GZip files read-only for now:
109  if (fmode != FMODE_ReadOnly) {
110  return ERROR_FileOpen;
111  }
112  GzHandle = gzopen (name, "rb");
113  if (GzHandle == NULL) { return ERROR_FileOpen; }
114  Type = MFILE_GZIP;
115  GzBuffer = new byte [GZ_BUFFER_SIZE];
116  GzBuffer_Current = GzBuffer;
117  GzBuffer_Avail = 0;
118  } else {
119  Handle = fopen (name, modeStr);
120  if (Handle == NULL) { return ERROR_FileOpen; }
121  Type = MFILE_SEQREAD;
122  Data = new byte [SEQREADBUFSIZE];
123  CurrentPtr = Data;
124  SeqReadLocation = 0;
125  fseek(Handle, 0L, SEEK_END);
126  Capacity = ftell(Handle);
127  fseek(Handle, 0L, SEEK_SET);
128  }
129 
130  FileMode = fmode;
131  FileName = strDuplicate (name);
132  Location = 0;
133  return OK;
134 }
135 
136 errorT
137 MFile::Create (const char * name, fileModeT fmode)
138 {
139  ASSERT (Handle == NULL && GzHandle == NULL);
140  const char * modeStr = NULL;
141  switch (fmode) {
142  case FMODE_WriteOnly: modeStr = "wb"; break;
143  case FMODE_Both: modeStr = "w+b"; break;
144  default: return ERROR_FileMode;
145  }
146  if ((Handle = fopen (name, modeStr)) == NULL) { return ERROR_FileOpen; }
147  FileMode = fmode;
148  FileName = strDuplicate (name);
149  Location = 0;
150  Type = MFILE_REGULAR;
151  return OK;
152 }
153 
154 errorT
155 MFile::WriteNBytes (const char * str, uint length)
156 {
157  ASSERT (FileMode != FMODE_ReadOnly);
158 
159  errorT err = OK;
160 // while (length-- > 0) {
161 // err = WriteOneByte (*str);
162 // str++;
163 // }
164 // return err;
165 
166  if (Type == MFILE_MEMORY) {
167  while (length-- > 0) {
168  if (Location >= Capacity) { Extend(); }
169  *CurrentPtr++ = *str;
170  Location++;
171  str++;
172  }
173  return OK;
174  }
175  if (Type == MFILE_SEQREAD) Seek(Location);
176  Location += length;
177 
178  if (Type == MFILE_GZIP) {
179  err = OK;
180  while (length-- > 0 && err == OK) {
181  err = (gzputc(GzHandle, *str) == EOF) ? ERROR_FileWrite : OK;
182  str++;
183  }
184  return err;
185  }
186  return (fwrite( str, length, 1, Handle) != 1) ? ERROR_FileWrite : OK;
187 }
188 
189 errorT
190 MFile::ReadNBytes (char * str, uint length)
191 {
192  ASSERT (FileMode != FMODE_WriteOnly);
193  if (Type != MFILE_REGULAR) {
194  while (length-- > 0) {
195  *str++ = ReadOneByte ();
196  }
197  } else {
198  Location += fread (str, 1, length, Handle);
199  }
200  return OK;
201 }
202 
203 errorT
205 {
206  ASSERT (FileMode != FMODE_ReadOnly);
207  WriteOneByte ((value >> 8) & 255);
208  return WriteOneByte (value & 255);
209 }
210 
211 uint
213 {
214  uint result = 0;
215  ASSERT (FileMode != FMODE_WriteOnly);
216  result = ReadOneByte();
217  result <<= 8;
218  result += ReadOneByte();
219  return result;
220 }
221 
222 errorT
224 {
225  ASSERT (FileMode != FMODE_ReadOnly);
226  WriteOneByte ((value >> 16) & 255);
227  WriteOneByte ((value >> 8) & 255);
228  return WriteOneByte (value & 255);
229 }
230 
231 uint
233 {
234  uint result = 0;
235  ASSERT (FileMode != FMODE_WriteOnly);
236  result = ReadOneByte();
237  result <<= 8;
238  result += ReadOneByte();
239  result <<= 8;
240  result += ReadOneByte();
241  return result;
242 }
243 
244 errorT
246 {
247  ASSERT (FileMode != FMODE_ReadOnly);
248  WriteOneByte ((value >> 24) & 255);
249  WriteOneByte ((value >> 16) & 255);
250  WriteOneByte ((value >> 8) & 255);
251  return WriteOneByte (value & 255);
252 }
253 
254 
255 uint
257 {
258  uint result = 0;
259  ASSERT (FileMode != FMODE_WriteOnly);
260  result = ReadOneByte();
261  result <<= 8;
262  result += ReadOneByte();
263  result <<= 8;
264  result += ReadOneByte();
265  result <<= 8;
266  result += ReadOneByte();
267  return result;
268 }
269 
270 int
271 MFile::FillGzBuffer ()
272 {
273  ASSERT (Type == MFILE_GZIP && GzBuffer != NULL && GzBuffer_Avail <= 0);
274  int bytesread = gzread (GzHandle, GzBuffer, GZ_BUFFER_SIZE);
275  if (bytesread <= 0) { return EOF; }
276  GzBuffer_Avail = bytesread - 1;
277  GzBuffer_Current = &(GzBuffer[1]);
278  return GzBuffer[0];
279 
280 }
281 
282 //////////////////////////////////////////////////////////////////////
283 // End of file: mfile.cpp
284 //////////////////////////////////////////////////////////////////////
unsigned char byte
Definition: common.h:97
uint ReadTwoBytes()
Definition: mfile.cpp:212
bool strEqual(const char *str1, const char *str2)
Definition: misc.h:305
uint ReadThreeBytes()
Definition: mfile.cpp:232
const errorT OK
Definition: error.h:23
char * strDuplicate(const char *original)
Definition: misc.cpp:239
const errorT ERROR_FileWrite
Definition: error.h:32
#define ASSERT(f)
Definition: common.h:67
int gzseek(gzFile, int, int)
Definition: mfile.h:43
errorT Flush()
Definition: mfile.cpp:88
names
Definition: tablebase.tcl:260
int gzputc(gzFile, int c)
Definition: mfile.h:39
errorT ReadNBytes(char *str, uint length)
Definition: mfile.cpp:190
const char * strFileSuffix(const char *target)
Definition: misc.h:329
const uint GZ_BUFFER_SIZE
Definition: mfile.cpp:20
errorT WriteTwoBytes(uint value)
Definition: mfile.cpp:204
errorT Seek(uint position)
Definition: mfile.cpp:57
gzFile gzopen(const char *, const char *)
Definition: mfile.h:38
const char GZIP_SUFFIX[]
Definition: common.h:55
int gzread(gzFile, unsigned char *, int)
Definition: mfile.h:41
uint ReadFourBytes()
Definition: mfile.cpp:256
errorT Open(const char *name, fileModeT fmode)
Definition: mfile.cpp:95
errorT WriteFourBytes(uint value)
Definition: mfile.cpp:245
uint32_t uint
Definition: common.h:99
unsigned short errorT
Definition: error.h:20
int ReadOneByte()
Definition: mfile.h:143
errorT WriteOneByte(byte value)
Definition: mfile.h:125
const errorT ERROR_FileSeek
Definition: error.h:34
errorT Create(const char *name, fileModeT fmode)
Definition: mfile.cpp:137
fileModeT
Definition: common.h:144
const errorT ERROR_FileMode
Definition: error.h:38
errorT WriteThreeBytes(uint value)
Definition: mfile.cpp:223
const errorT ERROR_FileOpen
Definition: error.h:31
errorT WriteNBytes(const char *str, uint length)
Definition: mfile.cpp:155