filters

libmswrite_defs.h
1/* This file is part of the LibMSWrite Library
2 Copyright (C) 2001-2003 Clarence Dang <clarencedang@users.sourceforge.net>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License Version 2 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License Version 2 for more details.
12
13 You should have received a copy of the GNU Library General Public License
14 Version 2 along with this library; see the file COPYING.LIB. If not,
15 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17
18 LibMSWrite Project Website:
19 http://sourceforge.net/projects/libmswrite/
20*/
21
22#ifndef __LIBMSWRITE_DEFS_H__
23#define __LIBMSWRITE_DEFS_H__
24
25#include <assert.h>
26#include <stdio.h>
27#include <string.h>
28
29#include "config.libmswrite.h"
30#include "list.h"
31
32namespace MSWrite
33{
34 // library version
35 extern const char *Version;
36
37
44
45 typedef unsigned char Byte; // 1 byte
46 typedef unsigned short Word; // 2 bytes
47 typedef signed short Short; // 2 bytes
48
49 // undefine for 16-bit (although the code is untested)
50 #define ATLEAST32BIT
51
52 #ifdef ATLEAST32BIT // 32-bit or 64-bit system
53 typedef unsigned int DWord; // 4 bytes
54 typedef signed int Long; // 4 bytes
55 #else
56 typedef unsigned long DWord; // 4 bytes
57 typedef signed long Long; // 4 Bytes
58 #endif
59
60
61 //
62 // possible errors passed to Devices
63 //
64 class Error
65 {
66 public:
67 static const int Ok = 0;
68 static const int Warn = 1;
69 static const int InvalidFormat = 2;
70 static const int OutOfMemory = 3;
71 static const int InternalError = 4;
72 static const int Unsupported = 5;
73 static const int FileError = 6;
74
75 static const int LastOne = 255;
76 // for your own Errors, only use values >= 256 (values < 256 are reserved)
77 };
78
79
92 #define Twip2Point(val) ((val) / 20)
93 #define Point2Twip(val) ((val) * 20)
94
95 #define Twip2Inch(val) ((val) / 1440)
96 #define Inch2Twip(val) ((val) * 1440)
97
98 #define Point2Inch(val) ((val) / 72)
99 #define Inch2Point(val) ((val) * 72)
100
101 #define Twip2Milli(val) ((val) / 56.6929)
102 #define Milli2Twip(val) ((val) * 56.6929)
103
104 #define Point2Milli(val) ((val) / 2.83465)
105 #define Milli2Point(val) ((val) * 2.83465)
106
107 #define Inch2Mill(val) ((val) * 25.4)
108 #define Milli2Inch(val) ((val) / 25.4)
109
115 inline Byte ReadByte (Byte &dest, const Byte *src)
116 {
117 return dest = *src;
118 }
119
120 inline Word ReadWord (Word &dest, const Byte *src)
121 {
122 return dest = ((Word) src [0]) |
123 (((Word) src [1]) << 8);
124 }
125
126 inline Short ReadShort (Short &dest, const Byte *src)
127 {
128 return (Short) ReadWord ((Word &) dest, src);
129 }
130
131 inline DWord ReadDWord (DWord &dest, const Byte *src)
132 {
133 return dest = ((DWord) src [0]) |
134 (((DWord) src [1]) << 8) |
135 (((DWord) src [2]) << 16) |
136 (((DWord) src [3]) << 24);
137 }
138
139 inline Long ReadLong (Long &dest, const Byte *src)
140 {
141 return (Long) ReadDWord ((DWord &) dest, src);
142 }
143
144 inline Byte WriteByte (const Byte &src, Byte *dest)
145 {
146 *dest = src;
147 return src;
148 }
149
150 inline Word WriteWord (const Word &src, Byte *dest)
151 {
152 dest [0] = (Byte) (src & 255);
153 dest [1] = (Byte) (src >> 8);
154 return src;
155 }
156
157 inline Short WriteShort (const Short &src, Byte *dest)
158 {
159 WriteWord ((Word) src, dest);
160 return src;
161 }
162
163 inline DWord WriteDWord (const DWord &src, Byte *dest)
164 {
165 dest [0] = (Byte) (src & 255);
166 dest [1] = (Byte) ((src >> 8) & 255);
167 dest [2] = (Byte) ((src >> 16) & 255);
168 dest [3] = (Byte) (src >> 24);
169 return src;
170 }
171
172 inline Long WriteLong (const Long &src, Byte *dest)
173 {
174 WriteDWord ((DWord) src, dest);
175 return src;
176 }
177
183
184 // optimisation freak, I know :)
185 #define BitMask1 1
186 #define BitMask2 3
187 #define BitMask3 7
188 #define BitMask4 15
189 #define BitMask5 31
190 #define BitMask6 63
191 #define BitMask7 127
192 #define BitMask8 255
193
194 #define ReadBitsFromByte(destbits,srcbyte,start,len) \
195 ((destbits)=((srcbyte)>>(start))&(BitMask##len))
196 // NOTE: it is your fault if destbyte is not 0 to start with!
197 #define WriteBitsToByte(srcbits,destbyte,start,len) \
198 ((destbyte)|=((Byte(srcbits)&(BitMask##len))<<(start)))
199
200
206 class Device
207 {
208 private:
209 static const int MaxCacheDepth = 32;
210 long m_posInternal;
211 Byte *m_cache [MaxCacheDepth];
212 int m_cacheCount;
213
214 static const int MaxDebugLen = 1024;
215 char m_debugTemp [MaxDebugLen];
216
217 protected:
218 int m_error;
219
220 public:
221 Device () : m_posInternal (0), m_cacheCount (0), m_error (0)
222 {
223 }
224
225 virtual ~Device ()
226 {
227 }
228
229
230 //
231 // Do _not_ try to override these functions!
232 // They are used internally by LibMSWrite so that reads/writes can
233 // be redirected from/to memory blocks.
234 //
235
236
247 bool setCache (Byte *const cache)
248 {
249 if (cache)
250 {
251 m_cache [m_cacheCount] = cache;
252 m_cacheCount++;
253 if (m_cacheCount > MaxCacheDepth)
254 {
255 error (Error::InternalError, "too many caches\n");
256 return false;
257 }
258 }
259 else
260 {
261 --m_cacheCount;
262 if (m_cacheCount < 0)
263 {
264 error (Error::InternalError, "too few caches\n");
265 return false;
266 }
267 }
268
269 return true;
270 }
271
272 bool readInternal (Byte *buf, const long numBytes)
273 {
274 bool ret;
275
276 if (m_cacheCount)
277 {
278 memcpy (buf, m_cache [m_cacheCount - 1], numBytes);
279 m_cache [m_cacheCount - 1] += numBytes;
280 ret = true;
281 }
282 else
283 {
284 ret = read (buf, numBytes);
285 if (ret) m_posInternal += numBytes;
286 }
287
288 return ret;
289 }
290
291 bool writeInternal (const Byte *buf, const long numBytes)
292 {
293 bool ret;
294
295 if (m_cacheCount)
296 {
297 memcpy (m_cache [m_cacheCount - 1], buf, numBytes);
298 m_cache [m_cacheCount - 1] += numBytes;
299 ret = true;
300 }
301 else
302 {
303 ret = write (buf, numBytes);
304 if (ret) m_posInternal += numBytes;
305 }
306
307 return ret;
308 }
309
310 bool seekInternal (const long offset, const int whence)
311 {
312 bool ret = seek (offset, whence);
313
314 if (ret)
315 {
316 switch (whence)
317 {
318 case SEEK_SET:
319 m_posInternal = offset;
320 break;
321 case SEEK_CUR:
322 m_posInternal += offset;
323 break;
324 case SEEK_END:
325 m_posInternal = tell ();
326 break;
327 }
328 }
329
330 return ret;
331 }
332
333 long tellInternal (void) const
334 {
335 // does not reflect the cache!
336 return m_posInternal;
337 }
338
339
340 //
341 // convenience functions
342 //
343
344 void debug (const char *s, const int i)
345 {
346 snprintf (m_debugTemp, MaxDebugLen - 1, "%s%i\n", s, i);
347 m_debugTemp [MaxDebugLen - 1] = 0;
348 debug (m_debugTemp);
349 }
350 void debug (const char *s1, const char *s2)
351 {
352 snprintf (m_debugTemp, MaxDebugLen - 1, "%s%s\n", s1, s2);
353 m_debugTemp [MaxDebugLen - 1] = 0;
354 debug (m_debugTemp);
355 }
356
357 void debug (const char *s1, const Byte *s2)
358 {
359 debug (s1, (const char *) s2);
360 }
361
362 #define Dump(name) m_device->debug("\t" #name ": ", m_##name)
363
364 bool good (void) const
365 {
366 return m_error == 0;
367 }
368
369 int bad (void) const
370 {
371 return m_error;
372 }
373
374
385 virtual bool read (Byte *buf, const DWord numBytes) = 0;
386 virtual bool write (const Byte *buf, const DWord numBytes) = 0;
387 virtual bool seek (const long offset, const int whence) = 0;
388 virtual long tell (void) = 0;
389 virtual void debug (const char *s)
390 {
391 fprintf (stderr, "%s", s);
392 }
393 virtual void debug (const int i)
394 {
395 fprintf (stderr, "%i", i);
396 }
397 static const DWord NoToken = DWord (0xABCD1234); // hopefully won't clash with any values
398 virtual void error (const int errorCode, const char *message,
399 const char *file = "", const int lineno = 0,
400 DWord token = NoToken)
401 {
402 // errors do not really include warnings after all...
403 if (errorCode != Error::Warn)
404 m_error = errorCode;
405
406 if (lineno)
407 fprintf (stderr, "%s:%i:", file, lineno);
408
409 // TODO: why the \n?
410 if (token == NoToken)
411 fprintf (stderr, "%s\n", message);
412 else
413 fprintf (stderr, "%s (val=%li)\n", message, long (token));
414 }
415
416 #define ErrorAndQuit(errorCode,message) \
417 { \
418 m_device->error(errorCode,message); \
419 return false; \
420 }
421
422 #define Verify(errorCode,expr,token) \
423 ((expr)? true : (m_device->error(errorCode, "check \'" #expr "\' failed",__FILE__,__LINE__,token),m_device->good ()))
424 };
425
426
433
434 class MemoryDevice : public Device
435 {
436 public:
437 MemoryDevice ()
438 {
439 }
440
441 virtual ~MemoryDevice ()
442 {
443 }
444
445 bool read (Byte * /*buf*/, const DWord /*numBytes*/)
446 {
447 error (Error::InternalError, "memory device not reading from memory?\n");
448 return false;
449 }
450 bool write (const Byte * /*buf*/, const DWord /*numBytes*/)
451 {
452 error (Error::InternalError, "memory device not writing to memory?\n");
453 return false;
454 }
455 bool seek (const long /*offset*/, const int /*whence*/)
456 {
457 error (Error::InternalError, "memory device cannot seek full stop!\n");
458 return false;
459 }
460 long tell (void)
461 {
462 error (Error::InternalError, "memory device not accessing memory?\n");
463 return -1;
464 }
465 };
466
467 class NeedsDevice
468 {
469 protected:
470 Device *m_device;
471
472 public:
473 NeedsDevice (Device *device = NULL)
474 {
475 setDevice (device);
476 }
477
478 virtual ~NeedsDevice ()
479 {
480 }
481
482 void setDevice (Device *const device)
483 {
484 m_device = device;
485 }
486 };
487
488 #ifdef CHECK_INTERNAL
489 #define CHECK_DEVICE_ERROR fprintf (stderr, "%s:%i: INTERNAL ERROR - device not set\n", __FILE__, __LINE__)
490 #define CHECK_DEVICE \
491 if (!m_device) \
492 { \
493 CHECK_DEVICE_ERROR; \
494 return false; \
495 }
496 #else
497 #define CHECK_DEVICE_ERROR
498 #define CHECK_DEVICE
499 #endif
500
501 // [PRIVATE]
502 class UseThisMuchPrefixSize
503 {
504 private:
505 int m_val;
506
507 public:
508 UseThisMuchPrefixSize (const int val = 0)
509 {
510 setVal (val);
511 }
512
513 ~UseThisMuchPrefixSize ()
514 {
515 }
516
517 bool operator== (const UseThisMuchPrefixSize &rhs)
518 {
519 return m_val == rhs.m_val;
520 }
521
522 UseThisMuchPrefixSize &operator= (const UseThisMuchPrefixSize &rhs)
523 {
524 if (this == &rhs)
525 return *this;
526
527 m_val = rhs.m_val;
528 return *this;
529 }
530
531 int getVal (void) const { return m_val; }
532 void setVal (const int val) { m_val = val; }
533 };
534
535 // [PRIVATE]
536 class UseThisMuch
537 {
538 private:
539 List <UseThisMuchPrefixSize> m_notDefaultBits;
540
541 protected:
542 UseThisMuch &operator= (const UseThisMuch &rhs)
543 {
544 if (this == &rhs)
545 return *this;
546
547 this->m_notDefaultBits = rhs.m_notDefaultBits;
548 return *this;
549 }
550
551 void signalHaveSetData (const bool isDefault, const int needNumBits)
552 {
553 if (isDefault)
554 {
555 // it's a delete operation then
556 List <UseThisMuchPrefixSize>::Iterator it = m_notDefaultBits.search (needNumBits);
557 if (it != m_notDefaultBits.end ()) m_notDefaultBits.erase (it);
558 }
559 // possibly a new value
560 else
561 {
562 List <UseThisMuchPrefixSize>::Iterator it = m_notDefaultBits.search (needNumBits);
563
564 // new value
565 if (it == m_notDefaultBits.end ())
566 {
567 UseThisMuchPrefixSize utmps (needNumBits);
568 m_notDefaultBits.addToBack (utmps);
569 }
570 }
571 }
572
573 // not bits
574 int getNeedNumDataBytes (void) const
575 {
576 int biggest = 0;
577 List <UseThisMuchPrefixSize>::Iterator it;
578 for (it = m_notDefaultBits.begin (); it != m_notDefaultBits.end (); it++)
579 {
580 if ((*it).getVal () > biggest)
581 biggest = (*it).getVal ();
582 }
583
584 if (biggest % 8)
585 return biggest / 8 + 1; // account for fractional byte
586 else
587 return biggest / 8;
588 }
589
590 public:
591 UseThisMuch ()
592 {
593 }
594
595 virtual ~UseThisMuch ()
596 {
597 }
598 };
599
600} // namespace MSWrite {
601
602#endif // __LIBMSWRITE_DEFS_H__
603
604// end of libmswrite_defs.h
virtual bool read(Byte *buf, const DWord numBytes)=0
Functions that the user must implement.
bool setCache(Byte *const cache)
setCache specifies whether or not Device should start reading from memory block specified by
bool read(Byte *, const DWord)
Functions that the user must implement.