[Kst] branches/work/kst/portto4/kst/src/datasources/ascii
Peter Kümmel
syntheticpp at gmx.net
Mon Jul 26 20:29:11 CEST 2010
SVN commit 1155018 by kuemmel:
AsciiPlugin: add bound checking in debug mode, maybe speed up in release mode, less lines by using Qt
M +36 -41 asciisource.cpp
M +5 -4 asciisource.h
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.cpp #1155017:1155018
@@ -1,9 +1,8 @@
/***************************************************************************
- ascii.cpp - ASCII file data source
+ ASCII file data source
-------------------
begin : Fri Oct 17 2003
copyright : (C) 2003 The University of Toronto
- email :
***************************************************************************/
/***************************************************************************
@@ -108,11 +107,17 @@
AsciiSource::AsciiSource(Kst::ObjectStore *store, QSettings *cfg, const QString& filename, const QString& type, const QDomElement& e) :
Kst::DataSource(store, cfg, filename, type),
- _rowIndex(0L),
- iv(new DataInterfaceAsciiVector(*this))
+ iv(new DataInterfaceAsciiVector(*this)),
+ _tmpBuffer(),
+ _rowIndex()
{
setInterface(iv);
+ // enable all pre-allocated memory
+ _tmpBuffer.resize(_tmpBuffer.capacity());
+ _rowIndex.resize(_rowIndex.capacity());
+
+
//TIME_IN_SCOPE(Ctor_AsciiSource);
setUpdateType(File);
@@ -137,23 +142,14 @@
AsciiSource::~AsciiSource()
{
- if (_rowIndex) {
- free(_rowIndex);
- _rowIndex = 0L;
- _numLinesAlloc = 0;
}
-}
void AsciiSource::reset()
{
_tmpBuffer.clear();
+ _rowIndex.clear();
- if (_rowIndex) {
- free(_rowIndex);
- _rowIndex = 0L;
- _numLinesAlloc = 0;
- }
_numFrames = 0;
_haveHeader = false;
_fieldListComplete = false;
@@ -184,11 +180,8 @@
}
-bool AsciiSource::initRowIndex() {
- if (!_rowIndex) {
- _rowIndex = (int *)malloc(32768 * sizeof(int));
- _numLinesAlloc = 32768;
- }
+bool AsciiSource::initRowIndex()
+{
_rowIndex[0] = 0;
_byteLength = 0;
_numFrames = 0;
@@ -280,10 +273,13 @@
} else if (tmpbuf[i] == '\n' || tmpbuf[i] == '\r') {
if (has_dat) {
++_numFrames;
- if (_numFrames >= _numLinesAlloc) {
- _numLinesAlloc += 32768;
- _rowIndex = (int *)realloc(_rowIndex, _numLinesAlloc*sizeof(int));
+ if (_numFrames >= _rowIndex.size()) {
+ _rowIndex.resize(_rowIndex.size() + 32768);
+ if (_numFrames >= _rowIndex.size()) {
+ // TODO where could we report an error;
+ return;
}
+ }
new_data = true;
}
_rowIndex[_numFrames] = bufstart + i + 1;
@@ -369,19 +365,18 @@
return 0;
}
- _tmpBuffer.reserve(bufread);
- if(_tmpBuffer.capacity() < bufread) {
+ _tmpBuffer.resize(bufread);
+ if(_tmpBuffer.size() < bufread) {
return -1;
}
- char* data = _tmpBuffer.data();
file.seek(bufstart);
- file.read(data, bufread);
+ file.read(&_tmpBuffer[0], bufread);
if (_config._columnType == AsciiSourceConfig::Fixed) {
for (int i = 0; i < n; ++i, ++s) {
// Read appropriate column and convert to double
- v[i] = lexc.toDouble(data + _rowIndex[i] - _rowIndex[0] + _config._columnWidth * (col - 1));
+ v[i] = lexc.toDouble(&_tmpBuffer[0] + _rowIndex[i] - _rowIndex[0] + _config._columnWidth * (col - 1));
}
} else if (_config._columnType == AsciiSourceConfig::Custom) {
for (int i = 0; i < n; ++i, ++s) {
@@ -389,21 +384,21 @@
int i_col = 0;
v[i] = Kst::NOPOINT;
for (int ch = _rowIndex[s] - bufstart; ch < bufread; ++ch) {
- if (_config._columnDelimiter.value().contains(data[ch])) {
+ if (_config._columnDelimiter.value().contains(_tmpBuffer[ch])) {
incol = false;
- } else if (data[ch] == '\n' || data[ch] == '\r') {
+ } else if (_tmpBuffer[ch] == '\n' || _tmpBuffer[ch] == '\r') {
break;
- } else if (_config._delimiters.value().contains(data[ch])) {
+ } else if (_config._delimiters.value().contains(_tmpBuffer[ch])) {
break;
} else {
if (!incol) {
incol = true;
++i_col;
if (i_col == col) {
- if (isdigit(data[ch]) || data[ch] == '-' || data[ch] == '.' || data[ch] == '+') {
- v[i] = lexc.toDouble(data + ch);
- } else if (ch + 2 < bufread && tolower(data[ch]) == 'i' &&
- tolower(data[ch + 1]) == 'n' && tolower(data[ch + 2]) == 'f') {
+ if (isdigit(_tmpBuffer[ch]) || _tmpBuffer[ch] == '-' || _tmpBuffer[ch] == '.' || _tmpBuffer[ch] == '+') {
+ v[i] = lexc.toDouble(&_tmpBuffer[0] + ch);
+ } else if (ch + 2 < bufread && tolower(_tmpBuffer[ch]) == 'i' &&
+ tolower(_tmpBuffer[ch + 1]) == 'n' && tolower(_tmpBuffer[ch + 2]) == 'f') {
v[i] = INF;
}
break;
@@ -419,23 +414,23 @@
v[i] = Kst::NOPOINT;
for (int ch = _rowIndex[s] - bufstart; ch < bufread; ++ch) {
- if (isspace(data[ch])) {
- if (data[ch] == '\n' || data[ch] == '\r') {
+ if (isspace(_tmpBuffer[ch])) {
+ if (_tmpBuffer[ch] == '\n' || _tmpBuffer[ch] == '\r') {
break;
} else {
incol = false;
}
- } else if (_config._delimiters.value().contains(data[ch])) {
+ } else if (_config._delimiters.value().contains(_tmpBuffer[ch])) {
break;
} else {
if (!incol) {
incol = true;
++i_col;
if (i_col == col) {
- if (isdigit(data[ch]) || data[ch] == '-' || data[ch] == '.' || data[ch] == '+') {
- v[i] = lexc.toDouble(data + ch);
- } else if (ch + 2 < bufread && tolower(data[ch]) == 'i' &&
- tolower(data[ch + 1]) == 'n' && tolower(data[ch + 2]) == 'f') {
+ if (isdigit(_tmpBuffer[ch]) || _tmpBuffer[ch] == '-' || _tmpBuffer[ch] == '.' || _tmpBuffer[ch] == '+') {
+ v[i] = lexc.toDouble(&_tmpBuffer[0] + ch);
+ } else if (ch + 2 < bufread && tolower(_tmpBuffer[ch]) == 'i' &&
+ tolower(_tmpBuffer[ch + 1]) == 'n' && tolower(_tmpBuffer[ch + 2]) == 'f') {
v[i] = INF;
}
break;
--- branches/work/kst/portto4/kst/src/datasources/ascii/asciisource.h #1155017:1155018
@@ -70,15 +70,16 @@
static QStringList stringListFor(const QString& filename, AsciiSourceConfig *cfg);
private:
- int *_rowIndex;
- int _numLinesAlloc;
+ // TODO Is this too big or should we use even more: 1MB on the stack?
+#define KST_PREALLOC 1 * 1024 * 1024
+ QVarLengthArray<char, KST_PREALLOC> _tmpBuffer;
+ QVarLengthArray<int, KST_PREALLOC / 4> _rowIndex;
+
int _numFrames;
int _byteLength;
friend class ConfigWidgetAscii;
mutable AsciiSourceConfig _config;
- // TODO Is this too big or should we use even more: 1MB on the stack?
- QVarLengthArray<char, 1*1024*1024> _tmpBuffer;
bool _haveHeader;
bool _fieldListComplete;
More information about the Kst
mailing list