00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "wvprotostream.h"
00010 #include "wvlog.h"
00011 #include "strutils.h"
00012 #include <ctype.h>
00013 #include <assert.h>
00014
00015
00016 WvProtoStream::WvProtoStream(WvStream **_cloned, WvLog *_debuglog)
00017 : WvStreamClone(_cloned)
00018 {
00019 if (_debuglog)
00020 logp = new WvLog(_debuglog->split(WvLog::Debug3));
00021 else
00022 logp = NULL;
00023
00024 log_enable = true;
00025 state = 0;
00026 }
00027
00028
00029 WvProtoStream::~WvProtoStream()
00030 {
00031 if (logp) delete logp;
00032 }
00033
00034
00035
00036
00037
00038 size_t WvProtoStream::uwrite(const void *buf, size_t size)
00039 {
00040 if (logp && log_enable)
00041 {
00042 (*logp)("Sent: ");
00043 logp->write(buf, size);
00044 (*logp)("\n");
00045 }
00046
00047 return WvStreamClone::uwrite(buf, size);
00048 }
00049
00050
00051 WvProtoStream::Token *WvProtoStream::next_token()
00052 {
00053 static unsigned char whitespace[] = " \t\r\n";
00054 size_t len;
00055
00056
00057 tokbuf.get(tokbuf.match(whitespace, sizeof(whitespace)));
00058
00059
00060 len = tokbuf.match(whitespace, sizeof(whitespace), true);
00061 return len ? new Token(tokbuf.get(len), len) : NULL;
00062 }
00063
00064
00065 WvString WvProtoStream::next_token_str()
00066 {
00067 Token *t = next_token();
00068 if (!t) return WvString("");
00069
00070 WvString s(t->data);
00071 delete t;
00072 return s;
00073 }
00074
00075
00076 WvString WvProtoStream::token_remaining()
00077 {
00078 tokbuf.put("", 1);
00079 return trim_string((char *)tokbuf.get(tokbuf.used()));
00080 }
00081
00082
00083
00084
00085
00086 WvProtoStream::TokenList *WvProtoStream::tokenize()
00087 {
00088 TokenList *tl = new TokenList;
00089 Token *t;
00090
00091 while ((t = next_token()) != NULL)
00092 tl->append(t, true);
00093 #if 0
00094 if (logp && log_enable && tl->count())
00095 {
00096 (*logp)("Read: ");
00097 TokenList::Iter i(*tl);
00098 for (i.rewind(); i.next(); )
00099 (*logp)("(%s) ", i.data);
00100 (*logp)("\n");
00101 }
00102 #endif
00103 return tl;
00104 }
00105
00106
00107
00108
00109
00110
00111 size_t WvProtoStream::list_to_array(TokenList *tl, Token **array)
00112 {
00113 size_t total = tl->count(), count;
00114
00115 assert(array);
00116 *array = new Token[total];
00117
00118 TokenList::Iter i(*tl);
00119 for (count = 0, i.rewind(); i.next(); count++)
00120 {
00121 Token &t = i;
00122 (*array)[count].fill((unsigned char *)(const char *)t.data, t.length);
00123 }
00124
00125 delete tl;
00126 return count;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 WvProtoStream::Token *WvProtoStream::tokline(const char *line)
00137 {
00138 if (!line) return NULL;
00139
00140 char *newline = strdup(line);
00141
00142 tokbuf.zap();
00143 tokbuf.put(line, strlen(line));
00144
00145 if (strlen(trim_string(newline)) > 0)
00146 (*logp)("Read: %s\n", trim_string(newline));
00147
00148 free(newline);
00149
00150 return next_token();
00151 }
00152
00153
00154
00155
00156
00157 int WvProtoStream::tokanal(const Token &t, char **lookup,
00158 bool case_sensitive)
00159 {
00160 assert(lookup);
00161
00162 char **i;
00163
00164 for (i = lookup; *i; i++)
00165 {
00166 if ( (!case_sensitive && !strcasecmp(t.data, *i))
00167 || ( case_sensitive && !strcmp(t.data, *i)) )
00168 return i - lookup;
00169 }
00170
00171 return -1;
00172 }
00173
00174
00175 void WvProtoStream::do_state(Token &)
00176 {
00177 }
00178
00179
00180 void WvProtoStream::switch_state(int newstate)
00181 {
00182 state = newstate;
00183 }
00184
00185
00186
00187
00188
00189 void WvProtoStream::execute()
00190 {
00191 WvStreamClone::execute();
00192
00193 Token *t1 = tokline(getline(0));
00194
00195 if (t1)
00196 {
00197 do_state(*t1);
00198 delete t1;
00199 }
00200 }
00201
00202
00203
00205
00206
00207
00208 WvProtoStream::Token::Token()
00209 {
00210
00211 }
00212
00213
00214 WvProtoStream::Token::Token(const unsigned char *_data, size_t _length)
00215 {
00216 fill(_data, _length);
00217 }
00218
00219
00220 void WvProtoStream::Token::fill(const unsigned char *_data,
00221 size_t _length)
00222 {
00223 length = _length;
00224
00225 data.setsize(length + 1);
00226 memcpy(data.edit(), _data, length);
00227 data.edit()[length] = 0;
00228 }
00229
00230
00231 WvProtoStream::Token::~Token()
00232 {
00233
00234 }