include/Base.h
changeset 0 31a43d94cc26
child 8 21a6c17f4e3e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/include/Base.h	Sun Sep 20 15:14:12 2009 -0700
     1.3 @@ -0,0 +1,113 @@
     1.4 +/*
     1.5 + *  Base.h
     1.6 + *  Ottoman
     1.7 + *
     1.8 + *  Created by Jens Alfke on 8/18/09.
     1.9 + *  Copyright 2009 Jens Alfke. All rights reserved.
    1.10 + *  BSD-Licensed: See the file "LICENSE.txt" for details.
    1.11 + */
    1.12 +
    1.13 +#ifndef _MOOSEYARD_BASE_
    1.14 +#define _MOOSEYARD_BASE_
    1.15 +#include <stdlib.h>
    1.16 +#include <stdint.h>
    1.17 +#include <string.h>
    1.18 +#include <libkern/OSByteOrder.h>
    1.19 +#include <CoreFoundation/CFByteOrder.h>
    1.20 +
    1.21 +namespace Mooseyard {
    1.22 +    
    1.23 +    /** A 32-bit file position/offset. Supports files of up to 4GB. */
    1.24 +    typedef uint32_t FilePosition;
    1.25 +    const FilePosition kNoFilePosition = (FilePosition)-1L;
    1.26 +    
    1.27 +
    1.28 +    /** A simple structure representing a range of memory (a pointer plus a length).
    1.29 +        It doesn't do any memory management; it just points. */
    1.30 +    struct Blob {
    1.31 +        const void *bytes;
    1.32 +        size_t length;
    1.33 +        
    1.34 +        Blob()                                                  :bytes(NULL), length(0) { }
    1.35 +        Blob (const void *b, size_t len)                        :bytes(b), length(len) { }
    1.36 +        Blob (const char *str);
    1.37 +        const void* end() const                                 {return (const uint8_t*)bytes+length;}
    1.38 +        
    1.39 +        operator bool() const                                   {return bytes!=NULL;}
    1.40 +        bool operator== (const Blob &b)                         {return bytes==b.bytes && length==b.length;}
    1.41 +        bool equals (const Blob &b) const                       {return length==b.length && memcmp(bytes,b.bytes,length)==0;}
    1.42 +        void clear()                                            {bytes=NULL; length=0;}
    1.43 +    };
    1.44 +
    1.45 +    
    1.46 +    // Utility to offset a pointer by some number of bytes.
    1.47 +    inline const void* offsetBy(const void *src, size_t off)   {return (const uint8_t*)src + off;}
    1.48 +    inline void* offsetBy(void *src, size_t off)               {return (uint8_t*)src + off;}
    1.49 +    
    1.50 +    
    1.51 +    #define UNCOPYABLE(CLASS)  private: CLASS(const CLASS&);  CLASS& operator=(const CLASS&)
    1.52 +    
    1.53 +    
    1.54 +#pragma mark -
    1.55 +#pragma mark LITTLE-ENDIAN:
    1.56 +    
    1.57 +    /** A template for numeric types that are always stored in little-endian form.
    1.58 +        Useful for structures stored in files that need to be useable on all architectures. */
    1.59 +    template <typename INT, typename REP=INT>
    1.60 +    class LittleEndian {
    1.61 +    public:
    1.62 +        inline LittleEndian ();
    1.63 +        inline LittleEndian (INT);
    1.64 +        inline operator INT() const;
    1.65 +        inline LittleEndian& operator= (INT);
    1.66 +        inline LittleEndian& operator= (const LittleEndian&);
    1.67 +        inline LittleEndian& operator++();
    1.68 +        inline LittleEndian& operator--();
    1.69 +    private:
    1.70 +        static inline REP makeLittle (INT);
    1.71 +        static inline INT makeNative (REP);
    1.72 +        REP _value;
    1.73 +    };
    1.74 +    
    1.75 +    typedef LittleEndian<double,CFSwappedFloat64> LittleEndianDouble;
    1.76 +    
    1.77 +
    1.78 +    // Implementation gunk:
    1.79 +    template <typename INT, typename REP>
    1.80 +    inline LittleEndian<INT,REP>::LittleEndian ()               :_value() { }
    1.81 +    template <typename INT, typename REP>
    1.82 +    inline LittleEndian<INT,REP>::LittleEndian (INT i)          :_value(makeLittle(i)) { }
    1.83 +    template <typename INT, typename REP>
    1.84 +    inline LittleEndian<INT,REP>::operator INT() const          {return makeNative(_value);}
    1.85 +    template <typename INT, typename REP>
    1.86 +    inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator++() {return *this = (INT)*this + 1;}
    1.87 +    template <typename INT, typename REP>
    1.88 +    inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator--() {return *this = (INT)*this - 1;}
    1.89 +    
    1.90 +    template <typename INT, typename REP>
    1.91 +    inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (INT i) {
    1.92 +        _value = makeLittle(i);
    1.93 +        return *this;
    1.94 +    }
    1.95 +    template <typename INT, typename REP>
    1.96 +    inline LittleEndian<INT,REP>& LittleEndian<INT,REP>::operator= (const LittleEndian<INT,REP> &p) {
    1.97 +        _value = p._value;
    1.98 +        return *this;
    1.99 +    }
   1.100 +    
   1.101 +    template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i) 
   1.102 +    {return OSSwapHostToLittleInt32(i);}
   1.103 +    template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i) 
   1.104 +    {return OSSwapLittleToHostInt32(i);}
   1.105 +    template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i) 
   1.106 +    {return OSSwapHostToLittleInt16(i);}
   1.107 +    template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i) 
   1.108 +    {return OSSwapLittleToHostInt16(i);}
   1.109 +    template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d) 
   1.110 +    {return CFConvertDoubleHostToSwapped(d);}
   1.111 +    template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d) 
   1.112 +    {return CFConvertDoubleSwappedToHost(d);}
   1.113 +    
   1.114 +}
   1.115 +
   1.116 +#endif _MOOSEYARD_BASE_