system.h

Go to the documentation of this file.
00001 
00021 /*
00022  *  Copyright (c) 2003, Matt Beard
00023  *
00024  *  This software is provided 'as-is', without any express or implied warranty.
00025  *  In no event will the authors be held liable for any damages arising from
00026  *  the use of this software.
00027  *
00028  *  Permission is granted to anyone to use this software for any purpose,
00029  *  including commercial applications, and to alter it and redistribute it
00030  *  freely, subject to the following restrictions:
00031  *
00032  *    1. The origin of this software must not be misrepresented; you must
00033  *       not claim that you wrote the original software. If you use this
00034  *       software in a product, an acknowledgment in the product
00035  *       documentation would be appreciated but is not required.
00036  *  
00037  *    2. Altered source versions must be plainly marked as such, and must
00038  *       not be misrepresented as being the original software.
00039  *  
00040  *    3. This notice may not be removed or altered from any source
00041  *       distribution.
00042  */
00043 
00044 #ifndef MXFLIB__SYSTEM_H
00045 #define MXFLIB__SYSTEM_H
00046 
00047 // Required headers for non-system specific bits
00048 #include <time.h>
00049 #include <stdlib.h>                     // Required for integer conversions
00050 
00051 /************************************************/
00052 /*           (Hopefully) Common types           */
00053 /************************************************/
00054 /* Defined here so they can be used in the rest */
00055 /* of this file if required                     */
00056 /************************************************/
00057 
00058 namespace mxflib
00059 {
00060     typedef unsigned int UInt32;        
00061     typedef unsigned short int UInt16;  
00062     typedef unsigned char UInt8;        
00063 
00064     typedef int Int32;                  
00065     typedef short int Int16;            
00066     typedef signed char Int8;           
00067 
00068     struct full_time                    
00069     {
00070         time_t  time;
00071         int     msBy4;
00072     };
00073 
00074 
00075     // Runtime detection of endian-ness using detection code that executes once.
00076     // The variable littleEndian is then used to check if bytes read/written to
00077     // files need to be swapped.
00078     static bool IsLittleEndian()
00079     {
00080         unsigned int val = 0x12345678;
00081         unsigned char *p;
00082 
00083         p = (unsigned char *)&val;
00084 
00085         if (p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78)
00086             return false;
00087         else if (p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12)
00088             return true;
00089 
00090         return false;
00091     }
00092 
00093     static bool littleEndian = IsLittleEndian();
00094 }
00095 
00096 
00097 
00098 /************************************************/
00099 /*             Microsoft Visual C++             */
00100 /************************************************/
00101 
00102 #ifdef _MSC_VER
00103 
00104 // Visual studio 6 specifics
00105 #if _MSC_VER < 1300
00106 #pragma warning(disable:4786)           // Ignore "identifer > 255 characters" warning
00107                                         // This is produced from many STL class specialisations
00108                                         // Note: Not all these warnings go away (another MS-Bug??)
00109 
00110 #ifndef UINT64_C
00111 #define UINT64_C(c) c                   // for defining 64bit constants
00112 #endif // UINT64_C
00113 #ifndef INT64_C
00114 #define INT64_C(c)  c                   // for defining 64bit constants
00115 #endif // INT64_C
00116 
00117 #else  // _MSC_VER < 1300
00118 
00119 #ifndef UINT64_C
00120 #define UINT64_C(c) c##ULL              // for defining 64bit constants
00121 #endif // UINT64_C
00122 #ifndef INT64_C
00123 #define INT64_C(c)  c##ULL              // for defining 64bit constants
00124 #endif // INT64_C
00125 
00126 #endif // _MSC_VER < 1300
00127 
00128 #include <crtdbg.h>                     
00129 #include <string>                       
00130 #include <io.h>                         
00131 
00132 namespace mxflib
00133 {
00134     typedef __int64 Int64;              
00135     typedef unsigned __int64 UInt64;    
00136 
00137     /******** ENDIAN SWAPPING ********/
00138     inline UInt16 Swap(UInt16 Val) 
00139     {
00140         return ((Val & 0xff00) >> 8) | ((Val & 0x00ff) << 8); 
00141     };
00142 
00143     inline Int16 Swap(Int16 Val) { return (Int16)Swap((UInt16)Val); };
00144     
00145     inline UInt32 Swap(UInt32 Val) 
00146     { 
00147         return ( ((Val & 0xff000000) >> 24)
00148                | ((Val & 0x00ff0000) >> 8)
00149                | ((Val & 0x0000ff00) << 8)
00150                | ((Val & 0x000000ff) << 24) ); 
00151     };
00152     inline Int32 Swap(Int32 Val) { return (Int32)Swap((UInt32)Val); };
00153 
00154     inline UInt64 Swap(UInt64 Val) 
00155     { 
00156         UInt32 MSW = (UInt32)((Val & 0xffffffff00000000) >> 32);
00157         UInt32 LSW = (UInt32)(Val & 0x00000000ffffffff);
00158 
00159         MSW = Swap(MSW);
00160         LSW = Swap(LSW);
00161 
00162         return (((UInt64)LSW) << 32) | ((UInt64)MSW);
00163     };
00164     inline Int64 Swap(Int64 Val) { return (Int64)Swap((UInt64)Val); };
00165 
00166     
00167     /******** Int64 Conversion ********/
00168     inline Int64 ato_Int64(const char *str) { return _atoi64(str); };
00169     inline Int64 ato_UInt64(const char *str) { return (UInt64)_atoi64(str); };
00170 
00171     inline std::string Int64toString(Int64 Val)
00172     { 
00173         char Buffer[32];
00174         _i64toa(Val, Buffer, 10);
00175         return std::string(Buffer);
00176     };
00177 
00178     inline std::string UInt64toString(UInt64 Val)
00179     { 
00180         char Buffer[32];
00181         _ui64toa(Val, Buffer, 10);
00182         return std::string(Buffer);
00183     };
00184 
00185     inline std::string Int64toHexString(Int64 Val, int Digits = 0)
00186     {
00187         char Buffer[32];
00188         if(Digits > 30) Digits = 30;
00189         sprintf(Buffer,"%0*I64x", Digits, Val );
00190         return std::string(Buffer);
00191     };
00192 
00193 #define ASSERT _ASSERT                  
00194 #define strcasecmp(s1, s2) stricmp(s1, s2)
00195 
00197 #define IsCommandLineSwitchPrefix(x) ( (x == '/') || (x == '-'))
00198 
00200     inline void PauseForInput(void)
00201     {
00202         printf("Press enter key...");
00203         getchar();
00204         printf("\n");
00205     }
00206 }
00207 #else // _MSC_VER
00208 namespace mxflib
00209 {
00210     typedef long long Int64;            
00211     typedef unsigned long long UInt64;  
00212 }
00213 #endif // _MSC_VER
00214 
00215 
00216 
00217 // _WIN32 platform specific File I/O, GUID and time functions
00218 #ifdef _WIN32
00219 
00220 #include <windows.h>        
00221 #include <fcntl.h>          
00222 #include <sys/stat.h>       
00223 #include <sys/timeb.h>      
00224 
00225 #define DIR_SEPARATOR       '\\'
00226 #define PATH_SEPARATOR      ';'
00227 #ifndef DEFAULT_DICT_PATH
00228 #define DEFAULT_DICT_PATH   ".\\"
00229 #endif //DEFAULT_DICT_PATH
00230 
00231 namespace mxflib
00232 {
00233     /******** 64-bit file-I/O ********/
00234 #ifndef MXFLIB_NO_FILE_IO
00235     typedef int FileHandle;
00236     inline int FileSeek(FileHandle file, UInt64 offset) { return _lseeki64(file, offset, SEEK_SET) == -1 ? -1 : 0; }
00237     inline int FileSeekEnd(FileHandle file) { return _lseeki64(file, 0, SEEK_END) == -1 ? -1 : 0; }
00238     
00239     // DRAGONS: MSVC can't read or write more than 4Gb in one go currently
00240     inline size_t FileRead(FileHandle file, unsigned char *dest, size_t size) { return read(file, dest, (unsigned int)size); }
00241     inline size_t FileWrite(FileHandle file, const unsigned char *source, size_t size) { return write(file, source, (unsigned int)size); }
00242 
00243     inline int FileGetc(FileHandle file) { UInt8 c; return (FileRead(file, &c, 1) == 1) ? (int)c : EOF; }
00244     inline FileHandle FileOpen(const char *filename) { return open(filename, _O_BINARY | _O_RDWR ); }
00245     inline FileHandle FileOpenRead(const char *filename) { return open(filename, _O_BINARY | _O_RDONLY ); }
00246     inline FileHandle FileOpenNew(const char *filename) { return open(filename, _O_BINARY | _O_RDWR | _O_CREAT | _O_TRUNC, _S_IREAD | _S_IWRITE); }
00247     inline bool FileValid(FileHandle file) { return (file >= 0); }
00248     inline bool FileEof(FileHandle file) { return eof(file) ? true : false; }
00249     inline UInt64 FileTell(FileHandle file) { return _telli64(file); }
00250     inline void FileClose(FileHandle file) { close(file); }
00251     inline bool FileExists(const char *filename) { struct stat buf; return stat(filename, &buf) == 0; }
00252 #endif //MXFLIB_NO_FILE_IO
00253 
00254 
00255     /********* Acurate time *********/
00257     inline full_time GetTime(void)
00258     {
00259         full_time Ret;
00260         _timeb tb;
00261         _ftime(&tb);
00262         Ret.time = tb.time;
00263         Ret.msBy4 = tb.millitm / 4;
00264         return Ret;
00265     }
00266 
00267     /******** UUID Generation ********/
00268     inline void MakeUUID(UInt8 *Buffer)
00269     {
00270         CoCreateGuid(reinterpret_cast<GUID*>(Buffer));
00271     }
00272 
00274     inline bool IsAbsolutePath(const char *Filename)
00275     {
00276         if(*Filename == '\\') return true;
00277         if(*Filename == '/') return true;
00278         if(*Filename != '\0' && Filename[1] == ':') return true;
00279         return false;
00280     }
00281 }
00282 
00283 
00286 namespace mxflib
00287 {
00289     inline std::string OSName(void)
00290     {
00291         std::string Ret = "Windows";
00292 
00293         OSVERSIONINFOEX OSInfo;
00294 
00295         // Flag that we want the full info (if possible)
00296         OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
00297 
00298         BOOL Result = GetVersionEx((OSVERSIONINFO*)&OSInfo);
00299         if(!Result)
00300         {
00301             // Try the old version (we may be on an old version of Windows)
00302             OSInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00303             Result = GetVersionEx((OSVERSIONINFO*)&OSInfo);
00304         }
00305 
00306         if(Result)
00307         {
00308             if(OSInfo.dwMajorVersion == 4)
00309             {
00310                 if(OSInfo.dwPlatformId & VER_PLATFORM_WIN32_NT) Ret = "Windows NT";
00311                 else Ret = "Windows 95";
00312             }
00313             else if(OSInfo.dwMajorVersion == 5)
00314             {
00315                 if(OSInfo.dwMinorVersion == 0) Ret = "Windows 2000";
00316                 else if(OSInfo.dwMinorVersion == 1) Ret = "Windows XP";
00317                 else if(OSInfo.dwMinorVersion == 2) 
00318                 {
00319 #ifdef _MSC_VER
00320 #if _MSC_VER >= 1300
00321                     if(OSInfo.wProductType & VER_NT_SERVER) Ret = "Windows Server 2003";
00322                     else Ret = "Windows XP x64";
00323                     
00324                     if (0)  // Remove following pre-VC7 version
00325 #endif // _MSC_VER >= 1300
00326 #endif // _MSC_VER
00327                         Ret = "Windows Server 2003 or XP x64";
00328                 }
00329                 else if(OSInfo.dwMinorVersion == 10) Ret = "Windows 98";
00330                 else if(OSInfo.dwMinorVersion == 90) Ret = "Windows Me";
00331             }
00332             else if(OSInfo.dwMajorVersion == 6)
00333             {
00334                 if(OSInfo.dwMinorVersion == 0) 
00335                 {
00336 #ifdef _MSC_VER
00337 #if _MSC_VER >= 1300
00338                     if(OSInfo.wProductType & VER_NT_SERVER) Ret = "Windows Server \"Longhorn\"";
00339                     else Ret = "Windows Vista";
00340                     
00341                     if (0)  // Remove following pre-VC7 version
00342 #endif // _MSC_VER >= 1300
00343 #endif // _MSC_VER
00344                         Ret = "Windows Vista or Server \"Longhorn\"";
00345                 }
00346             }
00347 
00348             // Add any service pack details
00349             if(OSInfo.szCSDVersion)
00350             {
00351                 if(OSInfo.dwPlatformId & VER_PLATFORM_WIN32_WINDOWS)
00352                 {
00353                     if(OSInfo.szCSDVersion[1] == 'A') Ret += " Second Edition";
00354                     else if(OSInfo.szCSDVersion[1] == 'B') Ret += " Second Edition";
00355                     else if(OSInfo.szCSDVersion[1] == 'C') Ret += " OSR2";
00356                 }
00357                 else Ret += " " + std::string(OSInfo.szCSDVersion);
00358             }
00359         }
00360 
00361         return Ret;
00362     }
00363 }
00364 
00365 #endif // _WIN32
00366 
00367 
00368 #ifndef _MSC_VER
00369 // Support for all platforms with ISO C++ compilers using autoconf environment
00370 // including the _WIN32 platform with Mingw, Cygwin or Intel compilers.
00371 
00372 #include "config.h"     // generated by running ./configure
00373 #include <stdio.h>
00374 #include <string>
00375 #include <sys/time.h>
00376 #include <sys/types.h>
00377 #include <sys/stat.h>
00378 #include <unistd.h>
00379 
00380 #ifdef HAVE_STDINT_H
00381 #include <stdint.h>
00382 #else
00383 #define uintptr_t long
00384 #endif
00385 
00386 #ifdef HAVE_UUID_GENERATE
00387 #include <uuid/uuid.h>
00388 #endif
00389 
00390 namespace mxflib
00391 {
00392     /******** ENDIAN SWAPPING ********/
00393     inline UInt16 Swap(UInt16 Val) 
00394     { 
00395         if (!littleEndian)
00396             return Val;
00397         else
00398             return ((Val & 0xff00) >> 8) | ((Val & 0x00ff) << 8); 
00399     };
00400 
00401     inline Int16 Swap(Int16 Val) { return (Int16)Swap((UInt16)Val); }
00402     
00403     inline UInt32 Swap(UInt32 Val) 
00404     { 
00405         if (!littleEndian)
00406             return Val;
00407 
00408         return ( ((Val & 0xff000000) >> 24)
00409                | ((Val & 0x00ff0000) >> 8)
00410                | ((Val & 0x0000ff00) << 8)
00411                | ((Val & 0x000000ff) << 24) ); 
00412     }
00413     inline Int32 Swap(Int32 Val) { return (Int32)Swap((UInt32)Val); }
00414 
00415     inline UInt64 Swap(UInt64 Val) 
00416     {
00417         if (!littleEndian)
00418             return Val;
00419 
00420         UInt32 MSW = (UInt32)((Val & 0xffffffff00000000LL) >> 32);
00421         UInt32 LSW = (UInt32)(Val & 0x00000000ffffffff);
00422 
00423         MSW = Swap(MSW);
00424         LSW = Swap(LSW);
00425 
00426         return (((UInt64)LSW) << 32) | ((UInt64)MSW);
00427     }
00428     inline Int64 Swap(Int64 Val) { return (Int64)Swap((UInt64)Val); }
00429 
00430     
00431     /******** Int64 Conversion ********/
00432     inline Int64 ato_Int64(const char *str) { return strtoll(str, NULL, 10); }
00433     inline Int64 ato_UInt64(const char *str) { return strtoull(str, NULL, 10); }
00434 
00435     inline std::string Int64toString(Int64 Val)
00436     { 
00437         char Buffer[32];
00438         snprintf(Buffer, sizeof(Buffer) - 1, "%lld", Val);
00439         Buffer[31] = '\0';
00440         return std::string(Buffer);
00441     }
00442 
00443     inline std::string UInt64toString(UInt64 Val)
00444     { 
00445         char Buffer[32];
00446         snprintf(Buffer, sizeof(Buffer) - 1, "%llu", Val);
00447         Buffer[31] = '\0';
00448         return std::string(Buffer);
00449     }
00450 
00451     inline std::string Int64toHexString(Int64 Val, int Digits = 0)
00452     {
00453         char Buffer[32];
00454         if(Digits > 30) Digits = 30;
00455         sprintf(Buffer,"%0*llx", Digits, Val );
00456         return std::string(Buffer);
00457     }
00458 
00460     inline void PauseForInput(void)
00461     {
00462         printf("Press enter key...");
00463         getchar();
00464         printf("\n");
00465     }
00466 
00467 #ifndef _WIN32
00468 
00469 #define DIR_SEPARATOR       '/'
00470 #define PATH_SEPARATOR      ':'
00471 #ifndef DEFAULT_DICT_PATH
00472 #define DEFAULT_DICT_PATH   "/usr/local/share/mxflib/"
00473 #endif //DEFAULT_DICT_PATH
00474 
00475     /******** 64-bit file-I/O ********/
00476 #ifndef MXFLIB_NO_FILE_IO
00477     typedef FILE *FileHandle;
00478     inline int FileSeek(FileHandle file, UInt64 offset) { return fseeko(file, offset, SEEK_SET); }
00479     inline int FileSeekEnd(FileHandle file) { return fseeko(file, 0, SEEK_END); }
00480     inline size_t FileRead(FileHandle file, unsigned char *dest, size_t size) { return fread(dest, 1, size, file); }
00481     inline size_t FileWrite(FileHandle file, const unsigned char *source, size_t size) { return fwrite(source, 1, size, file); }
00482     inline int FileGetc(FileHandle file) { UInt8 c; return (FileRead(file, &c, 1) == 1) ? (int)c : EOF; }
00483     inline FileHandle FileOpen(const char *filename) { return fopen(filename, "r+b" ); }
00484     inline FileHandle FileOpenRead(const char *filename) { return fopen(filename, "rb" ); }
00485     inline FileHandle FileOpenNew(const char *filename) { return fopen(filename, "w+b"); }
00486     inline bool FileValid(FileHandle file) { return (file != NULL); }
00487     inline bool FileEof(FileHandle file) { return feof(file); }
00488     inline UInt64 FileTell(FileHandle file) { return ftello(file); }
00489     inline void FileClose(FileHandle file) { fclose(file); }
00490     inline bool FileExists(const char *filename) { struct stat buf; return stat(filename, &buf) == 0; }
00491 #endif //MXFLIB_NO_FILE_IO
00492 
00493     /********* Acurate time *********/
00495     inline full_time GetTime(void)
00496     {
00497         full_time Ret;
00498         struct timeval  tv;
00499 
00500         gettimeofday(&tv, NULL);
00501 
00502         Ret.time = tv.tv_sec;
00503         // msBy4 is in units of 0.025 seconds
00504         Ret.msBy4 = (int)(tv.tv_usec / 4000 + 0.5); // round to nearest 0.025s unit
00505         return Ret;
00506     }
00507 
00508     /******** UUID Generation ********/
00509 #ifdef HAVE_UUID_GENERATE
00510     inline void MakeUUID(UInt8 *Buffer)
00511     {
00512         uuid_t u;
00513         uuid_generate(u);
00514         memcpy(Buffer, &u, sizeof(u));
00515     }
00516 #else // HAVE_UUID_GENERATE
00517     inline void MakeUUID(UInt8 *Buffer)
00518     {
00519         static bool Inited = false;
00520         if(!Inited)
00521         {
00522             // Attempt a reasonably random seed to prevent duplicate UUIDs
00523             // The time is normally good enough as a seed, except multiple processes may run this code at the
00524             // same time across all machines in use at any time.  The address of the buffer will depend on the
00525             // target platform and other processes running on the same machine.  The value of clock() will
00526             // depend on how much CPU time has elapsed since the program started and is shifted to reduce the
00527             // chance that a system using the same granularity for this and time() will simply give the
00528             // program start time. Why also include a random number in the seed? Because if someone has already
00529             // seeded the generator with a decent random number this will be taken into account to prevent
00530             // degrading the randomness
00531             srand((time(NULL)) ^ ((uintptr_t)Buffer) ^ (clock() << 2) ^ rand());
00532             Inited = true;
00533         }
00534         int i;
00535         for(i=0; i<16; i++)
00536         {
00537             Buffer[i] = (UInt8)rand();
00538         }
00539 
00540         // Set reserved bits (variant "10" = ISO/IEC 11578)
00541         Buffer[8] &= 0x3f;
00542         Buffer[8] |= 0x80;
00543 
00544         // Set version bits (version "0100" = random or pseudo-random)
00545         Buffer[7] &= 0x0f;
00546         Buffer[7] |= 0x40;
00547     }
00548 #endif // HAVE_UUID_GENERATE
00549 
00551     inline bool IsAbsolutePath(const char *Filename)
00552     {
00553         if(*Filename == '/') return true;
00554         return false;
00555     }
00556 
00557 #endif // _WIN32
00558 }
00559 
00561 #define IsCommandLineSwitchPrefix(x) ( x == '-' )
00562 
00563 #ifndef UINT64_C
00564 #define UINT64_C(c) c##ULL      // for defining 64bit constants
00565 #endif // UINT64_C
00566 #ifndef INT64_C
00567 #define INT64_C(c)  c##ULL      // for defining 64bit constants
00568 #endif // INT64_C
00569 
00570 #include <assert.h>
00571 #define ASSERT assert       // use -DNDEBUG
00572 
00575 namespace mxflib
00576 {
00577     inline std::string OSName(void)
00578     {
00579         char *OSType = getenv("OSTYPE");
00580         char *MachType = getenv("MACHTYPE");
00581 
00582         std::string Ret;
00583         if(OSType)
00584         {
00585             Ret = OSType;
00586             if(MachType) Ret += " on " + std::string(MachType);
00587         }
00588         else
00589         {
00590             if(MachType) Ret = MachType; else Ret = "Unknown";
00591         }
00592     
00593         return Ret;
00594     }
00595 }
00596 
00597 #endif // not _WIN32
00598 
00599 /************************************************/
00600 /************************************************/
00601 
00602 // Support old capitalization of unsigned integers
00603 namespace mxflib
00604 {
00605     typedef UInt8 Uint8;
00606     typedef UInt16 Uint16;
00607     typedef UInt32 Uint32;
00608     typedef UInt64 Uint64;
00609     inline std::string Uint64toString(Uint64 Val) { return UInt64toString(Val); }
00610 }
00611 
00612 
00613 /*****************************************************/
00614 /*     Declarations for client supplied file-I/O     */
00615 /*****************************************************/
00616 // If File-I/O is supplied by the caller FileHandle will be defined as a UInt32
00617 // The caller may need to do something fancy to cope with this
00618 //
00619 #ifdef MXFLIB_NO_FILE_IO
00620 namespace mxflib
00621 { 
00622     typedef UInt32 FileHandle;
00623     int FileSeek(FileHandle file, UInt64 offset);
00624     int FileSeekEnd(FileHandle file);
00625     UInt64 FileRead(FileHandle file, unsigned char *dest, UInt64 size);
00626     UInt64 FileWrite(FileHandle file, const unsigned char *source, UInt64 size);
00627     int FileGetc(FileHandle file);
00628     FileHandle FileOpen(const char *filename);
00629     FileHandle FileOpenRead(const char *filename);
00630     FileHandle FileOpenNew(const char *filename);
00631     bool FileValid(FileHandle file);
00632     bool FileEof(FileHandle file);
00633     UInt64 FileTell(FileHandle file);
00634     void FileClose(FileHandle file);
00635     bool FileExists(const char *filename);
00636 }
00637 #endif // MXFLIB_NO_FILE_IO
00638 
00639 
00640 #endif // MXFLIB__SYSTEM_H

Generated on Mon Apr 2 15:20:54 2007 for MXFLib by  doxygen 1.5.1-p1