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