00001
00002
00003 #ifndef binpac_h
00004 #define binpac_h
00005
00006 #include <stdarg.h>
00007 #include <stdio.h>
00008 #include <string>
00009
00010 using namespace std;
00011
00012 namespace BinPAC
00013 {
00014
00015 const int bigendian = 0;
00016 const int littleendian = 1;
00017
00018 #ifndef pac_type_defs
00019 #define pac_type_defs
00020
00021 typedef char int8;
00022 typedef short int16;
00023 typedef long int32;
00024 typedef unsigned char uint8;
00025 typedef unsigned short uint16;
00026 typedef unsigned long uint32;
00027
00028 #endif
00029
00030
00031
00032 #include <sys/param.h>
00033
00034 #ifdef BYTE_ORDER
00035 # if BYTE_ORDER == BIG_ENDIAN
00036 # define HOST_BYTEORDER bigendian
00037 # elif BYTE_ORDER == LITTLE_ENDIAN
00038 # define HOST_BYTEORDER littleendian
00039 # else
00040 # error "Unknown BYTE_ORDER"
00041 # endif
00042 #else
00043 # error "BYTE_ORDER is not defined"
00044 #endif
00045
00046 static inline int16 pac_swap(int16 x)
00047 {
00048 return (x >> 8) | ((x & 0xff) << 8);
00049 }
00050
00051 static inline uint16 pac_swap(uint16 x)
00052 {
00053 return (x >> 8) | ((x & 0xff) << 8);
00054 }
00055
00056 static inline int32 pac_swap(int32 x)
00057 {
00058 return (x >> 24) |
00059 ((x & 0xff0000) >> 8) |
00060 ((x & 0xff00) << 8) |
00061 ((x & 0xff) << 24);
00062 }
00063
00064 static inline uint32 pac_swap(uint32 x)
00065 {
00066 return (x >> 24) |
00067 ((x & 0xff0000) >> 8) |
00068 ((x & 0xff00) << 8) |
00069 ((x & 0xff) << 24);
00070 }
00071
00072
00073
00074 template <class T>
00075 static inline T UnMarshall(const u_char *data, T &result,
00076 int byteorder)
00077 {
00078 result = 0;
00079 for ( int i = 0; i < sizeof(T); ++i )
00080 result = ( result << 8 ) |
00081 data[byteorder == bigendian ? i : sizeof(T) - 1 - i];
00082 return result;
00083 }
00084
00085 static const char* do_fmt(const char* format, va_list ap)
00086 {
00087 static char buf[1024];
00088 vsnprintf(buf, sizeof(buf), format, ap);
00089 return buf;
00090 }
00091
00092 static const char* fmt(const char* format, ...)
00093 {
00094 va_list ap;
00095 va_start(ap, format);
00096 const char* r = do_fmt(format, ap);
00097 va_end(ap);
00098 return r;
00099 }
00100
00101 class Exception
00102 {
00103 public:
00104 Exception(const char* m = "")
00105 : msg_("BinPAC exception: ")
00106 {
00107 append(m);
00108 #ifdef DEBUG
00109
00110 #endif
00111 }
00112
00113 void append(string m) { msg_ += m; }
00114 string msg() const { return msg_; }
00115 const char* c_msg() const { return msg().c_str(); }
00116
00117 protected:
00118 string msg_;
00119 };
00120
00121 class ExceptionOutOfBound : public Exception
00122 {
00123 public:
00124 ExceptionOutOfBound(const char* where, int len_needed, int len_given)
00125 {
00126 append(fmt("out_of_bound: %s: %d > %d",
00127 where, len_needed, len_given));
00128 }
00129 };
00130
00131 class ExceptionInvalidCase : public Exception
00132 {
00133 public:
00134 ExceptionInvalidCase(const char* arg_location,
00135 int arg_index, int arg_expected)
00136 : location(arg_location),
00137 index(arg_index), expected(arg_expected)
00138 {
00139 append(fmt("invalid case: %s: %d != %d",
00140 location, index, expected));
00141 }
00142
00143 protected:
00144 const char* location;
00145 int index, expected;
00146 };
00147
00148 class ExceptionInvalidCaseIndex : public Exception
00149 {
00150 public:
00151 ExceptionInvalidCaseIndex(const char* arg_location,
00152 int arg_index)
00153 : location(arg_location),
00154 index(arg_index)
00155 {
00156 append(fmt("invalid index for case: %s: %d",
00157 location, index));
00158 }
00159
00160 protected:
00161 const char* location;
00162 int index;
00163 };
00164
00165 class ExceptionInvalidOffset : public Exception
00166 {
00167 public:
00168 ExceptionInvalidOffset(const char* arg_location,
00169 int arg_min_offset, int arg_offset)
00170 : location(arg_location),
00171 min_offset(arg_min_offset), offset(arg_offset)
00172 {
00173 append(fmt("invalid offset: %s: min_offset = %d, offset = %d",
00174 location, min_offset, offset));
00175 }
00176
00177 protected:
00178 const char* location;
00179 int min_offset, offset;
00180 };
00181
00182 template <class T>
00183 struct array
00184 {
00185 T* v;
00186 int length;
00187
00188 T const & operator[](int index) const { check_index(index); return v[index]; }
00189 T & operator[](int index) { check_index(index); return v[index]; }
00190 int size() const { return length; }
00191 T const * begin() const { return v; }
00192 T const * end() const { return v + length; }
00193
00194 void check_index(int index) const
00195 {
00196 if ( index < 0 || index >= size() )
00197 throw Exception(fmt("array index out of bound: %d", index));
00198 }
00199 };
00200
00201 template <class T>
00202 static void make_array(array<T> &a, int len)
00203 {
00204 a.length = len;
00205 if ( len > 0 )
00206 a.v = new T[len];
00207 else
00208 a.v = 0;
00209 }
00210
00211 template <class T>
00212 static void delete_array(array<T> &a)
00213 {
00214 delete [] a.v;
00215 a.v = 0;
00216 }
00217
00218 }
00219
00220 #endif