WvStreams
wvlistener.cc
1 /* -*- Mode: C++ -*-
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * A base implementation for "listeners", streams that spawn other streams
6  * from (presumably) incoming connections.
7  */
8 #include "wvlistener.h"
9 #include "wvistreamlist.h"
10 #include "wvaddr.h"
11 #include "wvmoniker.h"
12 
18 
19 
20 IWvListener *IWvListener::create(WvString moniker, IObject *obj)
21 {
22  IWvListener *l = wvcreate<IWvListener>(moniker, obj);
23  if (!l)
24  {
25  l = new WvNullListener();
26  l->seterr_both(EINVAL, "Unknown moniker '%s'", moniker);
27  }
28  return l;
29 }
30 
31 
32 WvListener::WvListener(IWvStream *_cloned)
33 {
34  cloned = _cloned;
35  wrapper = 0;
36 }
37 
38 
39 WvListener::~WvListener()
40 {
41  if (cloned)
42  WVRELEASE(cloned);
43  WvIStreamList::globallist.unlink(this);
44 }
45 
46 
47 static IWvStream *wrapper_runner(IWvListenerWrapper wrapper,
48  IWvStream *s)
49 {
50  return wrapper(s);
51 }
52 
53 
54 void WvListener::addwrap(IWvListenerWrapper _wrapper)
55 {
56  // What the heck is this, you ask?
57  // The idea is that we can support multiple layers of wrappers by
58  // creating recursive callbacks. When we add a wrapper and one already
59  // exists, we want to create a new one to essentially do newer(older(s))
60  // ...but only when it finally gets called.
61  if (wrapper)
62  wrapper = wv::bind(&wrapper_runner, _wrapper, _1);
63  else
64  wrapper = _wrapper;
65 }
66 
67 
68 void WvListener::callback()
69 {
70  if (acceptor)
71  {
72  IWvStream *s = accept();
73  if (s) acceptor(s);
74  }
75 }
76 
77 
78 IWvStream *WvListener::wrap(IWvStream *s)
79 {
80  if (wrapper && s)
81  return wrapper(s);
82  else
83  return s;
84 }
85 
86 
87 IWvListenerCallback WvListener::onaccept(IWvListenerCallback _cb)
88 {
89  IWvListenerCallback old = acceptor;
90  acceptor = _cb;
91  return old;
92 }
93 
94 
95 void WvListener::runonce(time_t msec_delay)
96 {
97  callback();
98 }
99 
100 
101 static WvStringAddr nulladdr("ERROR", WvEncap::Unknown);
102 const WvAddr *WvNullListener::src() const
103 {
104  return &nulladdr;
105 }
106 
107 WvString WvListener::getattr(WvStringParm name) const
108 {
109  WvString ret = attrs.get(name);
110  if (ret.isnull() && cloned)
111  return cloned->getattr(name);
112 
113  return ret;
114 }
WvListener
Definition: wvlistener.h:15
UUID_MAP_ENTRY
#define UUID_MAP_ENTRY(iface)
Add an entry to an interface map.
Definition: utils.h:68
WvStringAddr
A WvAddr that simply contains a printable string with a user-defined encapsulation type.
Definition: wvaddr.h:161
UUID_MAP_BEGIN
#define UUID_MAP_BEGIN(component)
Start the interface map for "component".
Definition: utils.h:63
IWvStream
Definition: iwvstream.h:24
IWvListener
Definition: iwvlistener.h:16
WvListener::onaccept
virtual IWvListenerCallback onaccept(IWvListenerCallback _cb)
Set a user-defined function to be called when a new connection is available.
Definition: wvlistener.cc:87
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvFastString::isnull
bool isnull() const
returns true if this string is null
Definition: wvstring.h:290
WvAddr
Base class for different address types, each of which will have the ability to convert itself to/from...
Definition: wvaddr.h:118
IWvListener::accept
virtual IWvStream * accept()=0
Accept a connection from this stream.
WvNullListener
This is a listener that doesn't work.
Definition: wvlistener.h:107
UUID_MAP_END
#define UUID_MAP_END
Marks the end of an interface map.
Definition: utils.h:80
IObject
Definition: IObject.h:65
WvListener::addwrap
virtual void addwrap(IWvListenerWrapper _wrapper)
Add a wrapper function for this stream: something that accept() will call to possibly wrap the stream...
Definition: wvlistener.cc:54