00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "WOscContainer.h"
00041 #include "WOscException.h"
00042 #include <string.h>
00043 #include <iostream>
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 WOscContainer::WOscContainer(const WOscContainerInfo& info, int defNumChildren, int defNumMethods)
00068 {
00069
00070
00071 m_parent = NULL;
00072
00073 m_containerEntries.reserve(defNumChildren);
00074 m_methodEntries.reserve(defNumMethods);
00075
00076
00077 m_info = info;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 WOscContainer::WOscContainer(WOscContainer* parent, const char* name, const WOscContainerInfo& info, int defNumChildren, int defNumMethods){
00109
00110 if ( parent == NULL )
00111 throw WOscException(ERR_PARENT_POINTER_NULL, __FILE__, __LINE__);
00112
00113 m_parent = parent;
00114 m_info = info;
00115
00116 m_containerEntries.reserve(defNumChildren);
00117 m_methodEntries.reserve(defNumMethods);
00118
00119 m_parent->AddContainer(this, name, false);
00120 }
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130 WOscContainer::~WOscContainer()
00131 {
00132
00133
00134
00135 std::vector<WOscContainerEntry> containers = m_containerEntries;
00136 for ( std::vector<WOscContainerEntry>::iterator it = containers.begin(); it < containers.end(); it++ )
00137 if ( ! it->m_isAlias )
00138 ((WOscContainer*)FindRoot())->RecursivelyRemoveAliases(it->m_container);
00139
00140
00141 for ( int i = m_containerEntries.size()-1; i >= 0; i-- )
00142 if ( ! m_containerEntries[i].m_isAlias ) {
00143 delete m_containerEntries[i].m_container;
00144 }
00145 m_containerEntries.clear();
00146
00147
00148
00149
00150 std::vector<WOscMethodEntry> methods = m_methodEntries;
00151 for ( std::vector<WOscMethodEntry>::iterator it = methods.begin(); it < methods.end(); it++ )
00152 if ( ! it->m_isAlias )
00153 ((WOscContainer*)FindRoot())->RecursivelyRemoveAliases(it->m_method);
00154
00155
00156 for ( int i = m_methodEntries.size()-1; i >= 0; i-- )
00157 if ( ! m_methodEntries[i].m_isAlias )
00158 delete m_methodEntries[i].m_method;
00159 m_methodEntries.clear();
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 void
00169 WOscContainer::RemoveAll()
00170 {
00171 delete FindRoot();
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void
00191 WOscContainer::AddContainerAlias(WOscContainer* parent, const char* alias)
00192 {
00193 if ( m_parent == NULL )
00194 throw WOscException(ERR_ROOT_ALIAS, __FILE__, __LINE__);
00195
00196 if ( parent == this )
00197 throw WOscException(ERR_RECURSIVE_ALIAS, __FILE__, __LINE__);
00198
00199 if ( parent == NULL )
00200 throw WOscException(ERR_PARENT_POINTER_NULL, __FILE__, __LINE__);
00201
00202 parent->AddContainer(this, alias, true);
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 void
00222 WOscContainer::AddMethod(WOscMethod* method, const char* name, bool isAlias)
00223 {
00224 WOscMethodEntry entry;
00225 entry.m_name = name;
00226 entry.m_isAlias = isAlias;
00227 entry.m_method = method;
00228 m_methodEntries.push_back(entry);
00229 }
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 void
00248 WOscContainer::AddContainer(WOscContainer* container, const char* name, bool isAlias)
00249 {
00250 WOscContainerEntry entry;
00251 entry.m_name = name;
00252 entry.m_isAlias = isAlias;
00253 entry.m_container = container;
00254 m_containerEntries.push_back(entry);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269 const WOscContainer*
00270 WOscContainer::FindContainer(const char* address) const
00271 {
00272 unsigned int addrlen = strlen(address);
00273
00274 if ( addrlen == 0 )
00275 return NULL;
00276 if ( address[0] != '/' )
00277 return NULL;
00278 if ( addrlen == 1 && *address == '/' )
00279 return this;
00280
00281
00282 const char* next = NextSlashOrNull(address+1);
00283
00284 if ( *next == 0 ) {
00285
00286 for (int i = m_containerEntries.size()-1; i >= 0; i-- )
00287 if ( m_containerEntries[i].m_name == (address+1) )
00288 return m_containerEntries[i].m_container;
00289 } else {
00290
00291 unsigned int thisNodeStrLen = next-address;
00292 for ( int i = m_containerEntries.size()-1; i >= 0; i-- ) {
00293 if ( strncmp(m_containerEntries[i].m_name.c_str(), address+1, thisNodeStrLen) == 0 ) {
00294 const WOscContainer* ctnr = m_containerEntries[i].m_container->FindContainer(next);
00295 if ( ctnr )
00296 return ctnr;
00297 }
00298 }
00299 }
00300
00301 return NULL;
00302 }
00303
00304
00305
00306
00307 bool
00308 WOscContainer::RemoveContainer(const char* name)
00309 {
00310 for ( int i = m_containerEntries.size()-1; i >= 0; i-- )
00311 if ( m_containerEntries[i].m_name == name ) {
00312
00313 if ( ! m_containerEntries[i].m_isAlias )
00314 delete m_containerEntries[i].m_container;
00315 m_containerEntries.erase(m_containerEntries.begin() + i);
00316 return true;
00317 }
00318 return false;
00319 }
00320
00321
00322
00323
00324 bool
00325 WOscContainer::RemoveMethod(const char* name)
00326 {
00327 for ( int i = m_methodEntries.size()-1; i >= 0; i-- )
00328 if ( m_methodEntries[i].m_name == name ) {
00329
00330 if ( ! m_methodEntries[i].m_isAlias )
00331 delete m_methodEntries[i].m_method;
00332 m_methodEntries.erase(m_methodEntries.begin() + i);
00333 return true;
00334 }
00335 return false;
00336 }
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 void
00361 WOscContainer::DispatchMessage(WOscCallbackList& methods, WOscMessage* msg)
00362 {
00363 if ( m_parent != NULL )
00364 throw WOscException(ERR_NOT_DISPATCHING_FROM_ROOT, __FILE__, __LINE__);
00365
00366 const char* pattern = msg->GetOscAddress().GetBuffer();
00367
00368 if ( pattern == NULL || pattern[0] != '/')
00369 throw WOscException(ERR_INVALID_ADDRESS_NO_SLASH, __FILE__, __LINE__);
00370
00371
00372 DispatchSubMessage(methods, pattern+1);
00373 }
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 void
00389 WOscContainer::DispatchSubMessage(WOscCallbackList& methods, const char* pattern)
00390 {
00391 const char *nextSlash = NextSlashOrNull(pattern);
00392 if (*nextSlash == '\0') {
00393
00394
00395 for (int i = m_methodEntries.size()-1; i >= 0 ; i--)
00396 if (PatternMatch(pattern, m_methodEntries[i].m_name.c_str()))
00397
00398 methods.Append(m_methodEntries[i].m_method);
00399 } else {
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 *((char*)nextSlash) = '\0';
00410 const char *restOfPattern = nextSlash + 1;
00411 for (int i = m_containerEntries.size()-1; i >= 0; i--)
00412 if (PatternMatch(pattern, m_containerEntries[i].m_name.c_str()))
00413 m_containerEntries[i].m_container->DispatchSubMessage(methods, restOfPattern);
00414 *((char*)nextSlash) = '/';
00415 }
00416 }
00417
00418
00419
00420
00421
00422
00423 WOscString
00424 WOscContainer::GetName() const
00425 {
00426 if ( m_parent != NULL ) {
00427
00428 const std::vector<WOscContainerEntry>& entries = m_parent->m_containerEntries;
00429 for ( int i = entries.size()-1; i >= 0; i-- )
00430 if ( (entries[i].m_container == this) && (!(entries[i].m_isAlias))){
00431 return WOscString(entries[i].m_name.c_str());
00432 break;
00433 }
00434 }
00435 return WOscString("/");
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448 WOscString
00449 WOscContainer::GetAddress() const
00450 {
00451
00452 if ( m_parent == NULL)
00453 return WOscString("/");
00454
00455 WOscContainer* momentaryParent = m_parent;
00456 WOscString address = GetName();
00457 address += '/';
00458
00459
00460 while ( momentaryParent != NULL ) {
00461 address = momentaryParent->GetName() + address;
00462 momentaryParent = momentaryParent->m_parent;
00463 }
00464
00465 return address;
00466 }
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 WOscString
00479 WOscContainer::GetAddressSpace() const
00480 {
00481 const WOscContainer* root = FindRoot();
00482 return root->GetMethodList();
00483 }
00484
00485
00486
00487
00488
00489
00490
00491 WOscString
00492 WOscContainer::GetMethodList() const
00493 {
00494 WOscString methodList;
00495
00496
00497 for ( int m = m_methodEntries.size()-1; m >= 0; m-- ){
00498 if ( m_methodEntries[m].m_isAlias ) {
00499 methodList += GetAddress();
00500 methodList += m_methodEntries[m].m_name.c_str();
00501 } else {
00502 methodList += m_methodEntries[m].m_method->GetAddress();
00503 }
00504 methodList += '\n';
00505 }
00506
00507
00508 for ( int c = m_containerEntries.size()-1; c >= 0; c-- ) {
00509 if ( m_containerEntries[c].m_isAlias ) {
00510
00511 } else {
00512 methodList += m_containerEntries[c].m_container->GetMethodList();
00513 }
00514 }
00515
00516 return methodList;
00517 }
00518
00519
00520
00521
00522
00523
00524 const WOscContainer*
00525 WOscContainer::FindRoot() const
00526 {
00527
00528 const WOscContainer* momentaryParent = m_parent;
00529 const WOscContainer* lastParent = this;
00530
00531
00532 while ( momentaryParent != NULL ){
00533 lastParent = momentaryParent;
00534 momentaryParent = momentaryParent->m_parent;
00535 }
00536 return lastParent;
00537 }
00538
00539
00540
00541
00542
00543
00544 bool
00545 WOscContainer::IsRoot() const
00546 {
00547 return m_parent == NULL ? true : false;
00548 }
00549
00550 void
00551 WOscContainer::RecursivelyRemoveAliases(WOscContainer* container)
00552 {
00553
00554 for ( int i = m_containerEntries.size()-1 ; i >= 0; i-- ) {
00555 WOscContainerEntry& entry = m_containerEntries[i];
00556
00557 if ( entry.m_isAlias ) {
00558
00559
00560 if ( entry.m_container == container )
00561 m_containerEntries.erase(m_containerEntries.begin()+i);
00562 } else {
00563 entry.m_container->RecursivelyRemoveAliases(container);
00564 }
00565 }
00566 }
00567
00568 void
00569 WOscContainer::RecursivelyRemoveAliases(WOscMethod* method)
00570 {
00571
00572 for ( int i = m_methodEntries.size()-1 ; i >= 0; i-- ) {
00573 WOscMethodEntry& entry = m_methodEntries[i];
00574
00575 if ( entry.m_isAlias ) {
00576
00577
00578 if ( entry.m_method == method )
00579 m_methodEntries.erase(m_methodEntries.begin()+i);
00580 }
00581 }
00582
00583 for ( int i = m_containerEntries.size()-1 ; i >= 0; i-- )
00584 m_containerEntries[i].m_container->RecursivelyRemoveAliases(method);
00585 }