00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef W_OPAQUE_H
00031 #define W_OPAQUE_H
00032
00033 #include "w_defines.h"
00034
00035
00036
00037 #include <cctype>
00038 #include <cstring>
00039
00040 #ifndef W_BASE_H
00041 #include <w_base.h>
00042 #endif
00043
00044 #ifdef __GNUC__
00045
00046
00047
00048
00049 #if W_GCC_THIS_VER < W_GCC_VER(2,95)
00050 #define W_NO_TEMPLATE_FORWARD_DECLS
00051 #endif
00052 #endif
00053
00054 template <int LEN> class opaque_quantity;
00055 #ifndef W_NO_TEMPLATE_FORWARD_DECLS
00056 template <int LEN> ostream &operator<<(ostream &o,
00057 const opaque_quantity<LEN> &r);
00058 template <int LEN> bool operator==(const opaque_quantity<LEN> &l,
00059 const opaque_quantity<LEN> &r);
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 template <int LEN>
00074 class opaque_quantity
00075 {
00076
00077 private:
00078
00079 uint4_t _length;
00080 unsigned char _opaque[LEN];
00081
00082 public:
00083 opaque_quantity() {
00084 (void) set_length(0);
00085 #ifdef ZERO_INIT
00086 memset(_opaque, '\0', LEN);
00087 #endif
00088 }
00089 opaque_quantity(const char* s)
00090 {
00091 #ifdef ZERO_INIT
00092 memset(_opaque, '\0', LEN);
00093 #endif
00094 *this = s;
00095 }
00096
00097 friend bool
00098 operator== <LEN> (
00099 const opaque_quantity<LEN> &l,
00100 const opaque_quantity<LEN> &r);
00101
00102 friend ostream &
00103 operator<< <LEN> (
00104 ostream &o,
00105 const opaque_quantity<LEN> &b);
00106
00107 opaque_quantity<LEN> &
00108 operator=(const opaque_quantity<LEN> &r)
00109 {
00110 (void) set_length(r.length());
00111 memcpy(_opaque,r._opaque,length());
00112 return *this;
00113 }
00114 opaque_quantity<LEN> &
00115 operator=(const char* s)
00116 {
00117 w_assert9(strlen(s) <= LEN);
00118 (void) set_length(0);
00119 while ((_opaque[length()] = *s++))
00120 (void) set_length(length() + 1);
00121 return *this;
00122 }
00123 opaque_quantity<LEN> &
00124 operator+=(const char* s)
00125 {
00126 w_assert9(strlen(s) + length() <= LEN);
00127 while ((_opaque[set_length(length() + 1)] = *s++))
00128 ;
00129 return *this;
00130 }
00131 opaque_quantity<LEN> &
00132 operator-=(uint4_t len)
00133 {
00134 w_assert9(len <= length());
00135 (void) set_length(length() - len);
00136 return *this;
00137 }
00138 opaque_quantity<LEN> &
00139 append(const void* data, uint4_t len)
00140 {
00141 w_assert9(len + length() <= LEN);
00142 memcpy((void*)&_opaque[length()], data, len);
00143 (void) set_length(length() + len);
00144 return *this;
00145 }
00146 opaque_quantity<LEN> &
00147 zero()
00148 {
00149 (void) set_length(0);
00150 memset(_opaque, 0, LEN);
00151 return *this;
00152 }
00153 opaque_quantity<LEN> &
00154 clear()
00155 {
00156 (void) set_length(0);
00157 return *this;
00158 }
00159 void *
00160 data_at_offset(unsigned i) const
00161 {
00162 w_assert9(i < length());
00163 return (void*)&_opaque[i];
00164 }
00165 uint4_t wholelength() const {
00166 return (sizeof(_length) + length());
00167 }
00168 uint4_t set_length(uint4_t l) {
00169 if(is_aligned()) {
00170 _length = l;
00171 } else {
00172 char *m = (char *)&_length;
00173 memcpy(m, &l, sizeof(_length));
00174 }
00175 return l;
00176 }
00177 uint4_t length() const {
00178 if(is_aligned()) return _length;
00179 else {
00180 uint4_t l;
00181 char *m = (char *)&_length;
00182 memcpy(&l, m, sizeof(_length));
00183 return l;
00184 }
00185 }
00186
00187 void ntoh() {
00188 if(is_aligned()) {
00189 _length = w_base_t::w_ntohl(_length);
00190 } else {
00191 uint4_t l = w_base_t::w_ntohl(length());
00192 char *m = (char *)&l;
00193 memcpy(&_length, m, sizeof(_length));
00194 }
00195 }
00196 void hton() {
00197 if(is_aligned()) {
00198 _length = w_base_t::w_htonl(_length);
00199 } else {
00200 uint4_t l = w_base_t::w_htonl(length());
00201 char *m = (char *)&l;
00202 memcpy(&_length, m, sizeof(_length));
00203 }
00204 }
00205
00206
00207 bool is_aligned() const {
00208 return (((ptrdiff_t)(&_length) & (sizeof(_length) - 1)) == 0);
00209 }
00210
00211 ostream &print(ostream & o) const {
00212 o << "opaque[" << length() << "]" ;
00213
00214 uint4_t print_length = length();
00215 if (print_length > LEN) {
00216 o << "[TRUNC TO LEN=" << LEN << "!!]";
00217 print_length = LEN;
00218 }
00219 o << '"';
00220 const unsigned char *cp = &_opaque[0];
00221 for (uint4_t i = 0; i < print_length; i++, cp++) {
00222 if (isprint(*cp))
00223 o << *cp;
00224 else {
00225 W_FORM(o)("\\x%02X", *cp);
00226 }
00227 }
00228
00229 return o << '"';
00230 }
00231 };
00232
00233
00234 template <int LEN>
00235 bool operator==(const opaque_quantity<LEN> &a,
00236 const opaque_quantity<LEN> &b)
00237 {
00238 return ((a.length()==b.length()) &&
00239 (memcmp(a._opaque,b._opaque,a.length())==0));
00240 }
00241
00242 template <int LEN>
00243 ostream &
00244 operator<<(ostream &o, const opaque_quantity<LEN> &b)
00245 {
00246 return b.print(o);
00247 }
00248
00249
00250
00251 #endif