1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software; you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation; either version 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "dictionary.H"
28 #include "primitiveEntry.H"
29 #include "dictionaryEntry.H"
31 /* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
33 defineTypeNameAndDebug(Foam::dictionary, 0);
35 const Foam::dictionary Foam::dictionary::null;
37 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39 Foam::dictionary::dictionary()
41 parent_(dictionary::null)
45 Foam::dictionary::dictionary
47 const dictionary& parentDict,
48 const dictionary& dict
51 IDLList<entry>(dict, *this),
57 IDLList<entry>::iterator iter = begin();
62 hashedEntries_.insert(iter().keyword(), &iter());
67 Foam::dictionary::dictionary
69 const dictionary& dict
72 IDLList<entry>(dict, *this),
74 parent_(dictionary::null)
78 IDLList<entry>::iterator iter = begin();
83 hashedEntries_.insert(iter().keyword(), &iter());
88 Foam::autoPtr<Foam::dictionary> Foam::dictionary::clone() const
90 return autoPtr<dictionary>(new dictionary(*this));
94 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
96 Foam::dictionary::~dictionary()
98 // cerr<< "~dictionary() " << name() << " " << long(this) << std::endl;
102 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
104 Foam::label Foam::dictionary::startLineNumber() const
108 return first()->startLineNumber();
117 Foam::label Foam::dictionary::endLineNumber() const
121 return last()->endLineNumber();
130 bool Foam::dictionary::found(const word& keyword, bool recursive) const
132 if (hashedEntries_.found(keyword))
136 else if (recursive && &parent_ != &dictionary::null)
138 return parent_.found(keyword, recursive);
147 const Foam::entry* Foam::dictionary::lookupEntryPtr
153 HashTable<entry*>::const_iterator iter = hashedEntries_.find(keyword);
155 if (iter == hashedEntries_.end())
157 if (recursive && &parent_ != &dictionary::null)
159 return parent_.lookupEntryPtr(keyword, recursive);
171 Foam::entry* Foam::dictionary::lookupEntryPtr
177 HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);
179 if (iter == hashedEntries_.end())
181 if (recursive && &parent_ != &dictionary::null)
183 return const_cast<dictionary&>(parent_).lookupEntryPtr
199 const Foam::entry& Foam::dictionary::lookupEntry
205 const entry* entryPtr = lookupEntryPtr(keyword, recursive);
207 if (entryPtr == NULL)
211 "dictionary::lookupEntry(const word& keyword) const",
213 ) << "keyword " << keyword << " is undefined in dictionary "
215 << exit(FatalIOError);
222 Foam::ITstream& Foam::dictionary::lookup
228 return lookupEntry(keyword, recursive).stream();
232 bool Foam::dictionary::isDict(const word& keyword) const
234 const entry* entryPtr = lookupEntryPtr(keyword);
238 return entryPtr->isDict();
247 const Foam::dictionary* Foam::dictionary::subDictPtr(const word& keyword) const
249 const entry* entryPtr = lookupEntryPtr(keyword);
253 return &entryPtr->dict();
262 const Foam::dictionary& Foam::dictionary::subDict(const word& keyword) const
264 const entry* entryPtr = lookupEntryPtr(keyword);
265 if (entryPtr == NULL)
269 "dictionary::subDict(const word& keyword) const",
271 ) << "keyword " << keyword << " is undefined in dictionary "
273 << exit(FatalIOError);
275 return entryPtr->dict();
279 Foam::dictionary& Foam::dictionary::subDict(const word& keyword)
281 entry* entryPtr = lookupEntryPtr(keyword);
282 if (entryPtr == NULL)
286 "dictionary::subDict(const word& keyword)",
288 ) << "keyword " << keyword << " is undefined in dictionary "
290 << exit(FatalIOError);
292 return entryPtr->dict();
296 Foam::wordList Foam::dictionary::toc() const
298 wordList keys(size());
303 IDLList<entry>::const_iterator iter = begin();
308 keys[i++] = iter().keyword();
315 bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
317 HashTable<entry*>::iterator iter = hashedEntries_.find(entryPtr->keyword());
319 if (mergeEntry && iter != hashedEntries_.end())
321 // merge dictionary with dictionary
322 if (iter()->isDict() && entryPtr->isDict())
324 iter()->dict().merge(entryPtr->dict());
331 // replace existing dictionary with entry or vice versa
332 IDLList<entry>::replace(iter(), entryPtr);
334 hashedEntries_.erase(iter);
336 if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
338 entryPtr->name() = name_ + "::" + entryPtr->keyword();
343 IOWarningIn("dictionary::add(entry*)", (*this))
344 << "problem replacing entry "<< entryPtr->keyword()
345 << " in dictionary " << name() << endl;
347 IDLList<entry>::remove(entryPtr);
354 if (hashedEntries_.insert(entryPtr->keyword(), entryPtr))
356 entryPtr->name() = name_ + "::" + entryPtr->keyword();
357 IDLList<entry>::append(entryPtr);
363 IOWarningIn("dictionary::add(entry* entryPtr)", (*this))
364 << "attempt to add entry "<< entryPtr->keyword()
365 << " which already exists in dictionary " << name()
374 void Foam::dictionary::add(const entry& e, bool mergeEntry)
376 add(e.clone(*this).ptr(), mergeEntry);
379 void Foam::dictionary::add(const word& k, const word& w, bool overwrite)
381 add(new primitiveEntry(k, token(w)), overwrite);
384 void Foam::dictionary::add(const word& k, const Foam::string& s, bool overwrite)
386 add(new primitiveEntry(k, token(s)), overwrite);
389 void Foam::dictionary::add(const word& k, const label l, bool overwrite)
391 add(new primitiveEntry(k, token(l)), overwrite);
394 void Foam::dictionary::add(const word& k, const scalar s, bool overwrite)
396 add(new primitiveEntry(k, token(s)), overwrite);
399 void Foam::dictionary::add(const word& k, const dictionary& d, bool mergeEntry)
401 add(new dictionaryEntry(k, *this, d), mergeEntry);
405 void Foam::dictionary::set(entry* entryPtr)
407 entry* existingPtr = lookupEntryPtr(entryPtr->keyword());
409 // clear dictionary so merge acts like overwrite
410 if (existingPtr && existingPtr->isDict())
412 existingPtr->dict().clear();
418 void Foam::dictionary::set(const entry& e)
420 set(e.clone(*this).ptr());
423 void Foam::dictionary::set(const word& k, const dictionary& d)
425 set(new dictionaryEntry(k, *this, d));
429 bool Foam::dictionary::remove(const word& Keyword)
431 HashTable<entry*>::iterator iter = hashedEntries_.find(Keyword);
433 if (iter != hashedEntries_.end())
435 IDLList<entry>::remove(iter());
437 hashedEntries_.erase(iter);
448 bool Foam::dictionary::changeKeyword
450 const word& oldKeyword,
451 const word& newKeyword,
456 if (oldKeyword == newKeyword)
461 HashTable<entry*>::iterator iter = hashedEntries_.find(oldKeyword);
463 // oldKeyword not found - do nothing
464 if (iter == hashedEntries_.end())
469 HashTable<entry*>::iterator iter2 = hashedEntries_.find(newKeyword);
471 // newKeyword already exists
472 if (iter2 != hashedEntries_.end())
476 IDLList<entry>::replace(iter2(), iter());
478 hashedEntries_.erase(iter2);
482 WarningIn("dictionary::changeKeyword(const word&, const word&)")
483 << "cannot rename keyword "<< oldKeyword
484 << " to existing keyword " << newKeyword
485 << " in dictionary " << name() << endl;
490 // change name and HashTable, but leave DL-List untouched
491 iter()->keyword() = newKeyword;
492 iter()->name() = name_ + "::" + newKeyword;
493 hashedEntries_.erase(oldKeyword);
494 hashedEntries_.insert(newKeyword, iter());
500 bool Foam::dictionary::merge(const dictionary& dict)
502 // Check for assignment to self
505 FatalErrorIn("dictionary::merge(const dictionary&)")
506 << "attempted merge to self for dictionary " << name()
507 << abort(FatalError);
510 bool changed = false;
514 IDLList<entry>::const_iterator iter = dict.begin();
519 const word& keyword = iter().keyword();
521 HashTable<entry*>::iterator iter2 = hashedEntries_.find(keyword);
523 if (iter2 != hashedEntries_.end())
525 // Recursively merge sub-dictionaries
526 // TODO: merge without copying
527 if (iter2()->isDict() && iter().isDict())
529 if (iter2()->dict().merge(iter().dict()))
536 add(iter().clone(*this).ptr(), true);
542 // not found - just add
543 add(iter().clone(*this).ptr());
552 void Foam::dictionary::clear()
554 IDLList<entry>::clear();
555 hashedEntries_.clear();
559 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
561 Foam::ITstream& Foam::dictionary::operator[](const word& keyword) const
563 return lookup(keyword);
567 void Foam::dictionary::operator=(const dictionary& dict)
569 // Check for assignment to self
572 FatalErrorIn("dictionary::operator=(const dictionary&)")
573 << "attempted assignment to self for dictionary " << name()
574 << abort(FatalError);
580 // Create clones of the entries in the given dictionary
581 // resetting the parentDict to this dictionary
584 IDLList<entry>::const_iterator iter = dict.begin();
589 IDLList<entry>::append(iter().clone(*this).ptr());
594 IDLList<entry>::iterator iter = begin();
599 hashedEntries_.insert(iter().keyword(), &iter());
604 void Foam::dictionary::operator+=(const dictionary& dict)
606 // Check for assignment to self
609 FatalErrorIn("dictionary::operator+=(const dictionary&)")
610 << "attempted addition assignment to self for dictionary " << name()
611 << abort(FatalError);
616 IDLList<entry>::const_iterator iter = dict.begin();
621 add(iter().clone(*this).ptr());
626 void Foam::dictionary::operator|=(const dictionary& dict)
628 // Check for assignment to self
631 FatalErrorIn("dictionary::operator|=(const dictionary&)")
632 << "attempted assignment to self for dictionary " << name()
633 << abort(FatalError);
638 IDLList<entry>::const_iterator iter = dict.begin();
643 if (!found(iter().keyword()))
645 add(iter().clone(*this).ptr());
651 void Foam::dictionary::operator<<=(const dictionary& dict)
653 // Check for assignment to self
656 FatalErrorIn("dictionary::operator<<=(const dictionary&)")
657 << "attempted assignment to self for dictionary " << name()
658 << abort(FatalError);
663 IDLList<entry>::const_iterator iter = dict.begin();
668 set(iter().clone(*this).ptr());
673 /* * * * * * * * * * * * * * * * Global operators * * * * * * * * * * * * * */
675 Foam::dictionary Foam::operator+
677 const dictionary& dict1,
678 const dictionary& dict2
681 dictionary sum(dict1);
687 Foam::dictionary Foam::operator|
689 const dictionary& dict1,
690 const dictionary& dict2
693 dictionary sum(dict1);
699 // ************************************************************************* //