00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <Basics.H>
00023 #include <Generics.H>
00024 #include <SRPC.H>
00025 #include <sstream>
00026
00027 #include "FV2.H"
00028
00029 using std::ostream;
00030 using std::ostringstream;
00031
00032
00033
00034
00035
00036 const char Delim = '/';
00037
00038
00039
00040
00041 const int MaxLen = 128;
00042
00043 void FV2::T::FromStr(const char *str, const char delim) throw ()
00044 {
00045 const char *start = str;
00046 while (true) {
00047 const char *match = index(start, (int)delim);
00048 if (match != NULL) {
00049 int subLen = (match - start);
00050 this->addhi(Text(start, subLen));
00051 start = match + 1;
00052 } else {
00053 this->addhi(Text(start));
00054 break;
00055 }
00056 }
00057 }
00058
00059 char* FV2::T::ToStr(char *buff, const int sz, char delim, char type)
00060 const throw ()
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 {
00072 char *res = buff;
00073
00074
00075 int i;
00076 int totalLen;
00077 if (type != '\0') {
00078 assert(sz >= 2);
00079 res[0] = type;
00080 res[1] = delim;
00081 totalLen = 2;
00082 } else {
00083 totalLen = 0;
00084 }
00085 for (i = 0; i < this->size(); i++) {
00086 Text txt = this->get(i);
00087 int len = txt.Length();
00088 if (totalLen + len >= sz) break;
00089 memcpy(res+totalLen, txt.cchars(), len);
00090 totalLen += len;
00091 res[totalLen++] = delim;
00092 }
00093
00094
00095 if (i < this->size()) {
00096
00097
00098
00099 int curr = totalLen;
00100 for (int j = i; j < this->size(); j++) {
00101 totalLen += this->get(j).Length() + 1;
00102 }
00103
00104
00105 char *newBuff = NEW_PTRFREE_ARRAY(char, totalLen);
00106 memcpy(newBuff, res, curr);
00107 res = newBuff;
00108
00109
00110 for (; i < this->size(); i++) {
00111 Text txt = this->get(i);
00112 int len = txt.Length();
00113 assert(curr + len < totalLen);
00114 memcpy(res+curr, txt.cchars(), len);
00115 curr += len;
00116 res[curr++] = delim;
00117 }
00118 assert(curr == totalLen);
00119 }
00120 totalLen--;
00121 res[totalLen] = '\0';
00122 return res;
00123 }
00124
00125 Text FV2::T::ToText(const char delim) const throw ()
00126 {
00127 char fixedBuff[MaxLen];
00128 char *buff = ToStr(fixedBuff, MaxLen, delim);
00129 return Text(buff);
00130 }
00131
00132 void FV2::T::Send(SRPC &srpc, char type) const throw (SRPC::failure)
00133 {
00134 char stackBuff[MaxLen];
00135 char *buff = this->ToStr(stackBuff, MaxLen, Delim, type);
00136
00137
00138
00139
00140 bool l_bad_arc = false;
00141 unsigned int l_bad_arc_index = 0;
00142 for (unsigned int i = 0; !l_bad_arc && (i < this->size()); i++)
00143 {
00144 if(this->get(i).FindChar(Delim) != -1)
00145 {
00146 l_bad_arc = true;
00147 l_bad_arc_index = i;
00148 }
00149 }
00150
00151
00152 if(l_bad_arc)
00153 {
00154 ostringstream l_msg;
00155 l_msg << "Free variable arc containing delimiter character ('" << Delim << "'):\n"
00156 << " arc = " << this->get(l_bad_arc_index) << "\n"
00157 << " path = " << buff;
00158
00159 throw SRPC::failure(SRPC::invalid_parameter, Text(l_msg.str()));
00160 }
00161
00162
00163 srpc.send_chars(buff);
00164 }
00165
00166 ostream& operator << (ostream &os, const FV2::T &t) throw ()
00167 {
00168 t.Print(os);
00169 return os;
00170 }
00171
00172 void FV2::T::Print(ostream &os) const throw()
00173 {
00174 char fixedBuff[MaxLen];
00175 char *buff = this->ToStr(fixedBuff, MaxLen, '/');
00176 os << buff;
00177 }
00178
00179
00180
00181 void FV2::List::Send(SRPC &srpc, const char *types) const throw (SRPC::failure)
00182
00183
00184
00185 {
00186 srpc.send_seq_start(this->len);
00187 for (int i = 0; i < this->len; i++) {
00188 this->name[i]->Send(srpc, types[i]);
00189 }
00190 srpc.send_seq_end();
00191 }
00192
00193 int FV2::ListApp::Append(FV2::T *s) throw ()
00194 {
00195 int res;
00196 if (len == maxLen) {
00197 maxLen = max(2, 2 * maxLen);
00198 assert(maxLen > len);
00199 FV2::TPtr *newNames = NEW_ARRAY(FV2::TPtr, maxLen);
00200 if (name != (FV2::TPtr *)NULL) {
00201 for (int i = 0; i < len; i++) newNames[i] = name[i];
00202 }
00203 name = newNames;
00204 }
00205 res = len;
00206 name[len++] = s;
00207 return res;
00208 }
00209
00210 ostream& operator << (ostream &os, const FV2::List &names) throw ()
00211 {
00212 os << "{ ";
00213 for (int i = 0; i < names.len; i++) {
00214 os << "\"" << names.name[i] << "\"";
00215 if (i < names.len - 1) os << ", ";
00216 }
00217 os << " }";
00218 return os;
00219 }
00220
00221 inline void Indent(ostream &os, int indent) throw ()
00222 {
00223 for (int i = 0; i < indent; i++) os << " ";
00224 }
00225
00226 void FV2::List::Print(ostream &os, int indent, const char *types) const
00227 throw ()
00228 {
00229 if (this->len > 0) {
00230 for (int i = 0; i < this->len; i++) {
00231 Indent(os, indent);
00232 #if 0
00233
00234
00235 os << "nm[" << i << "] = ";
00236 os << types[i] << " <\"";
00237 for (int j = 0; j < this->name[i]->size(); j++)
00238 {
00239 if(j > 0)
00240 {
00241 os << "\", \"";
00242 }
00243 os << this->name[i]->get(j);
00244 }
00245 os << "\">" << endl;
00246 #else
00247 os << "nm[" << i << "] = \"";
00248 os << types[i] << '/' << *(this->name[i]) << "\"\n";
00249 #endif
00250 }
00251 } else {
00252 Indent(os, indent);
00253 os << "<< no names >>\n";
00254 }
00255 }