Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members

binpac.h

Go to the documentation of this file.
00001 // $Id: binpac.h,v 1.2 2005/09/07 17:33:56 vern Exp $
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 /* pac_type_defs */
00029 
00030 /* Handling byte order */
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 // #define FixByteOrder(byteorder, x)   (byteorder == HOST_BYTEORDER ? (x) : pac_swap(x))
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                 // abort();
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 } // namespace BinPAC
00219 
00220 #endif /* binpac_h */

Generated on Wed Sep 14 02:55:58 2005 for bro_docs by doxygen 1.3.5