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