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_