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