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 template <int LEN> class opaque_quantity;
00045 template <int LEN> ostream &operator<<(ostream &o,
00046 const opaque_quantity<LEN> &r);
00047 template <int LEN> bool operator==(const opaque_quantity<LEN> &l,
00048 const opaque_quantity<LEN> &r);
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 template <int LEN>
00062 class opaque_quantity
00063 {
00064
00065 private:
00066
00067 uint4_t _length;
00068 unsigned char _opaque[LEN];
00069
00070 public:
00071 opaque_quantity() {
00072 (void) set_length(0);
00073 #ifdef ZERO_INIT
00074 memset(_opaque, '\0', LEN);
00075 #endif
00076 }
00077 opaque_quantity(const char* s)
00078 {
00079 #ifdef ZERO_INIT
00080 memset(_opaque, '\0', LEN);
00081 #endif
00082 *this = s;
00083 }
00084
00085 friend bool
00086 operator== <LEN> (
00087 const opaque_quantity<LEN> &l,
00088 const opaque_quantity<LEN> &r);
00089
00090 friend ostream &
00091 operator<< <LEN> (
00092 ostream &o,
00093 const opaque_quantity<LEN> &b);
00094
00095 opaque_quantity<LEN> &
00096 operator=(const opaque_quantity<LEN> &r)
00097 {
00098 (void) set_length(r.length());
00099 memcpy(_opaque,r._opaque,length());
00100 return *this;
00101 }
00102 opaque_quantity<LEN> &
00103 operator=(const char* s)
00104 {
00105 w_assert9(strlen(s) <= LEN);
00106 (void) set_length(0);
00107 while ((_opaque[length()] = *s++))
00108 (void) set_length(length() + 1);
00109 return *this;
00110 }
00111 opaque_quantity<LEN> &
00112 operator+=(const char* s)
00113 {
00114 w_assert9(strlen(s) + length() <= LEN);
00115 while ((_opaque[set_length(length() + 1)] = *s++))
00116 ;
00117 return *this;
00118 }
00119 opaque_quantity<LEN> &
00120 operator-=(uint4_t len)
00121 {
00122 w_assert9(len <= length());
00123 (void) set_length(length() - len);
00124 return *this;
00125 }
00126 opaque_quantity<LEN> &
00127 append(const void* data, uint4_t len)
00128 {
00129 w_assert9(len + length() <= LEN);
00130 memcpy((void*)&_opaque[length()], data, len);
00131 (void) set_length(length() + len);
00132 return *this;
00133 }
00134 opaque_quantity<LEN> &
00135 zero()
00136 {
00137 (void) set_length(0);
00138 memset(_opaque, 0, LEN);
00139 return *this;
00140 }
00141 opaque_quantity<LEN> &
00142 clear()
00143 {
00144 (void) set_length(0);
00145 return *this;
00146 }
00147 void *
00148 data_at_offset(unsigned i) const
00149 {
00150 w_assert9(i < length());
00151 return (void*)&_opaque[i];
00152 }
00153 uint4_t wholelength() const {
00154 return (sizeof(_length) + length());
00155 }
00156 uint4_t set_length(uint4_t l) {
00157 if(is_aligned()) {
00158 _length = l;
00159 } else {
00160 char *m = (char *)&_length;
00161 memcpy(m, &l, sizeof(_length));
00162 }
00163 return l;
00164 }
00165 uint4_t length() const {
00166 if(is_aligned()) return _length;
00167 else {
00168 uint4_t l;
00169 char *m = (char *)&_length;
00170 memcpy(&l, m, sizeof(_length));
00171 return l;
00172 }
00173 }
00174
00175 void ntoh() {
00176 if(is_aligned()) {
00177 _length = w_base_t::w_ntohl(_length);
00178 } else {
00179 uint4_t l = w_base_t::w_ntohl(length());
00180 char *m = (char *)&l;
00181 memcpy(&_length, m, sizeof(_length));
00182 }
00183 }
00184 void hton() {
00185 if(is_aligned()) {
00186 _length = w_base_t::w_htonl(_length);
00187 } else {
00188 uint4_t l = w_base_t::w_htonl(length());
00189 char *m = (char *)&l;
00190 memcpy(&_length, m, sizeof(_length));
00191 }
00192 }
00193
00194
00195 bool is_aligned() const {
00196 return (((ptrdiff_t)(&_length) & (sizeof(_length) - 1)) == 0);
00197 }
00198
00199 ostream &print(ostream & o) const {
00200 o << "opaque[" << length() << "]" ;
00201
00202 uint4_t print_length = length();
00203 if (print_length > LEN) {
00204 o << "[TRUNC TO LEN=" << LEN << "!!]";
00205 print_length = LEN;
00206 }
00207 o << '"';
00208 const unsigned char *cp = &_opaque[0];
00209 for (uint4_t i = 0; i < print_length; i++, cp++) {
00210 if (isprint(*cp))
00211 o << *cp;
00212 else {
00213 W_FORM(o)("\\x%02X", *cp);
00214 }
00215 }
00216
00217 return o << '"';
00218 }
00219 };
00220
00221
00222 template <int LEN>
00223 bool operator==(const opaque_quantity<LEN> &a,
00224 const opaque_quantity<LEN> &b)
00225 {
00226 return ((a.length()==b.length()) &&
00227 (memcmp(a._opaque,b._opaque,a.length())==0));
00228 }
00229
00230 template <int LEN>
00231 ostream &
00232 operator<<(ostream &o, const opaque_quantity<LEN> &b)
00233 {
00234 return b.print(o);
00235 }
00236
00237
00238
00239 #endif