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 13:45:08 EST 2005 by ken@xorian.net 00020 // modified on Mon Jun 16 11:07:39 PDT 1997 by heydon 00021 // modified on Tue Aug 8 11:32:39 PDT 1995 by levin 00022 00023 #ifndef _chars_seq 00024 #define _chars_seq 00025 00026 // ********************************************************* 00027 // * Supporting class for sequences of character strings * 00028 // ********************************************************* 00029 00030 #include <Basics.H> 00031 #include "chars_seq_private.H" 00032 00033 class chars_seq { 00034 friend class SRPC; 00035 friend class SRPC_impl; 00036 friend class chars_seq_impl; 00037 public: 00038 00039 // Generic failure type, for exception handling. 00040 00041 struct failure { 00042 Text msg; 00043 inline failure(const Text &msg) { this->msg = msg; }; 00044 inline failure(const failure &f) { this->msg = f.msg; }; 00045 inline failure& operator=(const failure &f) { 00046 this->msg = f.msg; return *this; }; 00047 }; 00048 00049 // Construction 00050 00051 typedef char *chars; 00052 00053 chars_seq(int len_hint = 0, int bytes = 0); /* "auto" */ 00054 // This constructor creates a (logically empty) chars_seq in dynamically 00055 // allocated storage. "len_hint" estimates the eventual length of the 00056 // sequence. If "bytes" is greater than 0, it specifies the number of 00057 // bytes of storage to be initially allocated to hold the bodies of 00058 // strings (see "append", below). 00059 00060 chars_seq(void **buffer, int bytes) throw(failure); /* "manual" */ 00061 // This constructor creates a (logically empty) chars_seq in storage 00062 // provided by the client. "buffer" specifies the starting address of 00063 // of the storage, "bytes" specifies its extent. The buffer is used 00064 // for the string bodies, the sequence itself (i.e., the pointers to 00065 // the string bodies), and a small amount of overhead. (It is typed 00066 // void** to emphasize the necessary alignment, even though its extent 00067 // is given in bytes.) For assistance in computing the "bytes" 00068 // paramter, see the "min_size" function, below. 00069 00070 chars_seq(const char **seq, int len) throw(failure); /* auto */ 00071 // This constructor creates a fully filled-in chars_seq from an existing 00072 // sequence of strings. The "seq" and "len" parameters specify the address 00073 // and length of a sequence of pointers to null-terminated character 00074 // strings. 00075 00076 ~chars_seq(); 00077 // Any storage allocated by the "auto" constructor, the "full" constructor 00078 // or the "append" function (below) used on a chars_seq created by the 00079 // "auto" constructor is deallocated. This destructor has no effect on 00080 // storage used by a chars_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 chars_seq 00084 // of "len" empty 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 // Conversion to char** 00089 00090 inline operator chars*() const { return (p == NULL ? NULL : &p->base); }; 00091 // Warning! The result returned by this function is valid only as long 00092 // as the underlying storage exists. In particular, if the chars_seq is 00093 // destroyed, the pointer becomes invalid. Moreover, an "append" or 00094 // "append-ptr" operation that expands storage may render invalid a result 00095 // previously returned by this function. Use with care! 00096 00097 // Sequence member access 00098 00099 inline chars ith(int i) const { return ((chars *)&p->base)[i]; }; 00100 // note: no bounds checking: in particular, no check for p == NULL 00101 00102 inline chars operator[](int i) const { return ith(i); }; 00103 // i.e., cs[i] is equivalent to cs.ith(i) 00104 00105 inline int length() const { return (p == NULL ? 0 : p->h.len); }; 00106 00107 // Adding members to the sequence 00108 00109 void append(const chars s) throw(failure); 00110 // If the chars_seq was created with "auto" constructor, 's' is copied to 00111 // dynamically allocated storage and a pointer to the copy is appended to 00112 // the sequence. Storage allocated at construction time is used first, 00113 // if available; otherwise, additional storage is allocated as necessary. 00114 // If the chars_seq was created with the "manual" constructor and has 00115 // sufficient space in the buffer provided at construction time, 's' is 00116 // copied to the buffer and a pointer to the copy is appended to the 00117 // sequence. Otherwise, "failure" is thrown. 00118 00119 void append(const Text &t) throw(failure); 00120 // This function is semantically equivalent to: 00121 // append(t.chars()); 00122 00123 inline void operator+=(const chars s) throw(failure) { append(s); }; 00124 // i.e., cs += s is equivalent to cs.append(s) 00125 00126 inline void operator+=(const Text &t) throw(failure) { append(t); }; 00127 // i.e., cs += t is equivalent to cs.append(t) 00128 00129 private: 00130 chars_seq_impl::rep *p; 00131 00132 // A chars_seq can be neither copied nor assigned. 00133 00134 chars_seq(const chars_seq &); 00135 chars_seq(chars_seq &); 00136 // Copy constructor; should never be accessed. 00137 00138 void operator=(chars_seq &); 00139 00140 }; 00141 00142 00143 #endif /* _chars_seq */