Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

uniclientconn.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Tunnel Vision Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Manages a connection between the UniConf client and daemon.
00006  */
00007 #include "uniclientconn.h"
00008 #include "wvaddr.h"
00009 #include "wvtclstring.h"
00010 #include "strutils.h"
00011 
00012 /***** UniClientConn *****/
00013 
00014 const UniClientConn::CommandInfo UniClientConn::cmdinfos[
00015     UniClientConn::NUM_COMMANDS] = {
00016     // requests
00017     { "noop", "noop: verify that the connection is active" },
00018     { "get", "get <key>: get the value of a key" },
00019     { "set", "set <key> <value>: sets the value of a key" },
00020     { "del", "del <key>: deletes the key" },
00021     { "subt", "subt <key>: enumerates the children of a key" },
00022     { "hchild", "hchild <key>: returns whether a key has children" },
00023     { "quit", "quit: kills the session nicely" },
00024     { "help", "help: returns this help text" },
00025     
00026     // command completion replies
00027     { "OK", "OK <payload>: reply on command success" },
00028     { "FAIL", "FAIL <payload>: reply on command failure" },
00029     { "CHILD", "CHILD <key> TRUE / FALSE: key has children or not" },
00030     { "ONEVAL", "ONEVAL <key> <value>: reply to a get" },
00031 
00032     // partial replies
00033     { "VAL", "VAL <key> <value>: intermediate reply value of a key" },
00034     { "TEXT", "TEXT <text>: intermediate reply of a text message" },
00035 
00036     // events
00037     { "HELLO", "HELLO <message>: sent by server on connection" },
00038     { "NOTICE", "NOTICE <key> <oldval> <newval>: forget key and its children" },
00039 };
00040 
00041 
00042 UniClientConn::UniClientConn(IWvStream *_s, WvStringParm dst) :
00043     WvStreamClone(_s),
00044     log(WvString("UniConf to %s", dst.isnull() ? *_s->src() : WvString(dst)),
00045     WvLog::Debug5), closed(false), payloadbuf("")
00046 {
00047     WvIStreamList::globallist.append(this, false);
00048     log("Opened\n");
00049 }
00050 
00051 
00052 UniClientConn::~UniClientConn()
00053 {
00054     WvIStreamList::globallist.unlink(this);
00055     close();
00056 }
00057 
00058 
00059 bool UniClientConn::pre_select(SelectInfo &si)
00060 {
00061     if (si.wants.readable && msgbuf.used()) return true;
00062     return WvStreamClone::pre_select(si);
00063 }
00064 
00065     
00066 bool UniClientConn::isok() const
00067 {
00068     return msgbuf.used() != 0 || WvStreamClone::isok();
00069 }
00070 
00071 
00072 void UniClientConn::close()
00073 {
00074     if (! closed)
00075     {
00076         closed = true;
00077         WvStreamClone::close();
00078         log("Closed\n");
00079     }
00080 }
00081 
00082 
00083 WvString UniClientConn::readmsg()
00084 {
00085     WvString word;
00086     while ((word = wvtcl_getword(msgbuf, "\r\n", false)).isnull())
00087     {
00088         char *line = getline(0);
00089         if (line)
00090         {
00091             msgbuf.putstr(line);
00092             msgbuf.put('\n');
00093         }
00094         else
00095         {
00096             if (!isok())
00097             {
00098                 // possibly left some incomplete command behind
00099                 msgbuf.zap();
00100             }
00101             return WvString::null;
00102         }
00103     }
00104     if (!!word)
00105         log("Read: %s\n", word);
00106     return word;
00107 }
00108 
00109 
00110 void UniClientConn::writemsg(WvStringParm msg)
00111 {
00112     write(WvString("%s\n", msg));
00113     log("Wrote: %s\n", msg);
00114 }
00115 
00116 
00117 UniClientConn::Command UniClientConn::readcmd()
00118 {
00119     for (;;)
00120     {
00121         WvString msg(readmsg());
00122         if (msg.isnull())
00123             return NONE;
00124 
00125         // extract command, leaving the remainder in payloadbuf
00126         payloadbuf.reset(msg);
00127         WvString cmd(readarg());
00128         if (cmd.isnull())
00129             return NONE;
00130 
00131         for (int i = 0; i < NUM_COMMANDS; ++i)
00132             if (strcasecmp(cmdinfos[i].name, cmd.cstr()) == 0)
00133                 return Command(i);
00134         return INVALID;
00135     }
00136 }
00137 
00138 
00139 WvString UniClientConn::readarg()
00140 {
00141     return wvtcl_getword(payloadbuf);
00142 }
00143 
00144 
00145 void UniClientConn::writecmd(UniClientConn::Command cmd, WvStringParm msg)
00146 {
00147     if (msg)
00148         writemsg(WvString("%s %s", cmdinfos[cmd].name, msg));
00149     else
00150         writemsg(cmdinfos[cmd].name);
00151 }
00152 
00153 
00154 void UniClientConn::writeok(WvStringParm payload)
00155 {
00156     writecmd(REPLY_OK, payload);
00157 }
00158 
00159 
00160 void UniClientConn::writefail(WvStringParm payload)
00161 {
00162     writecmd(REPLY_FAIL, payload);
00163 }
00164 
00165 
00166 void UniClientConn::writevalue(const UniConfKey &key, WvStringParm value)
00167 {
00168     writecmd(PART_VALUE, WvString("%s %s", wvtcl_escape(key),
00169         wvtcl_escape(value)));
00170 }
00171 
00172 
00173 void UniClientConn::writeonevalue(const UniConfKey &key, WvStringParm value)
00174 {
00175     writecmd(REPLY_ONEVAL, WvString("%s %s", wvtcl_escape(key),
00176         wvtcl_escape(value)));
00177 }
00178 
00179 
00180 void UniClientConn::writetext(WvStringParm text)
00181 {
00182     writecmd(PART_TEXT, wvtcl_escape(text));
00183 }

Generated on Wed Dec 15 15:08:10 2004 for WvStreams by  doxygen 1.3.9.1