w_opaque.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='W_OPAQUE_H'>
00002 
00003  $Id: w_opaque.h,v 1.7 2010/05/26 01:20:12 nhall Exp $
00004 
00005 SHORE -- Scalable Heterogeneous Object REpository
00006 
00007 Copyright (c) 1994-99 Computer Sciences Department, University of
00008                       Wisconsin -- Madison
00009 All Rights Reserved.
00010 
00011 Permission to use, copy, modify and distribute this software and its
00012 documentation is hereby granted, provided that both the copyright
00013 notice and this permission notice appear in all copies of the
00014 software, derivative works or modified versions, and any portions
00015 thereof, and that both notices appear in supporting documentation.
00016 
00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00021 
00022 This software was developed with support by the Advanced Research
00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00025 Further funding for this work was provided by DARPA through
00026 Rome Research Laboratory Contract No. F30602-97-2-0247.
00027 
00028 */
00029 
00030 #ifndef W_OPAQUE_H
00031 #define W_OPAQUE_H
00032 
00033 #include "w_defines.h"
00034 
00035 /*  -- do not edit anything above this line --   </std-header>*/
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 /* XXX gcc-2.7.2.3 has some weird problem with forward template function
00046    declarations.   The easiest way (for now) is to just not do it.
00047    This should be moved to w_workaround once the other similar
00048    issues are accounted for. */
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 /**\brief A set of untyped bytes. 
00063  *
00064  * \details 
00065  *
00066  * This is just a blob.  Not necessarily large object,
00067  * but it is an untyped group of bytes. Used for
00068  * global transaction IDs and server IDs for two-phase
00069  * commit.  The storage manager has to log this information
00070  * for preparing a 2PC transaction, so it has to flow
00071  * through the API.
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     /* XXX why doesn't this use the aligned macros? */
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 /*<std-footer incl-file-exclusion='W_OPAQUE_H'>  -- do not edit anything below this line -- */
00250 
00251 #endif          /*</std-footer>*/

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7