00001 #ifndef _IDENTIFIERCOLLECTION_H_
00002 #define _IDENTIFIERCOLLECTION_H_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef _WIN32
00023 #pragma once
00024 #endif
00025
00026 #include <FdoStd.h>
00027 #include <Fdo/Expression/Identifier.h>
00028 #include <Fdo/Commands/CommandException.h>
00029
00030
00031
00032 class FdoIdentifierCollection : public FdoCollection<FdoIdentifier, FdoCommandException>
00033 {
00034
00035 protected:
00036 virtual void Dispose();
00037
00038
00039 public:
00040
00041
00042
00043
00044
00045
00046 FDO_API static FdoIdentifierCollection* Create();
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 FDO_API FdoIdentifier* GetItem(FdoInt32 index)
00059 {
00060 return FdoCollection<FdoIdentifier, FdoCommandException>::GetItem(index);
00061 }
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 FDO_API FdoIdentifier* GetItem(const wchar_t* name)
00073 {
00074 FdoIdentifier* item = FindItem( name );
00075 if ( !item )
00076 throw FdoCommandException::Create(
00077 FdoException::NLSGetMessage(
00078 FDO_NLSID(FDO_38_ITEMNOTFOUND),
00079 name
00080 )
00081 );
00082
00083 return(item);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 FDO_API FdoIdentifier* FindItem(const wchar_t* name)
00098 {
00099
00100 ((FdoIdentifierCollection*) this)->InitMap();
00101
00102 FdoIdentifier* obj = NULL;
00103
00104 if ( mpNameMap ) {
00105
00106 obj = GetMap(name);
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 if ( (obj != NULL) && (Compare(obj->GetText(), name) != 0) )
00121 FDO_SAFE_RELEASE( obj );
00122 }
00123
00124 if ( obj == NULL ) {
00125
00126 for ( FdoInt32 i = 0; i < FdoCollection<FdoIdentifier, FdoCommandException>::GetCount(); i++ ) {
00127 FdoIdentifier* obj = GetItem(i);
00128
00129 if ( Compare(name, obj->GetText()) == 0 )
00130 return(obj);
00131
00132 FDO_SAFE_RELEASE(obj);
00133 }
00134 }
00135
00136 return (obj);
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150 virtual void SetItem(FdoInt32 index, FdoIdentifier* value)
00151 {
00152 CheckDuplicate( value, index );
00153
00154
00155 if ( mpNameMap )
00156 RemoveMapAt(index);
00157
00158
00159 if ( mpNameMap && value )
00160 InsertMap( value );
00161
00162
00163 FdoCollection<FdoIdentifier, FdoCommandException>::SetItem(index, value);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 virtual FdoInt32 Add( FdoIdentifier* value)
00176 {
00177 CheckDuplicate( value, -1 );
00178
00179
00180 if ( mpNameMap && value ) {
00181 InsertMap(value);
00182 }
00183
00184
00185 return( FdoCollection<FdoIdentifier, FdoCommandException>::Add(value) );
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 virtual void Insert( FdoInt32 item, FdoIdentifier* value)
00202 {
00203 CheckDuplicate( value, -1 );
00204
00205
00206 if ( mpNameMap ) {
00207 InsertMap(value);
00208 }
00209
00210
00211 return( FdoCollection<FdoIdentifier, FdoCommandException>::Insert(item, value) );
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 virtual void Clear()
00221 {
00222
00223 if (mpNameMap ) {
00224 delete mpNameMap;
00225 mpNameMap = NULL;
00226 }
00227
00228
00229 FdoCollection<FdoIdentifier, FdoCommandException>::Clear();
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 virtual void Remove(const FdoIdentifier* value)
00242 {
00243
00244 if ( mpNameMap )
00245 RemoveMap( value );
00246
00247
00248 FdoCollection<FdoIdentifier, FdoCommandException>::Remove(value);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260 virtual void RemoveAt(FdoInt32 index)
00261 {
00262
00263 if ( mpNameMap )
00264 RemoveMapAt(index);
00265
00266
00267 FdoCollection<FdoIdentifier, FdoCommandException>::RemoveAt(index);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 virtual bool Contains(const FdoIdentifier* value)
00280 {
00281
00282 ((FdoIdentifierCollection*) this)->InitMap();
00283
00284 if (mpNameMap )
00285 {
00286
00287 FdoPtr <FdoIDisposable> temp = GetMap (((FdoIdentifier*)value)->GetText());
00288 bool ret = (temp != NULL);
00289 return (ret);
00290 }
00291 else
00292 {
00293 FdoString * valueName = ((FdoIdentifier*)value)->GetText();
00294 FdoInt32 count = FdoCollection<FdoIdentifier, FdoCommandException>::GetCount();
00295 bool ret = false;
00296 for (FdoInt32 i = 0; !ret && i < count; i++)
00297 {
00298 FdoPtr<FdoIdentifier> item = GetItem(i);
00299 FdoString * itemName = item->GetText();
00300 ret = (Compare(itemName, valueName)==0);
00301 }
00302 return ret;
00303 }
00304 }
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 virtual bool Contains(FdoString* name)
00316 {
00317 FdoIdentifier* item = FindItem(name);
00318 bool found = (item != NULL);
00319
00320 FDO_SAFE_RELEASE(item);
00321
00322 return(found);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 virtual FdoInt32 IndexOf(const FdoIdentifier* value)
00335 {
00336 return(FdoCollection<FdoIdentifier, FdoCommandException>::IndexOf(value));
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 virtual FdoInt32 IndexOf(FdoString* name)
00349 {
00350 if (name == NULL)
00351 throw FdoCommandException::Create(FdoException::NLSGetMessage(FDO_NLSID(FDO_2_BADPARAMETER)));
00352
00353 FdoInt32 size = FdoCollection<FdoIdentifier, FdoCommandException>::GetCount();
00354 for (FdoInt32 i = 0; i < size; i++)
00355 {
00356 FdoPtr<FdoIdentifier> pitem = GetItem(i);
00357 if (pitem != NULL && pitem->GetText() != (FdoString*) NULL && Compare(name, pitem->GetText()) == 0) {
00358 return i;
00359 }
00360 }
00361
00362 return(-1);
00363 }
00364
00365 protected:
00366 FdoIdentifierCollection( bool caseSensitive = true )
00367 {
00368 mbCaseSensitive = caseSensitive;
00369 mpNameMap = NULL;
00370 }
00371
00372 virtual ~FdoIdentifierCollection(void)
00373 {
00374 if (mpNameMap )
00375 delete mpNameMap;
00376 }
00377
00378
00379 int Compare( FdoString* str1, FdoString* str2 ) const
00380 {
00381 if ( mbCaseSensitive )
00382 return ( wcscmp(str1, str2) );
00383
00384
00385 #ifdef _WIN32
00386 return ( _wcsicmp(str1, str2) );
00387 #else
00388 return ( wcscasecmp(str1, str2) );
00389 #endif
00390 }
00391
00392 void CheckDuplicate( FdoIdentifier* item, FdoInt32 index )
00393 {
00394 FdoPtr<FdoIdentifier> foundItem1 = FindItem( item->GetText() );
00395 FdoPtr<FdoIdentifier> foundItem2;
00396
00397 if ( index >= 0 ) {
00398 foundItem2 = GetItem(index);
00399 }
00400
00401 if ( (foundItem1 !=NULL) && (foundItem1.p != foundItem2.p ) ) {
00402 throw FdoCommandException::Create(
00403 FdoException::NLSGetMessage(
00404 FDO_NLSID(FDO_45_ITEMINCOLLECTION),
00405 (FdoString*) item->GetText()
00406 )
00407 );
00408 }
00409 }
00410
00411
00412 private:
00413 void InitMap()
00414 {
00415
00416 if ( !mpNameMap && ( FdoCollection<FdoIdentifier, FdoCommandException>::GetCount() > FDO_COLL_MAP_THRESHOLD ) ) {
00417 mpNameMap = new std::map<FdoStringP,FdoIdentifier*>();
00418
00419
00420 for ( FdoInt32 i = (FdoCollection<FdoIdentifier, FdoCommandException>::GetCount() - 1); i >= 0; i-- )
00421 InsertMap( FdoPtr<FdoIdentifier>(GetItem(i)) );
00422 }
00423 }
00424
00425 void InsertMap( FdoIdentifier* value ) const
00426 {
00427
00428
00429 if ( mbCaseSensitive )
00430 mpNameMap->insert( std::pair<FdoStringP,FdoIdentifier*> ( value->GetText(), value ) );
00431 else
00432 mpNameMap->insert( std::pair<FdoStringP,FdoIdentifier*> ( FdoStringP(value->GetText()).Lower(), value ) );
00433 }
00434
00435
00436 void RemoveMapAt( FdoInt32 index )
00437 {
00438
00439 FdoIdentifier* pItem = FdoCollection<FdoIdentifier, FdoCommandException>::GetItem(index);
00440
00441 if ( pItem ) {
00442 RemoveMap( pItem );
00443 pItem->Release();
00444 }
00445 }
00446
00447
00448 void RemoveMap( const FdoIdentifier* value )
00449 {
00450
00451 if ( mbCaseSensitive )
00452 mpNameMap->erase( FdoStringP( ((FdoIdentifier*)value)->GetText() ) );
00453 else
00454 mpNameMap->erase( FdoStringP( ((FdoIdentifier*)value)->GetText() ).Lower() );
00455 }
00456
00457
00458 FdoIdentifier* GetMap( const wchar_t* name ) const
00459 {
00460 FdoIdentifier* pItem = NULL;
00461
00462 std::map <FdoStringP,FdoIdentifier*> :: const_iterator iter;
00463
00464 if ( mbCaseSensitive )
00465 iter = mpNameMap->find( FdoStringP(name) );
00466 else
00467
00468 iter = mpNameMap->find( FdoStringP(name).Lower() );
00469
00470 if ( iter != mpNameMap->end() ) {
00471 pItem = (FdoIdentifier*) iter->second;
00472 FDO_SAFE_ADDREF(pItem);
00473 }
00474
00475 return( pItem );
00476 }
00477
00478 bool mbCaseSensitive;
00479
00480
00481 std::map<FdoStringP,FdoIdentifier*> *mpNameMap;
00482
00483 };
00484 #endif
00485