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
if (
logp)
delete 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->count())
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 (strlen(
trim_string(newline)) > 0)
00147 (*logp)(
"Read: %s\n",
trim_string(newline));
00148
00149 free(newline);
00150
00151
return next_token();
00152 }
00153
00154
00155
00156
00157
00158 int WvProtoStream::tokanal(
const Token &t,
char **lookup,
00159
bool case_sensitive)
00160 {
00161 assert(
lookup);
00162
00163
char **i;
00164
00165
for (i =
lookup; *i; i++)
00166 {
00167
if ( (!case_sensitive && !strcasecmp(t.
data, *i))
00168 || ( case_sensitive && !strcmp(t.
data, *i)) )
00169
return i -
lookup;
00170 }
00171
00172
return -1;
00173 }
00174
00175
00176 void WvProtoStream::do_state(
Token &)
00177 {
00178 }
00179
00180
00181 void WvProtoStream::switch_state(
int newstate)
00182 {
00183
state = newstate;
00184 }
00185
00186
00187
00188
00189
00190 void WvProtoStream::execute()
00191 {
00192
WvStreamClone::execute();
00193
00194
Token *t1 =
tokline(getline(0));
00195
00196
if (t1)
00197 {
00198
do_state(*t1);
00199
delete t1;
00200 }
00201 }
00202
00203
00204
00205
00206
00207
00208
00209 WvProtoStream::Token::Token()
00210 {
00211
00212 }
00213
00214
00215 WvProtoStream::Token::Token(
const unsigned char *_data, size_t _length)
00216 {
00217
fill(_data, _length);
00218 }
00219
00220
00221 void WvProtoStream::Token::fill(
const unsigned char *_data,
00222 size_t _length)
00223 {
00224
length = _length;
00225
00226
data.
setsize(
length + 1);
00227 memcpy(
data.
edit(), _data,
length);
00228
data.
edit()[
length] = 0;
00229 }
00230
00231
00232 WvProtoStream::Token::~Token()
00233 {
00234
00235 }