w_opaque.h

00001 /*<std-header orig-src='shore' incl-file-exclusion='W_OPAQUE_H'>
00002 
00003  $Id: w_opaque.h,v 1.8 2010/12/08 17:37:34 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 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 /**\brief A set of untyped bytes. 
00051  *
00052  * \details 
00053  *
00054  * This is just a blob.  Not necessarily large object,
00055  * but it is an untyped group of bytes. Used for
00056  * global transaction IDs and server IDs for two-phase
00057  * commit.  The storage manager has to log this information
00058  * for preparing a 2PC transaction, so it has to flow
00059  * through the API.
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     /* XXX why doesn't this use the aligned macros? */
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 /*<std-footer incl-file-exclusion='W_OPAQUE_H'>  -- do not edit anything below this line -- */
00238 
00239 #endif          /*</std-footer>*/

Generated on Thu Dec 9 08:42:26 2010 for Shore Storage Manager by  doxygen 1.4.7