From 2f82fd066321cde3e225fc87a9469849215413eb Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Sat, 20 Feb 2010 21:14:47 +0000 Subject: Mixed bag. Please see CHANGES. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@7117 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Preferences.cxx | 155 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 101 insertions(+), 54 deletions(-) (limited to 'src/Fl_Preferences.cxx') diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx index c3920c692..14b254312 100644 --- a/src/Fl_Preferences.cxx +++ b/src/Fl_Preferences.cxx @@ -466,7 +466,7 @@ char Fl_Preferences::deleteAllGroups() */ int Fl_Preferences::entries() { - return node->nEntry; + return node->nEntry(); } @@ -480,7 +480,7 @@ int Fl_Preferences::entries() */ const char *Fl_Preferences::entry( int index ) { - return node->entry[index].name; + return node->entry(index).name; } @@ -1350,10 +1350,13 @@ Fl_Preferences::Node::Node( const char *path ) { if ( path ) path_ = strdup( path ); else path_ = 0; child_ = 0; next_ = 0; parent_ = 0; - entry = 0; - nEntry = NEntry = 0; + entry_ = 0; + nEntry_ = NEntry_ = 0; dirty_ = 0; top_ = 0; + indexed_ = 0; + index_ = 0; + nIndex_ = NIndex_ = 0; } void Fl_Preferences::Node::deleteAllChildren() @@ -1366,27 +1369,28 @@ void Fl_Preferences::Node::deleteAllChildren() } child_ = 0L; dirty_ = 1; + updateIndex(); } void Fl_Preferences::Node::deleteAllEntries() { - if ( entry ) + if ( entry_ ) { - for ( int i = 0; i < nEntry; i++ ) + for ( int i = 0; i < nEntry_; i++ ) { - if ( entry[i].name ) { - free( entry[i].name ); - entry[i].name = 0L; + if ( entry_[i].name ) { + free( entry_[i].name ); + entry_[i].name = 0L; } - if ( entry[i].value ) { - free( entry[i].value ); - entry[i].value = 0L; + if ( entry_[i].value ) { + free( entry_[i].value ); + entry_[i].value = 0L; } } - free( entry ); - entry = 0L; - nEntry = 0; - NEntry = 0; + free( entry_ ); + entry_ = 0L; + nEntry_ = 0; + NEntry_ = 0; } dirty_ = 1; } @@ -1396,6 +1400,7 @@ Fl_Preferences::Node::~Node() { deleteAllChildren(); deleteAllEntries(); + deleteIndex(); if ( path_ ) { free( path_ ); path_ = 0L; @@ -1420,12 +1425,12 @@ int Fl_Preferences::Node::write( FILE *f ) { if ( next_ ) next_->write( f ); fprintf( f, "\n[%s]\n\n", path_ ); - for ( int i = 0; i < nEntry; i++ ) + for ( int i = 0; i < nEntry_; i++ ) { - char *src = entry[i].value; + char *src = entry_[i].value; if ( src ) { // hack it into smaller pieces if needed - fprintf( f, "%s:", entry[i].name ); + fprintf( f, "%s:", entry_[i].name ); int cnt; for ( cnt = 0; cnt < 60; cnt++ ) if ( src[cnt]==0 ) break; @@ -1443,7 +1448,7 @@ int Fl_Preferences::Node::write( FILE *f ) } } else - fprintf( f, "%s\n", entry[i].name ); + fprintf( f, "%s\n", entry_[i].name ); } if ( child_ ) child_->write( f ); dirty_ = 0; @@ -1482,37 +1487,38 @@ Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) Node *nd = find( name ); free( name ); dirty_ = 1; + updateIndex(); return nd; } // create and set, or change an entry within this node void Fl_Preferences::Node::set( const char *name, const char *value ) { - for ( int i=0; i=nEntry ) return; - char *&dst = entry[ lastEntrySet ].value; + if ( lastEntrySet<0 || lastEntrySet>=nEntry_ ) return; + char *&dst = entry_[ lastEntrySet ].value; int a = strlen( dst ); int b = strlen( line ); dst = (char*)realloc( dst, a+b+1 ); @@ -1559,15 +1565,15 @@ void Fl_Preferences::Node::add( const char *line ) const char *Fl_Preferences::Node::get( const char *name ) { int i = getEntry( name ); - return i>=0 ? entry[i].value : 0 ; + return i>=0 ? entry_[i].value : 0 ; } // find the index of an entry, returns -1 if no such entry int Fl_Preferences::Node::getEntry( const char *name ) { - for ( int i=0; inext_ ) - cnt++; - return cnt; + if (indexed_) { + return nIndex_; + } else { + int cnt = 0; + for ( Node *nd = child_; nd; nd = nd->next_ ) + cnt++; + return cnt; + } } // return the node name @@ -1688,7 +1698,7 @@ const char *Fl_Preferences::Node::name() } } -// return the n'th child node +// return the n'th child node's name const char *Fl_Preferences::Node::child( int ix ) { Node *nd = childNode( ix ); @@ -1701,13 +1711,22 @@ const char *Fl_Preferences::Node::child( int ix ) // return the n'th child node Fl_Preferences::Node *Fl_Preferences::Node::childNode( int ix ) { - Node *nd; - for ( nd = child_; nd; nd = nd->next_ ) - { - if ( !ix-- ) break; - if ( !nd ) break; + createIndex(); + if (indexed_) { + // usually faster access in correct order, but needing more memory + return index_[ix]; + } else { + // slow access and reverse order + int n = nChildren(); + ix = n - ix -1; + Node *nd; + for ( nd = child_; nd; nd = nd->next_ ) + { + if ( !ix-- ) break; + if ( !nd ) break; + } + return nd; } - return nd; } // remove myself from the list and delete me (and all children) @@ -1729,11 +1748,39 @@ char Fl_Preferences::Node::remove() } } parent()->dirty_ = 1; + parent()->updateIndex(); } delete this; return ( nd != 0 ); } +void Fl_Preferences::Node::createIndex() { + if (indexed_) return; + int n = nChildren(); + if (n>NIndex_) { + NIndex_ = n + 16; + index_ = (Node**)realloc(index_, NIndex_*sizeof(Node**)); + } + Node *nd; + int i = 0; + for (nd = child_; nd; nd = nd->next_, i++) { + index_[n-i-1] = nd; + } + nIndex_ = n; + indexed_ = 1; +} + +void Fl_Preferences::Node::updateIndex() { + indexed_ = 0; +} + +void Fl_Preferences::Node::deleteIndex() { + if (index_) free(index_); + NIndex_ = nIndex_ = 0; + index_ = 0; + indexed_ = 0; +} + char Fl_Preferences::Node::copyTo(Fl_Tree *tree, Fl_Tree_Item *ti) { ti->label(name()); @@ -1744,11 +1791,11 @@ char Fl_Preferences::Node::copyTo(Fl_Tree *tree, Fl_Tree_Item *ti) nd->copyTo(tree, tic); tic->close(); } - int i, n = nEntry; + int i, n = nEntry_; for (i=0; iadd(ti, buf); } -- cgit v1.2.3