00001 // Copyright (C) 2001, Compaq Computer Corporation 00002 // 00003 // This file is part of Vesta. 00004 // 00005 // Vesta is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // Vesta is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with Vesta; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 // Last modified on Tue Mar 22 14:40:25 EST 2005 by ken@xorian.net 00020 // modified on Mon Jun 16 11:07:40 PDT 1997 by heydon 00021 // modified on Tue Aug 8 11:33:37 PDT 1995 by levin 00022 00023 #ifndef _bytes_seq 00024 #define _bytes_seq 00025 00026 // ************************************************************** 00027 // * Supporting class for sequences of arbitrary byte strings * 00028 // ************************************************************** 00029 00030 #include <Basics.H> 00031 00032 struct byte_str { // "byte string" 00033 char *p; // pointer to first byte of string 00034 int l; // number of bytes in string 00035 00036 inline byte_str(char *p, int l) { this->p = p; this->l = l; }; 00037 }; 00038 00039 #include "bytes_seq_private.H" 00040 00041 class bytes_seq { 00042 friend class SRPC; 00043 friend class SRPC_impl; 00044 friend class bytes_seq_impl; 00045 public: 00046 00047 // Generic failure type, for exception handling. 00048 00049 struct failure { 00050 Text msg; 00051 inline failure(const Text &msg) { this->msg = msg; }; 00052 inline failure(const failure &f) { this->msg = f.msg; }; 00053 inline failure& operator=(const failure &f) { 00054 this->msg = f.msg; return *this; }; 00055 }; 00056 00057 // Construction 00058 00059 bytes_seq(int len_hint = 0, int bytes = 0); /* "auto" */ 00060 // This constructor creates a (logically empty) bytes_seq in dynamically 00061 // allocated storage. "len_hint" estimates the eventual length of the 00062 // sequence. If "bytes" is greater than 0, it specifies the number of 00063 // bytes of storage to be allocated to hold the bodies of byte sequences 00064 // (see "append", below). 00065 00066 bytes_seq(void **buffer, int bytes) throw(failure); /* "manual" */ 00067 // This constructor creates a (logically empty) bytes_seq in storage 00068 // provided by the client. "buffer" specifies the starting address of 00069 // of the storage, "bytes" specifies its extent. The buffer is used 00070 // for the byte string bodies, the sequence itself (i.e., the byte_str 00071 // structures), and a small amount of overhead. (It is typed 00072 // void** to emphasize the necessary alignment, even though its extent 00073 // is given in bytes.) For assistance in computing the "bytes" 00074 // paramter, see the "min_size" function, below. 00075 00076 ~bytes_seq(); 00077 // Any storage allocated by the "auto" constructor, the "full" constructor 00078 // or the "append" function (below) used on a bytes_seq created by the 00079 // "auto" constructor is deallocated. This destructor has no effect on 00080 // storage used by a bytes_seq created by the "manual" constructor. 00081 00082 static int min_size(int len); 00083 // This function returns the number of bytes required to hold a bytes_seq 00084 // of "len" empty byte strings. It is intended to assist the client in 00085 // computing a sufficient value for the "bytes" parameter to the 00086 // "manual" constructor. (Not inline because of compiler bug.) 00087 00088 // Sequence member access 00089 00090 inline byte_str ith(int i) const { return ((byte_str *)&p->base)[i]; }; 00091 // note: no bounds checking: in particular, no check for p == NULL 00092 00093 inline byte_str operator[](int i) const { return ith(i); }; 00094 // i.e., bs[i] is equivalent to bs.ith(i) 00095 00096 inline int length() const { return (p == NULL ? 0 : p->h.len); }; 00097 00098 // Adding members to the sequence 00099 00100 void append(const byte_str &b) throw(failure); 00101 // If the bytes_seq was created with "auto" constructor, the byte string 00102 // pointed to by 'b' is copied to dynamically allocated storage and a 00103 // pointer to the copy is appended to the sequence. Storage allocated 00104 // at construction time is used first, if available; additional storage 00105 // is allocated as necessary. If the bytes_seq was created with the 00106 // "manual" constructor and has sufficient space in the buffer provided 00107 // at construction time, the byte string pointed to by 'b' is 00108 // copied to the buffer and a pointer to the copy is appended to the 00109 // sequence. Otherwise, "failure" is thrown. 00110 00111 inline void operator+=(const byte_str &b) throw(failure) { append(b); }; 00112 // i.e., bs += b is equivalent to bs.append(b) 00113 00114 private: 00115 bytes_seq_impl::rep *p; 00116 00117 // A bytes_seq can be neither copied nor assigned. 00118 00119 bytes_seq(const bytes_seq &); 00120 bytes_seq(bytes_seq &); 00121 // Copy constructor; should never be accessed. 00122 00123 void operator=(bytes_seq &); 00124 00125 }; 00126 00127 00128 #endif /* _bytes_seq */