00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef __GNUG__
00024 # pragma implementation "StreamSplitter.h"
00025 #endif
00026
00027 #include "StrMod/StreamSplitter.h"
00028 #include <cassert>
00029
00030
00031 namespace strmod {
00032 namespace strmod {
00033
00034 namespace {
00035 static StreamSplitterModule test;
00036 };
00037
00038 const STR_ClassIdent StreamSplitterModule::identifier(10UL);
00039 const STR_ClassIdent StreamSplitterModule::SPPlug::identifier(11UL);
00040
00041 StreamSplitterModule::StreamSplitterModule()
00042 : inplug_(*this, SideIn),
00043 outplug_(*this, SideOut),
00044 biplug_(*this, SideBiDir)
00045 {
00046 flags_.inmade = flags_.outmade = flags_.bimade = false;
00047 }
00048
00049 StreamSplitterModule::~StreamSplitterModule()
00050 {
00051 }
00052
00053 bool StreamSplitterModule::deletePlug(Plug *plug)
00054 {
00055
00056 if (!ownsPlug(plug))
00057 {
00058 return(false);
00059 }
00060
00061 if (&inplug_ == plug)
00062 {
00063 flags_.inmade = 0;
00064 }
00065 else if (&outplug_ == plug)
00066 {
00067 flags_.outmade = 0;
00068 }
00069 else if (&biplug_ == plug)
00070 {
00071 flags_.bimade = 0;
00072 }
00073
00074 if (plug->pluggedInto() != NULL)
00075 {
00076 plug->unPlug();
00077 }
00078
00079 return(true);
00080 }
00081
00082 void StreamSplitterModule::plugDisconnected(Plug *plug)
00083 {
00084 switch (plug->side())
00085 {
00086 case SideIn:
00087 biplug_.setReadable(false);
00088 break;
00089 case SideOut:
00090 biplug_.setWriteable(false);
00091 break;
00092 case SideBiDir:
00093 inplug_.setWriteable(false);
00094 outplug_.setReadable(false);
00095 break;
00096 }
00097 StreamModule::plugDisconnected(plug);
00098 }
00099
00100 StreamModule::Plug *StreamSplitterModule::i_MakePlug(int side)
00101 {
00102 switch (side) {
00103 case SideIn:
00104 if (! flags_.inmade)
00105 {
00106 flags_.inmade = true;
00107 return(&inplug_);
00108 }
00109 break;
00110 case SideOut:
00111 if (! flags_.outmade)
00112 {
00113 flags_.outmade = true;
00114 return(&outplug_);
00115 }
00116 break;
00117 case SideBiDir:
00118 if (!flags_.bimade)
00119 {
00120 flags_.bimade = true;
00121 return(&biplug_);
00122 }
00123
00124 }
00125 return(NULL);
00126 }
00127
00128 const StrChunkPtr StreamSplitterModule::SPPlug::i_Read()
00129 {
00130
00131
00132 SPPlug *partner = getReadPartner();
00133 assert(partner != NULL);
00134 assert(partner->pluggedInto() != NULL);
00135
00136 Plug *other = partner->pluggedInto();
00137 setIsReading(*other, true);
00138 const StrChunkPtr chunk = partner->readOther();
00139 setIsReading(*other, false);
00140 other = partner->pluggedInto();
00141
00142 setReadable((other == NULL) ? false : getFlagsFrom(*other).canread_);
00143
00144 return(chunk);
00145 }
00146
00147 void StreamSplitterModule::SPPlug::i_Write(const StrChunkPtr &ptr)
00148 {
00149
00150
00151 SPPlug *partner = getWritePartner();
00152 assert(partner != NULL);
00153 assert(partner->pluggedInto() != NULL);
00154
00155 Plug *other = partner->pluggedInto();
00156 setIsWriting(*other, true);
00157 partner->writeOther(ptr);
00158 setIsWriting(*other, false);
00159 other = partner->pluggedInto();
00160
00161 setWriteable((other == NULL) ? false : getFlagsFrom(*other).canwrite_);
00162 }
00163
00164 void StreamSplitterModule::SPPlug::otherIsReadable()
00165 {
00166
00167
00168 SPPlug *partner = getWritePartner();
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 if (partner != NULL)
00180 {
00181 Plug *other = pluggedInto();
00182
00183 partner->setReadable((other != NULL) && getFlagsFrom(*other).canread_);
00184 }
00185 }
00186
00187 void StreamSplitterModule::SPPlug::otherIsWriteable()
00188 {
00189
00190
00191 SPPlug *partner = getReadPartner();
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 if (partner != NULL)
00204 {
00205 Plug *other = pluggedInto();
00206
00207 partner->setWriteable((other != NULL) && getFlagsFrom(*other).canwrite_);
00208 }
00209 }
00210
00211 };
00212 };