[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kdecore/config
From:       Jakub Stachowski <qbast () go2 ! pl>
Date:       2008-04-21 14:01:58
Message-ID: 1208786518.944950.32461.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 799413 by qbast:

Ini parsing optimization - avoid using QByteArray and excessive memory copying.



 A             bufferfragment_p.h   [License: LGPL (v2+)]
 M  +44 -48    kconfigini.cpp  
 M  +6 -1      kconfigini_p.h  


--- trunk/KDE/kdelibs/kdecore/config/kconfigini.cpp #799412:799413
@@ -29,6 +29,7 @@
 #include "kconfig.h"
 #include "kconfigbackend.h"
 #include "kconfigini_p.h"
+#include "bufferfragment_p.h"
 #include "kconfigdata.h"
 #include <ksavefile.h>
 #include <kde_file.h>
@@ -88,13 +89,17 @@
     bool groupOptionImmutable = false;
     bool groupSkip = false;
 
-    int lineNo=0;
+    int lineNo = 0;
     // on systems using \r\n as end of line, \r will be taken care of by 
-    // trimmed() below
-    QList<QByteArray> lines=file.readAll().split('\n');
-    for (int i=0;i<lines.size();i++) {
-        QByteArray& line=lines[i];
-        line=line.trimmed();
+    // trim() below
+    QByteArray buffer = file.readAll();
+    BufferFragment contents(buffer.data(), buffer.size());
+    unsigned int len = contents.length();
+    unsigned int startOfLine = 0;
+
+    while (startOfLine < len) {
+        BufferFragment line = contents.split('\n', &startOfLine);
+        line.trim();
         lineNo++;
 
         // skip empty lines and lines beginning with '#'
@@ -129,7 +134,9 @@
                 else {
                     if (!newGroup.isEmpty())
                         newGroup += '\x1d';
-                    newGroup += printableToString(line.mid(start, end - start), \
file, lineNo); +                    BufferFragment namePart=line.mid(start, end - \
start); +                    printableToString(&namePart, file, lineNo);
+                    newGroup += namePart.toByteArray();
                 }
             } while ((start = end + 2) <= line.length() && line.at(end + 1) == '[');
             currentGroup = newGroup;
@@ -147,14 +154,16 @@
             if (groupSkip && !bDefault)
                 continue; // skip entry
 
-            QByteArray aKey;
+            BufferFragment aKey;
             int eqpos = line.indexOf('=');
             if (eqpos < 0) {
                 aKey = line;
                 line.clear();
             } else {
-                aKey = line.left(eqpos).trimmed();
-                line.remove(0, eqpos + 1);
+                BufferFragment temp = line.left(eqpos);
+                temp.trim();
+                aKey = temp;
+                line.truncateLeft(eqpos + 1);
             }
             if (aKey.isEmpty()) {
                 qWarning() << warningProlog(file, lineNo) << "Invalid entry (empty \
key)"; @@ -165,17 +174,17 @@
             if (groupOptionImmutable)
                 entryOptions |= KEntryMap::EntryImmutable;
 
-            QByteArray locale;
-            QByteArray rawKey;
+            BufferFragment locale;
+            BufferFragment rawKey;
             int start;
-            while ((start = aKey.indexOf('[')) >= 0) {
+            while ((start = aKey.lastIndexOf('[')) >= 0) {
                 int end = aKey.indexOf(']', start);
                 if (end < 0) {
                     qWarning() << warningProlog(file, lineNo)
                             << "Invalid entry (missing ']')";
                     goto next_line;
                 } else if (end > start + 1 && aKey.at(start + 1) == '$') { // found \
                option(s)
-                    int i = start+2;
+                    int i = start + 2;
                     while (i < end) {
                         switch (aKey.at(i)) {
                             case 'i':
@@ -188,8 +197,9 @@
                                 break;
                             case 'd':
                                 entryOptions |= KEntryMap::EntryDeleted;
-                                aKey = printableToString(aKey.left(start), file, \
                lineNo);
-                                entryMap.setEntry(currentGroup, aKey, QByteArray(), \
entryOptions); +                                aKey = aKey.left(start);
+                                printableToString(&aKey, file, lineNo);
+                                entryMap.setEntry(currentGroup, aKey.toByteArray(), \
QByteArray(), entryOptions);  goto next_line;
                             default:
                                 break;
@@ -203,17 +213,16 @@
                         goto next_line;
                     }
 
-                    locale = aKey.mid(start+1,end-start-1);
-                    rawKey = aKey.left(end+1);
+                    locale = aKey.mid(start + 1,end - start - 1);
+                    rawKey = aKey.left(end + 1);
                 }
-                aKey.remove(start, end-start+1);
+                aKey.truncate(start);
             }
-
             if (eqpos < 0) { // Do this here after [$d] was checked
                 qWarning() << warningProlog(file, lineNo) << "Invalid entry (missing \
'=')";  continue;
             }
-            aKey = printableToString(aKey, file, lineNo);
+            printableToString(&aKey, file, lineNo);
             if (!locale.isEmpty()) {
                 if (locale != currentLocale) {
                     // backward compatibility. C == en_US
@@ -221,12 +230,12 @@
                         if (merging){
                             entryOptions |= KEntryMap::EntryRawKey;
                             aKey = rawKey; // store as unprocessed key
-                            locale = QByteArray();
+                            locale = BufferFragment();
                         } else
                             goto next_line; // skip this entry if we're not merging
                     }
                 }
-            }
+            } 
 
             if (options&ParseGlobal)
                 entryOptions |= KEntryMap::EntryGlobal;
@@ -234,7 +243,8 @@
                 entryOptions |= KEntryMap::EntryDefault;
             if (!locale.isNull())
                 entryOptions |= KEntryMap::EntryLocalized;
-            entryMap.setEntry(currentGroup, aKey, printableToString(line, file, \
lineNo), entryOptions); +            printableToString(&line, file, lineNo);
+            entryMap.setEntry(currentGroup, aKey.toByteArray(), line.toByteArray(), \
entryOptions);  }
 next_line:
         continue;
@@ -642,31 +652,18 @@
     return char(ret);
 }
 
-QByteArray KConfigIniBackend::printableToString(const QByteArray& aString, const \
QFile& file, int line) +void KConfigIniBackend::printableToString(BufferFragment* \
aString, const QFile& file, int line)  {
-    if (aString.isEmpty())
-        return QByteArray("");
+    if (aString->isEmpty() || aString->indexOf('\\')==-1) 
+        return;
+    aString->trim();
+    int l = aString->length();
+    char *r = aString->data();
+    char *str=r;
 
-    const char *str = aString.constData();
-    int l = aString.length();
-
-    // Strip leading white-space.
-    while((l > 0) && ((*str == ' ') || (*str == '\t') || (*str == '\r'))) {
-        str++; l--;
-     }
-
-
-    // Strip trailing white-space.
-    while((l > 0) && ((str[l-1] == ' ') || (str[l-1] == '\t') || (str[l-1] == \
                '\r'))) {
-        l--;
-    }
-
-    QByteArray result(l, 0);
-    char *r = result.data();
-
     for(int i = 0; i < l; i++, r++) {
-        if (str[i] != '\\') {
-            *r = str[i];
+        if (str[i]!= '\\') {
+            *r=str[i];
         } else {
             // Probable escape sequence
             i++;
@@ -707,6 +704,5 @@
             }
         }
     }
-    result.truncate(r - result.constData());
-    return result;
+    aString->truncate(r - aString->constData());
 }
--- trunk/KDE/kdelibs/kdecore/config/kconfigini_p.h #799412:799413
@@ -29,6 +29,9 @@
 
 class KConfigIniBackend : public KConfigBackend
 {
+private:
+    class BufferFragment;
+    
     KLockFile::Ptr lockFile;
 public:
 
@@ -61,7 +64,9 @@
         KeyString = 1,
         ValueString = 2
     };
-    static QByteArray printableToString(const QByteArray& aString, const QFile& \
file, int line); +    // Warning: this modifies data in-place. Other BufferFragment \
objects referencing the same buffer  +    // fragment will get their data modified \
too. +    static void printableToString(BufferFragment* aString, const QFile& file, \
                int line);
     static QByteArray stringToPrintable(const QByteArray& aString, StringType type);
     static char charFromHex(const char *str, const QFile& file, int line);
     static QString warningProlog(const QFile& file, int line);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic