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