filters

libmswrite_defs.h

00001 /* This file is part of the LibMSWrite Library
00002    Copyright (C) 2001-2003 Clarence Dang <clarencedang@users.sourceforge.net>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License Version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License Version 2 for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    Version 2 along with this library; see the file COPYING.LIB.  If not,
00015    write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016  * Boston, MA 02110-1301, USA.
00017 
00018    LibMSWrite Project Website:
00019    http://sourceforge.net/projects/libmswrite/
00020 */
00021 
00022 #ifndef __LIBMSWRITE_DEFS_H__
00023 #define __LIBMSWRITE_DEFS_H__
00024 
00025 #include <assert.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 
00029 #include "config.libmswrite.h"
00030 #include "list.h"
00031 
00032 namespace MSWrite
00033 {
00034     // library version
00035     extern const char *Version;
00036 
00037 
00045     typedef unsigned char Byte;                 // 1 byte
00046     typedef unsigned short Word;                    // 2 bytes
00047     typedef signed short Short;                 // 2 bytes
00048 
00049     // undefine for 16-bit (although the code is untested)
00050     #define ATLEAST32BIT
00051 
00052     #ifdef ATLEAST32BIT // 32-bit or 64-bit system
00053         typedef unsigned int DWord;             // 4 bytes
00054         typedef signed int Long;                    // 4 bytes
00055     #else
00056         typedef unsigned long DWord;                // 4 bytes
00057         typedef signed long Long;                   //  4 Bytes
00058     #endif
00059 
00060 
00061     //
00062     // possible errors passed to Devices
00063     //
00064     class Error
00065     {
00066     public:
00067         static const int Ok = 0;
00068         static const int Warn = 1;
00069         static const int InvalidFormat = 2;
00070         static const int OutOfMemory = 3;
00071         static const int InternalError = 4;
00072         static const int Unsupported = 5;
00073         static const int FileError = 6;
00074 
00075         static const int LastOne = 255;
00076         // for your own Errors, only use values >= 256 (values < 256 are reserved)
00077     };
00078 
00079 
00092     #define Twip2Point(val) ((val) / 20)
00093     #define Point2Twip(val) ((val) * 20)
00094 
00095     #define Twip2Inch(val)  ((val) / 1440)
00096     #define Inch2Twip(val)  ((val) * 1440)
00097 
00098     #define Point2Inch(val) ((val) / 72)
00099     #define Inch2Point(val) ((val) * 72)
00100 
00101     #define Twip2Milli(val) ((val) / 56.6929)
00102     #define Milli2Twip(val) ((val) * 56.6929)
00103 
00104     #define Point2Milli(val)    ((val) / 2.83465)
00105     #define Milli2Point(val)    ((val) * 2.83465)
00106 
00107     #define Inch2Mill(val)  ((val) * 25.4)
00108     #define Milli2Inch(val) ((val) / 25.4)
00109 
00115     inline Byte ReadByte (Byte &dest, const Byte *src)
00116     {
00117         return dest = *src;
00118     }
00119 
00120     inline Word ReadWord (Word &dest, const Byte *src)
00121     {
00122         return dest = ((Word) src [0]) |
00123                             (((Word) src [1]) << 8);
00124     }
00125 
00126     inline Short ReadShort (Short &dest, const Byte *src)
00127     {
00128         return (Short) ReadWord ((Word &) dest, src);
00129     }
00130 
00131     inline DWord ReadDWord (DWord &dest, const Byte *src)
00132     {
00133         return dest = ((DWord) src [0]) |
00134                             (((DWord) src [1]) << 8) |
00135                             (((DWord) src [2]) << 16) |
00136                             (((DWord) src [3]) << 24);
00137     }
00138 
00139     inline Long ReadLong (Long &dest, const Byte *src)
00140     {
00141         return (Long) ReadDWord ((DWord &) dest, src);
00142     }
00143 
00144     inline Byte WriteByte (const Byte &src, Byte *dest)
00145     {
00146         *dest = src;
00147         return src;
00148     }
00149 
00150     inline Word WriteWord (const Word &src, Byte *dest)
00151     {
00152         dest [0] = (Byte) (src & 255);
00153         dest [1] = (Byte) (src >> 8);
00154         return src;
00155     }
00156 
00157     inline Short WriteShort (const Short &src, Byte *dest)
00158     {
00159         WriteWord ((Word) src, dest);
00160         return src;
00161     }
00162 
00163     inline DWord WriteDWord (const DWord &src, Byte *dest)
00164     {
00165         dest [0] = (Byte) (src & 255);
00166         dest [1] = (Byte) ((src >> 8) & 255);
00167         dest [2] = (Byte) ((src >> 16) & 255);
00168         dest [3] = (Byte) (src >> 24);
00169         return src;
00170     }
00171 
00172     inline Long WriteLong (const Long &src, Byte *dest)
00173     {
00174         WriteDWord ((DWord) src, dest);
00175         return src;
00176     }
00177 
00184     // optimisation freak, I know :)
00185     #define BitMask1 1
00186     #define BitMask2 3
00187     #define BitMask3 7
00188     #define BitMask4 15
00189     #define BitMask5 31
00190     #define BitMask6 63
00191     #define BitMask7 127
00192     #define BitMask8 255
00193 
00194     #define ReadBitsFromByte(destbits,srcbyte,start,len)    \
00195         ((destbits)=((srcbyte)>>(start))&(BitMask##len))
00196     // NOTE: it is your fault if destbyte is not 0 to start with!
00197     #define WriteBitsToByte(srcbits,destbyte,start,len) \
00198         ((destbyte)|=((Byte(srcbits)&(BitMask##len))<<(start)))
00199 
00200 
00206     class Device
00207     {
00208     private:
00209         static const int MaxCacheDepth = 32;
00210         long m_posInternal;
00211         Byte *m_cache [MaxCacheDepth];
00212         int m_cacheCount;
00213 
00214         static const int MaxDebugLen = 1024;
00215         char m_debugTemp [MaxDebugLen];
00216 
00217     protected:
00218         int m_error;
00219 
00220     public:
00221         Device () : m_posInternal (0), m_cacheCount (0), m_error (0)
00222         {
00223         }
00224 
00225         virtual ~Device ()
00226         {
00227         }
00228 
00229         
00230         //
00231         // Do _not_ try to override these functions!
00232         // They are used internally by LibMSWrite so that reads/writes can
00233         // be redirected from/to memory blocks.
00234         //
00235 
00236 
00247         bool setCache (Byte *const cache)
00248         {
00249             if (cache)
00250             {
00251                 m_cache [m_cacheCount] = cache;
00252                 m_cacheCount++;
00253                 if (m_cacheCount > MaxCacheDepth)
00254                 {
00255                     error (Error::InternalError, "too many caches\n");
00256                     return false;
00257                 }
00258             }
00259             else
00260             {
00261                 --m_cacheCount;
00262                 if (m_cacheCount < 0)
00263                 {
00264                     error (Error::InternalError, "too few caches\n");
00265                     return false;
00266                 }
00267             }
00268 
00269             return true;
00270         }
00271 
00272         bool readInternal (Byte *buf, const long numBytes)
00273         {
00274             bool ret;
00275 
00276             if (m_cacheCount)
00277             {
00278                 memcpy (buf, m_cache [m_cacheCount - 1], numBytes);
00279                 m_cache [m_cacheCount - 1] += numBytes;
00280                 ret = true;
00281             }
00282             else
00283             {
00284                 ret = read (buf, numBytes);
00285                 if (ret) m_posInternal += numBytes;
00286             }
00287 
00288             return ret;
00289         }
00290 
00291         bool writeInternal (const Byte *buf, const long numBytes)
00292         {
00293             bool ret;
00294             
00295             if (m_cacheCount)
00296             {
00297                 memcpy (m_cache [m_cacheCount - 1], buf, numBytes);
00298                 m_cache [m_cacheCount - 1] += numBytes;
00299                 ret = true;
00300             }
00301             else
00302             {
00303                 ret = write (buf, numBytes);
00304                 if (ret) m_posInternal += numBytes;
00305             }
00306 
00307             return ret;
00308         }
00309 
00310         bool seekInternal (const long offset, const int whence)
00311         {
00312             bool ret = seek (offset, whence);
00313 
00314             if (ret)
00315             {
00316                 switch (whence)
00317                 {
00318                 case SEEK_SET:
00319                     m_posInternal = offset;
00320                     break;
00321                 case SEEK_CUR:
00322                     m_posInternal += offset;
00323                     break;
00324                 case SEEK_END:
00325                     m_posInternal = tell ();
00326                     break;
00327                 }
00328             }
00329 
00330             return ret;
00331         }
00332 
00333         long tellInternal (void) const
00334         {
00335             // does not reflect the cache!
00336             return m_posInternal;
00337         }
00338 
00339 
00340         //
00341         // convenience functions
00342         //
00343 
00344         void debug (const char *s, const int i)
00345         {
00346             snprintf (m_debugTemp, MaxDebugLen - 1, "%s%i\n", s, i);
00347             m_debugTemp [MaxDebugLen - 1] = 0;
00348             debug (m_debugTemp);
00349         }
00350         void debug (const char *s1, const char *s2)
00351         {
00352             snprintf (m_debugTemp, MaxDebugLen - 1, "%s%s\n", s1, s2);
00353             m_debugTemp [MaxDebugLen - 1] = 0;
00354             debug (m_debugTemp);
00355         }
00356 
00357         void debug (const char *s1, const Byte *s2)
00358         {
00359             debug (s1, (const char *) s2);
00360         }
00361 
00362         #define Dump(name) m_device->debug("\t" #name ": ", m_##name)
00363 
00364         bool good (void) const
00365         {
00366             return m_error == 0;
00367         }
00368 
00369         int bad (void) const
00370         {
00371             return m_error;
00372         }
00373 
00374 
00385         virtual bool read (Byte *buf, const DWord numBytes) = 0;
00386         virtual bool write (const Byte *buf, const DWord numBytes) = 0;
00387         virtual bool seek (const long offset, const int whence) = 0;
00388         virtual long tell (void) = 0;
00389         virtual void debug (const char *s)
00390         {
00391             fprintf (stderr, "%s", s);
00392         }
00393         virtual void debug (const int i)
00394         {
00395             fprintf (stderr, "%i", i);
00396         }
00397         static const DWord NoToken = DWord (0xABCD1234);    // hopefully won't clash with any values
00398         virtual void error (const int errorCode, const char *message,
00399                                     const char *file = "", const int lineno = 0,
00400                                     DWord token = NoToken)
00401         {
00402             // errors do not really include warnings after all...
00403             if (errorCode != Error::Warn)
00404                 m_error = errorCode;
00405 
00406             if (lineno)
00407                 fprintf (stderr, "%s:%i:", file, lineno);
00408             
00409             // TODO: why the \n?
00410             if (token == NoToken)
00411                 fprintf (stderr, "%s\n", message);
00412             else
00413                 fprintf (stderr, "%s (val=%li)\n", message, long (token));
00414         }
00415 
00416         #define ErrorAndQuit(errorCode,message)     \
00417         {                                                           \
00418             m_device->error(errorCode,message);         \
00419             return false;                                       \
00420         }
00421 
00422         #define Verify(errorCode,expr,token)    \
00423         ((expr)? true : (m_device->error(errorCode, "check \'" #expr "\' failed",__FILE__,__LINE__,token),m_device->good ()))
00424     };
00425 
00426 
00434     class MemoryDevice : public Device
00435     {
00436     public:
00437         MemoryDevice ()
00438         {
00439         }
00440 
00441         virtual ~MemoryDevice ()
00442         {
00443         }
00444 
00445         bool read (Byte * /*buf*/, const DWord /*numBytes*/)
00446         {
00447             error (Error::InternalError, "memory device not reading from memory?\n");
00448             return false;
00449         }
00450         bool write (const Byte * /*buf*/, const DWord /*numBytes*/)
00451         {
00452             error (Error::InternalError, "memory device not writing to memory?\n");
00453             return false;
00454         }
00455         bool seek (const long /*offset*/, const int /*whence*/)
00456         {
00457             error (Error::InternalError, "memory device cannot seek full stop!\n");
00458             return false;
00459         }
00460         long tell (void)
00461         {
00462             error (Error::InternalError, "memory device not accessing memory?\n");
00463             return -1;
00464         }
00465     };
00466 
00467     class NeedsDevice
00468     {
00469     protected:
00470         Device *m_device;
00471 
00472     public:
00473         NeedsDevice (Device *device = NULL)
00474         {
00475             setDevice (device);
00476         }
00477 
00478         virtual ~NeedsDevice ()
00479         {
00480         }
00481 
00482         void setDevice (Device *const device)
00483         {
00484             m_device = device;
00485         }
00486     };
00487 
00488     #ifdef CHECK_INTERNAL
00489         #define CHECK_DEVICE_ERROR  fprintf (stderr, "%s:%i: INTERNAL ERROR - device not set\n", __FILE__, __LINE__)
00490         #define CHECK_DEVICE        \
00491         if (!m_device)              \
00492         {                               \
00493             CHECK_DEVICE_ERROR; \
00494             return false;           \
00495         }
00496     #else
00497         #define CHECK_DEVICE_ERROR
00498         #define CHECK_DEVICE
00499     #endif
00500 
00501     // [PRIVATE]
00502     class UseThisMuchPrefixSize
00503     {
00504     private:
00505         int m_val;
00506 
00507     public:
00508         UseThisMuchPrefixSize (const int val = 0)
00509         {
00510             setVal (val);
00511         }
00512 
00513         ~UseThisMuchPrefixSize ()
00514         {
00515         }
00516 
00517         bool operator== (const UseThisMuchPrefixSize &rhs)
00518         {
00519             return m_val == rhs.m_val;
00520         }
00521 
00522         UseThisMuchPrefixSize &operator= (const UseThisMuchPrefixSize &rhs)
00523         {
00524             if (this == &rhs)
00525                 return *this;
00526 
00527             m_val = rhs.m_val;
00528             return *this;
00529         }
00530 
00531         int getVal (void) const {   return m_val;   }
00532         void setVal (const int val) {   m_val = val;    }
00533     };
00534     
00535     // [PRIVATE]
00536     class UseThisMuch
00537     {
00538     private:
00539         List <UseThisMuchPrefixSize> m_notDefaultBits;
00540         
00541     protected:
00542         UseThisMuch &operator= (const UseThisMuch &rhs)
00543         {
00544             if (this == &rhs)
00545                 return *this;
00546 
00547             this->m_notDefaultBits = rhs.m_notDefaultBits;
00548             return *this;
00549         }
00550         
00551         void signalHaveSetData (const bool isDefault, const int needNumBits)
00552         {
00553             if (isDefault)
00554             {
00555                 // it's a delete operation then
00556                 List <UseThisMuchPrefixSize>::Iterator it = m_notDefaultBits.search (needNumBits);
00557                 if (it != m_notDefaultBits.end ()) m_notDefaultBits.erase (it);
00558             }
00559             // possibly a new value
00560             else
00561             {
00562                 List <UseThisMuchPrefixSize>::Iterator it = m_notDefaultBits.search (needNumBits);
00563 
00564                 // new value
00565                 if (it == m_notDefaultBits.end ())
00566                 {
00567                     UseThisMuchPrefixSize utmps (needNumBits);
00568                     m_notDefaultBits.addToBack (utmps);
00569                 }
00570             }
00571         }
00572 
00573         // not bits
00574         int getNeedNumDataBytes (void) const
00575         {
00576             int biggest = 0;
00577             List <UseThisMuchPrefixSize>::Iterator it;
00578             for (it = m_notDefaultBits.begin (); it != m_notDefaultBits.end (); it++)
00579             {
00580                 if ((*it).getVal () > biggest)
00581                     biggest = (*it).getVal ();
00582             }
00583 
00584             if (biggest % 8)
00585                 return biggest / 8 + 1; // account for fractional byte
00586             else
00587                 return biggest / 8;
00588         }
00589 
00590     public:
00591         UseThisMuch ()
00592         {
00593         }
00594 
00595         virtual ~UseThisMuch ()
00596         {
00597         }
00598     };
00599     
00600 }   // namespace MSWrite    {
00601 
00602 #endif  // __LIBMSWRITE_DEFS_H__
00603 
00604 // end of libmswrite_defs.h
KDE Home | KDE Accessibility Home | Description of Access Keys