include/Base.h
author jbm@humility
Mon Sep 28 23:39:08 2009 -0700 (2009-09-28)
changeset 8 21a6c17f4e3e
parent 0 31a43d94cc26
child 9 629f61203db1
permissions -rw-r--r--
jbm: it compiles... but bombs in unit tests
     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 #if OSX
    17 /* OS X specific bits */
    18 #include <libkern/OSByteOrder.h>
    19 #include <CoreFoundation/CFByteOrder.h>
    20 
    21 #else
    22 /* OS X fixup kludge bits */
    23 
    24 #include <cf_fixup.h>
    25 #include <stdint.h>
    26 
    27 #endif
    28 
    29 namespace Mooseyard {
    30     
    31     /** A 32-bit file position/offset. Supports files of up to 4GB. */
    32     typedef uint32_t FilePosition;
    33     const FilePosition kNoFilePosition = (FilePosition)-1L;
    34     
    35 
    36     /** A simple structure representing a range of memory (a pointer plus a length).
    37         It doesn't do any memory management; it just points. */
    38     struct Blob {
    39         const void *bytes;
    40         size_t length;
    41         
    42         Blob()                                                  :bytes(NULL), length(0) { }
    43         Blob (const void *b, size_t len)                        :bytes(b), length(len) { }
    44         Blob (const char *str);
    45         const void* end() const                                 {return (const uint8_t*)bytes+length;}
    46         
    47         operator bool() const                                   {return bytes!=NULL;}
    48         bool operator== (const Blob &b)                         {return bytes==b.bytes && length==b.length;}
    49         bool equals (const Blob &b) const                       {return length==b.length && memcmp(bytes,b.bytes,length)==0;}
    50         void clear()                                            {bytes=NULL; length=0;}
    51     };
    52 
    53     
    54     // Utility to offset a pointer by some number of bytes.
    55     inline const void* offsetBy(const void *src, size_t off)   {return (const uint8_t*)src + off;}
    56     inline void* offsetBy(void *src, size_t off)               {return (uint8_t*)src + off;}
    57     
    58     
    59     #define UNCOPYABLE(CLASS)  private: CLASS(const CLASS&);  CLASS& operator=(const CLASS&)
    60     
    61     
    62 #pragma mark -
    63 #pragma mark LITTLE-ENDIAN:
    64     
    65     /** A template for numeric types that are always stored in little-endian form.
    66         Useful for structures stored in files that need to be useable on all architectures. */
    67     template <typename INT, typename REP=INT>
    68     class LittleEndian {
    69     public:
    70         inline LittleEndian ();
    71         inline LittleEndian (INT);
    72         inline operator INT() const;
    73         inline LittleEndian& operator= (INT);
    74         inline LittleEndian& operator= (const LittleEndian&);
    75         inline LittleEndian& operator++();
    76         inline LittleEndian& operator--();
    77     private:
    78         static inline REP makeLittle (INT);
    79         static inline INT makeNative (REP);
    80         REP _value;
    81     };
    82     
    83     typedef LittleEndian<double,CFSwappedFloat64> LittleEndianDouble;
    84     
    85 
    86     // Implementation gunk:
    87     template <typename INT, typename REP>
    88     inline LittleEndian<INT,REP>::LittleEndian ()               :_value() { }
    89     template <typename INT, typename REP>
    90     inline LittleEndian<INT,REP>::LittleEndian (INT i)          :_value(makeLittle(i)) { }
    91     template <typename INT, typename REP>
    92     inline LittleEndian<INT,REP>::operator INT() const          {return makeNative(_value);}
    93     template <typename INT, typename REP>
    94     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator++() {return *this = (INT)*this + 1;}
    95     template <typename INT, typename REP>
    96     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator--() {return *this = (INT)*this - 1;}
    97     
    98     template <typename INT, typename REP>
    99     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (INT i) {
   100         _value = makeLittle(i);
   101         return *this;
   102     }
   103     template <typename INT, typename REP>
   104     inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (const LittleEndian<INT,REP> &p) {
   105         _value = p._value;
   106         return *this;
   107     }
   108     
   109     template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
   110     {return OSSwapHostToLittleInt32(i);}
   111     template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
   112     {return OSSwapLittleToHostInt32(i);}
   113     template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i) 
   114     {return OSSwapHostToLittleInt16(i);}
   115     template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i) 
   116     {return OSSwapLittleToHostInt16(i);}
   117     template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d) 
   118     {return CFConvertDoubleHostToSwapped(d);}
   119     template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
   120     {return CFConvertDoubleSwappedToHost(d);}
   121     
   122 }
   123 
   124 #endif /* _MOOSEYARD_BASE_ */