vrecko
virtual reality framework
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
BufFile.h
Go to the documentation of this file.
1 // Created by Vit Kovalcik (vit@pastel.cz)
2 
3 // Buffered file (for sequential access)
4 // Supports ASCII and simple variant of UTF-16 files (double byte characters only)
5 
6 #ifndef BUFFILE_H
7 #define BUFFILE_H
8 
9 #include <vrecko/Export>
10 
11 #include <osg/Vec3>
12 
13 #include "DynamicArray.h"
14 #include <tchar.h>
15 
16 
17 #define BUFFILE_INITBUFFERSIZE 65536
18 #define BUFFILE_MINBUFFERSIZE 16384
19 
20 #define BUFFILE_MAXBUFFILESIZE 65536
21  // Kdyz se otevre soubor a zjisti se, ze je mensi nez tato konstanta
22  // tak se vytvori mensi buffer
23 
24 #ifndef INVALID_SET_FILE_POINTER
25  #define INVALID_SET_FILE_POINTER ((DWORD)-1)
26 #endif
27 
28 
29 #define BUFFILE_BEHVF_UNICODE_START_HIDE 0x00000002
30 #define BUFFILE_BEHVF_LOADFILETOMEM 0x00000001
31  // Nacte na zacatku cely soubor do pameti, soubor zavre a dale se s nim uz nepracuje.
32  // Tento flag ma efekt jen pri otevreni souboru funkci
33  // bool Init (LPCSTR lpFileName);
34  // Druha funkce
35  // bool Init (HANDLE hFile, bool bCallSPF);
36  // tento flag zrusi
37 
38 
39 namespace vrecko {
40 
41 
42 bool FileExists (const _TCHAR *pFileName);
43 
44 
45 class VRECKO_EXPORT BufferedFile {
46 public:
47  BufferedFile (void);
48  ~BufferedFile (void);
49 
50  bool setBehaviour (DWORD dwBehvFlags);
51  // kombinace BUFFILE_BEHVF_*
52  // Tuto funkci lze zavolat jen pred funkci Init.
53 
54  bool init (_TCHAR* lpFileName);
55 
56  bool init (HANDLE hFile, bool bCallSPF);
57  // hFile is handle to the opened file
58  // bCallSFP = true => call setFilePointer in destructor
59  // to set file pointer to the right position
60 
61  HANDLE getHandle() { return hFile; };
62 
63  LPBYTE lpBuffer;
64  DWORD dwPos;
65  inline DWORD getFilePos (void) const;
66  void close (void);
67  // After this function, the behaviour of other functions is
68  // undefined until calling Init.
69 
70  bool setFilePos (DWORD dwNewFilePos);
71  // true = OK, false = failed
72  // Pokud je specifikovan flag BUFFILE_BEHVF_UNICODE_START_HIDE, tak
73  // se automaticky zmeni pozice mensi nez [dwZeroPos] na [dwZeroPos].
74  inline DWORD getMaxPos (void) const;
75  inline DWORD getBufSize (void) const;
76  inline DWORD getFileSize (void) const;
77  void setBufSize (DWORD dwNewSize);
78 
79  bool preReadBytes (DWORD dwNumOfBytes);
80  // this function makes sure, that there are at least <dwNumOfBytes> bytes in buffer
81 
82  inline bool readBytes (LPVOID lpDest, DWORD dwBytesToRead);
83  // This function will fail, if it doesn't read all the data.
84 
85  inline bool readBytes (LPVOID lpDest, DWORD dwBytesToRead, LPDWORD lpdwBytesRead) {
86 /* Optimization, which doesn't speed things up very much, so it was turned off
87 
88  if (dwMaxPos - dwPos >= dwBytesToRead) {
89  memcpy (lpDest, (LPBYTE)lpBuffer + dwPos, dwBytesToRead);
90  if (lpdwBytesRead)
91  *lpdwBytesRead = dwBytesToRead;
92  dwPos += dwBytesToRead;
93  return true;
94  } else*/
95  return readBytesCore(lpDest, dwBytesToRead, lpdwBytesRead);
96  }
97  // ReadBytes cannot 'fail', but can read zero bytes.
98  // This function will return true, if it read exactly so many bytes as you specified
99  // or will return false, if it read less bytes (due to eof or error).
100  // lpdwBytesRead can be NULL in case you don't need this value
101 
102  inline BYTE readByte (void);
103  // Reads byte WITHOUT error checking
104 
105  bool readWCharTrans (WCHAR *wChar);
106  // Supports ASCII and UTF-16. (Automatic conversion)
107 
108  inline bool readBool (bool *pData) { return readBytes (pData, 1); };
109  inline bool readByte (BYTE *pData) { return readBytes (pData, 1); };
110  inline bool readWORD (WORD *pData) { return readBytes (pData, 2); };
111  inline bool readDWORD (DWORD *pData) { return readBytes (pData, 4); };
112  inline bool readLONG (LONG *pData) { return readBytes (pData, sizeof (LONG)); };
113  inline bool readFloat (float *pData) { return readBytes (pData, 4); };
114  inline bool readVec3f (osg::Vec3f *v) { return readBytes(&v->x(), 4) && readBytes(&v->y(), 4) && readBytes(&v->z(), 4); };
115  inline bool readInt (int *pData) { return readBytes (pData, 4); };
116  inline bool readPOINT (POINT *pData) { return readBytes (pData, sizeof (POINT)); };
117  inline bool readInt64 (__int64 *pData) { return readBytes (pData, 8); };
118  inline bool readRECT (RECT *pData) { return readBytes (pData, sizeof (RECT)); };
119  inline bool readStr (CHAR *pData);
120 
121 #ifdef UNICODE
122  inline bool tReadLine(_TCHAR* tBuffer, PDWORD pdwCharSize) { return readLineW(tBuffer, pdwCharSize); }
123 #else
124  inline bool tReadLine(_TCHAR* tBuffer, PDWORD pdwCharSize) { return readLine(tBuffer, pdwCharSize); }
125 #endif
126 
127 
128  bool readLine (PSTR pBuffer, PDWORD pdwCharSize);
129  // Reads line to CHAR buffer;
130  // Is is assumed, that file is in ASCII (not UTF-16)
131  // dwSize is size of buffer (in characters = 2 bytes) at the start and number of characters read
132  // after the function ends.
133  // pdwCharSize includes terminating character
134  // If dwSize is not enough to hold whole line, function will return false.
135 
136  bool readLineW (PWSTR pBuffer, PDWORD pdwCharSize);
137  // Reads line to WCHAR buffer.
138  // dwSize is size of buffer (in characters = 2 bytes) at the start and number of characters read
139  // after the function ends.
140  // pdwCharSize includes terminating character
141  // If dwSize is not enough to hold whole line, function will return false.
142 
143  inline bool isEOF (void) { return (getFilePos () >= getFileSize ()); }
144 
145 protected:
146  HANDLE hFile;
147 
148  DWORD dwFilePos;
149  DWORD dwMaxPos;
150  DWORD dwBufSize;
151  DWORD dwFileSize;
152 
154  // Should the file be closed in destructor?
155  bool bCallSFP;
156 
157  DWORD dwBehvFlags; // kombinace BUFFILE_BEHVF_*
158 
160  // je soubor ve formatu UTF? (jinak je normalne v ASCII)
162  // jsou byte ve WCHARu v souboru v obracenem poradi?
163 
164  DWORD dwZeroPos;
165  // Pouziva se pouze, kdyz je specifikovan flag BUFFILE_BEHVF_UNICODE_START_HIDE.
166  // Nulova pozice. UNICODE soubory tady budou mit "2",
167  // protoze v prvnich dvou bytech jsou ridici znaky, ktere nechceme cist.
168 
169  bool readBytesCore(LPVOID lpDest, DWORD dwBytesToRead, LPDWORD lpdwBytesRead);
170 
171  void UNICODECheck (void);
172 };
173 
174 
176 public:
177  BufferedFileWrite (void);
178  ~BufferedFileWrite (void);
179 
180  bool init (TCHAR *lpFileName);
181 
182  HANDLE getHandle() { return hFile; };
183 
184  inline bool write (LPVOID lpBuffer, DWORD dwSize); // sadly this has to be inline due to compilation errors (bugs?) in PointShellGeneric_Object_Data<_NodeType> template
185 
186  inline bool writeByte (BYTE bData) { return write (&bData, 1); };
187  inline bool writeBool (bool bData) { return write (&bData, 1); };
188  inline bool writeWORD (WORD wData) { return write (&wData, 2); };
189  inline bool writeLONG (LONG lData) { return write (&lData, sizeof (LONG)); };
190  inline bool writeDWORD (DWORD dwData) { return write (&dwData, 4); };
191  inline bool writeFloat (float fData) { return write (&fData, 4); };
192  inline bool writeVec3f (osg::Vec3f *v) { return write(&v->x(), 4) && write(&v->y(), 4) && write(&v->z(), 4); };
193  inline bool writeInt (int iData) { return write (&iData, 4); };
194  inline bool writePOINT (POINT *pnt) { return write (pnt, sizeof (POINT)); };
195  inline bool writeInt64 (__int64 iData) { return write (&iData, 8); };
196  inline bool writeRECT (RECT *rData) { return write (&rData, sizeof (RECT)); };
197  inline bool writeStr (PSTR pData) { return write (pData, (DWORD)strlen (pData) + 1); };
198  bool writeFormattedString (TCHAR *pFormat, ...);
199 
200  bool flush (void);
201  bool close (void);
202 
203 protected:
204  HANDLE hFile;
206 
208 };
209 
210 
211 inline DWORD BufferedFile::getFilePos (void) const
212 {
213  return dwFilePos + dwPos;
214 }
215 
216 
217 inline DWORD BufferedFile::getMaxPos (void) const
218 {
219  return dwMaxPos;
220 }
221 
222 
223 inline DWORD BufferedFile::getBufSize (void) const
224 {
225  return dwBufSize;
226 }
227 
228 
229 inline DWORD BufferedFile::getFileSize (void) const
230 {
231  return dwFileSize;
232 }
233 
234 
235 inline bool BufferedFile::readBytes (LPVOID lpDest, DWORD dwBytesToRead)
236 {
237  DWORD dw;
238  if (!readBytes (lpDest, dwBytesToRead, &dw))
239  return false;
240  return (dw == dwBytesToRead);
241 }
242 
243 
244 inline BYTE BufferedFile::readByte (void)
245 {
246  if (dwPos >= dwMaxPos) {
247  if (!preReadBytes (1))
248  return 0x00;
249 
250  if (dwMaxPos)
251  return lpBuffer[dwPos++];
252  return 0x00;
253  }
254  return lpBuffer[dwPos++];
255 }
256 
257 
258 bool BufferedFile::readStr (CHAR *pData)
259 {
260  while (readByte ((PBYTE)pData)) {
261  if (0x00 == *pData)
262  return true;
263  pData++;
264  }
265 
266  return false;
267 }
268 
269 
270 bool BufferedFileWrite::write (LPVOID lpBuffer, DWORD dwSize)
271 {
272  if (!dwSize)
273  return true;
274 
275  while (dwSize) {
276  DWORD dwTmp = dwSize;
277  if (dwSize > (dwBufMaxSize - buffer.dwNum))
278  dwTmp = (dwBufMaxSize - buffer.dwNum);
279 
280  memcpy (buffer.lpBuffer + buffer.dwNum, lpBuffer, dwTmp);
281  buffer.dwNum += dwTmp;
282  dwSize -= dwTmp;
283  lpBuffer = (LPVOID)((LPBYTE)lpBuffer + dwTmp);
284 
285  if (buffer.dwNum >= dwBufMaxSize) {
286  DWORD dwWritten;
287  if (FALSE == ::WriteFile (hFile, buffer.lpBuffer, buffer.dwNum, &dwWritten, NULL))
288  return false;
289  buffer.dwNum = 0;
290  }
291  }
292 
293  return true;
294 }
295 
296 
297 }; // namespace vrecko
298 
299 
300 #endif // BUFFILE_H