include/Base.h
author Jens Alfke <jens@mooseyard.com>
Tue Sep 29 15:46:42 2009 -0700 (2009-09-29)
changeset 9 629f61203db1
parent 8 21a6c17f4e3e
permissions -rw-r--r--
* Merged in jbm's changes for Linux compatibility, fixing Mac compatibility in the process :)
* Fixed two regressions having to do with the _previousTrailerPosition in VersionDictionary.cpp.
* Made sure RTTI is enabled in the OttomanTest target because gtest requires it.
     1 /*
     2  *  Base.h
     3  *  Ottoman
     4  *
     5  *  Created by Jens Alfke on 8/18/09.
     6  *  Copyright 2009 Jens Alfke. All rights reserved.
     7  *  BSD-Licensed: See the file "LICENSE.txt" for details.
     8  */
     9 
    10 #ifndef _MOOSEYARD_BASE_
    11 #define _MOOSEYARD_BASE_
    12 #include <stdlib.h>
    13 #include <stdint.h>
    14 #include <string.h>
    15 
    16 #ifdef __MACH__ /* OS X specific bits */
    17 #include <CoreFoundation/CFByteOrder.h>
    18 #endif
    19 
    20 namespace Mooseyard {
    21     
    22     /** A 32-bit file position/offset. Supports files of up to 4GB. */
    23     typedef uint32_t FilePosition;
    24     const FilePosition kNoFilePosition = (FilePosition)-1L;
    25     
    26 
    27     /** A simple structure representing a range of memory (a pointer plus a length).
    28         It doesn't do any memory management; it just points. */
    29     struct Blob {
    30         const void *bytes;
    31         size_t length;
    32         
    33         Blob()                                                  :bytes(NULL), length(0) { }
    34         Blob (const void *b, size_t len)                        :bytes(b), length(len) { }
    35         Blob (const char *str);
    36         const void* end() const                                 {return (const uint8_t*)bytes+length;}
    37         
    38         operator bool() const                                   {return bytes!=NULL;}
    39         bool operator== (const Blob &b)                         {return bytes==b.bytes && length==b.length;}
    40         bool equals (const Blob &b) const                       {return length==b.length && memcmp(bytes,b.bytes,length)==0;}
    41         void clear()                                            {bytes=NULL; length=0;}
    42     };
    43 
    44     
    45     // Utility to offset a pointer by some number of bytes.
    46     inline const void* offsetBy(const void *src, size_t off)   {return (const uint8_t*)src + off;}
    47     inline void* offsetBy(void *src, size_t off)               {return (uint8_t*)src + off;}
    48     
    49     
    50     #define UNCOPYABLE(CLASS)  private: CLASS(const CLASS&);  CLASS& operator=(const CLASS&)
    51     
    52     
    53 #pragma mark -
    54 #pragma mark LITTLE-ENDIAN:
    55     
    56     /** A template for numeric types that are always stored in little-endian form.
    57         Useful for structures stored in files that need to be useable on all architectures. */
    58     template <typename INT, typename REP=INT>
    59     class LittleEndian {
    60     public:
    61         inline LittleEndian ();
    62         inline LittleEndian (INT);
    63         inline operator INT() const;
    64         inline LittleEndian& operator= (INT);
    65         inline LittleEndian& operator= (const LittleEndian&);
    66         inline LittleEndian& operator++();
    67         inline LittleEndian& operator--();
    68     private:
    69         static inline REP makeLittle (INT);
    70         static inline INT makeNative (REP);
    71         REP _value;
    72     };
    73     
    74     typedef LittleEndian<double,CFSwappedFloat64> LittleEndianDouble;
    75     
    76 
    77     // Implementation gunk:
    78     template <typename INT, typename REP>
    79     inline LittleEndian<INT,REP>::LittleEndian ()               :_value() { }
    80     template <typename INT, typename REP>
    81     inline LittleEndian<INT,REP>::LittleEndian (INT i)          :_value(makeLittle(i)) { }
    82     template <typename INT, typename REP>
    83     inline LittleEndian<INT,REP>::operator INT() const          {return makeNative(_value);}
    84     template <typename INT, typename REP>
    85     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator++() {return *this = (INT)*this + 1;}
    86     template <typename INT, typename REP>
    87     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator--() {return *this = (INT)*this - 1;}
    88     
    89     template <typename INT, typename REP>
    90     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (INT i) {
    91         _value = makeLittle(i);
    92         return *this;
    93     }
    94     template <typename INT, typename REP>
    95     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (const LittleEndian<INT,REP> &p) {
    96         _value = p._value;
    97         return *this;
    98     }
    99    
   100 #ifdef __COREFOUNDATION_CFBYTEORDER__
   101     template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
   102     {return OSSwapHostToLittleInt32(i);}
   103     template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
   104     {return OSSwapLittleToHostInt32(i);}
   105     template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i) 
   106     {return OSSwapHostToLittleInt16(i);}
   107     template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i) 
   108     {return OSSwapLittleToHostInt16(i);}
   109     template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d) 
   110     {return CFConvertDoubleHostToSwapped(d);}
   111     template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
   112     {return CFConvertDoubleSwappedToHost(d);}
   113 #else
   114     //FIXME: Not implemented yet for non-Mac platforms
   115     template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
   116     {return i;}
   117     template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
   118     {return i;}
   119     template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i) 
   120     {return i;}
   121     template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i) 
   122     {return i;}
   123     template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d) 
   124     {return d;}
   125     template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
   126     {return d;}
   127 #endif
   128 }
   129 
   130 #endif /* _MOOSEYARD_BASE_ */