WvStreams
|
00001 /* -*- Mode: C++ -*- 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2002 Net Integration Technologies, Inc. 00004 * 00005 * A base implementation for "listeners", streams that spawn other streams 00006 * from (presumably) incoming connections. 00007 */ 00008 #include "wvlistener.h" 00009 #include "wvistreamlist.h" 00010 #include "wvaddr.h" 00011 #include "wvmoniker.h" 00012 00013 UUID_MAP_BEGIN(WvListener) 00014 UUID_MAP_ENTRY(IObject) 00015 UUID_MAP_ENTRY(IWvStream) 00016 UUID_MAP_ENTRY(IWvListener) 00017 UUID_MAP_END 00018 00019 00020 IWvListener *IWvListener::create(WvString moniker, IObject *obj) 00021 { 00022 IWvListener *l = wvcreate<IWvListener>(moniker, obj); 00023 if (!l) 00024 { 00025 l = new WvNullListener(); 00026 l->seterr_both(EINVAL, "Unknown moniker '%s'", moniker); 00027 } 00028 return l; 00029 } 00030 00031 00032 WvListener::WvListener(IWvStream *_cloned) 00033 { 00034 cloned = _cloned; 00035 wrapper = 0; 00036 } 00037 00038 00039 WvListener::~WvListener() 00040 { 00041 if (cloned) 00042 WVRELEASE(cloned); 00043 WvIStreamList::globallist.unlink(this); 00044 } 00045 00046 00047 static IWvStream *wrapper_runner(IWvListenerWrapper wrapper, 00048 IWvStream *s) 00049 { 00050 return wrapper(s); 00051 } 00052 00053 00054 void WvListener::addwrap(IWvListenerWrapper _wrapper) 00055 { 00056 // What the heck is this, you ask? 00057 // The idea is that we can support multiple layers of wrappers by 00058 // creating recursive callbacks. When we add a wrapper and one already 00059 // exists, we want to create a new one to essentially do newer(older(s)) 00060 // ...but only when it finally gets called. 00061 if (wrapper) 00062 wrapper = wv::bind(&wrapper_runner, _wrapper, _1); 00063 else 00064 wrapper = _wrapper; 00065 } 00066 00067 00068 void WvListener::callback() 00069 { 00070 if (acceptor) 00071 { 00072 IWvStream *s = accept(); 00073 if (s) acceptor(s); 00074 } 00075 } 00076 00077 00078 IWvStream *WvListener::wrap(IWvStream *s) 00079 { 00080 if (wrapper && s) 00081 return wrapper(s); 00082 else 00083 return s; 00084 } 00085 00086 00087 IWvListenerCallback WvListener::onaccept(IWvListenerCallback _cb) 00088 { 00089 IWvListenerCallback old = acceptor; 00090 acceptor = _cb; 00091 return old; 00092 } 00093 00094 00095 void WvListener::runonce(time_t msec_delay) 00096 { 00097 callback(); 00098 } 00099 00100 00101 static WvStringAddr nulladdr("ERROR", WvEncap::Unknown); 00102 const WvAddr *WvNullListener::src() const 00103 { 00104 return &nulladdr; 00105 } 00106 00107 WvString WvListener::getattr(WvStringParm name) const 00108 { 00109 WvString ret = attrs.get(name); 00110 if (ret.isnull() && cloned) 00111 return cloned->getattr(name); 00112 00113 return ret; 00114 }