TextSplit rewind support, support for sectors in reverse order

This commit is contained in:
Erich Edgar Hoover 2005-12-28 05:22:18 +00:00
parent 848b96039b
commit afbd0a462a
5 changed files with 75 additions and 39 deletions

View File

@ -84,21 +84,20 @@ Scene::Scene(const char *name, const char *buf, int len) :
if (ts.eof()) // Sectors are optional, but section: doesn't seem to be
return;
// Sector NAMES can be null, but ts doesn't seem flexible enough to allow this
if (strlen(ts.currentLine()) > strlen(" sector"))
ts.scanString(" sector %256s", 1, tempBuf);
else {
ts.nextLine();
strcpy(tempBuf, "");
int sectorStart = ts.getLineNumber();
_numSectors = 0;
// Find the number of sectors (while the sectors usually
// count down from the highest number there are a few
// cases where they count up, see hh.set for example)
while (!ts.eof()) {
ts.scanString(" %s", 1, tempBuf);
if(!std::strcmp(tempBuf, "sector"))
_numSectors++;
}
ts.scanString(" id %d", 1, &_numSectors);
_numSectors++;
// Allocate and fill an array of sector info
_sectors = new Sector[_numSectors];
// FIXME: This would be nicer if we could rewind the textsplitter
// stream
_sectors[0].load0(ts, tempBuf, _numSectors);
for (int i = 1; i < _numSectors; i++)
ts.setLineNumber(sectorStart);
for (int i = 0; i < _numSectors; i++)
_sectors[i].load(ts);
}

View File

@ -55,10 +55,34 @@ int residual_vsscanf(const char *str, int field_count, const char *format, va_li
}
TextSplitter::TextSplitter(const char *data, int len) {
_data = new char[len + 1];
std::memcpy(_data, data, len);
_data[len] = '\0';
_currLine = _data;
char *line, *tmpData;
int i;
tmpData = new char[len+1];
std::memcpy(tmpData, data, len);
tmpData[len] = '\0';
// Find out how many lines of text there are
_numLines = _lineIndex = 0;
line = (char *) tmpData;
while (line != NULL) {
line = std::strchr(line, '\n');
if (line != NULL) {
_numLines++;
line++;
}
}
// Allocate an array of the lines
_lines = new TextLines[_numLines];
line = (char *) tmpData;
for (i=0;i<_numLines;i++) {
char *lastLine = line;
line = std::strchr(lastLine, '\n');
_lines[i].setData(lastLine, line-lastLine);
line++;
}
delete[] tmpData;
_currLine = NULL;
processLine();
}
@ -74,7 +98,7 @@ bool TextSplitter::checkString(const char *needle) {
}
void TextSplitter::expectString(const char *expected) {
if (eof())
if (_currLine == NULL)
error("Expected `%s', got EOF\n", expected);
if (std::strcmp(currentLine(), expected) != 0)
error("Expected `%s', got `%s'\n", expected, currentLine());
@ -82,7 +106,7 @@ void TextSplitter::expectString(const char *expected) {
}
void TextSplitter::scanString(const char *fmt, int field_count, ...) {
if (eof())
if (_currLine == NULL)
error("Expected line of format `%s', got EOF\n", fmt);
std::va_list va;
@ -104,11 +128,7 @@ void TextSplitter::processLine() {
if (eof())
return;
_nextLine = std::strchr(_currLine, '\n');
if (_nextLine != NULL) {
*_nextLine = '\0';
_nextLine++;
}
_currLine = _lines[_lineIndex++].getData();
// Cut off comments
char *comment_start = std::strchr(_currLine, '#');
@ -130,3 +150,11 @@ void TextSplitter::processLine() {
for (char *s = _currLine; *s != '\0'; s++)
*s = std::tolower(*s);
}
void TextSplitter::TextLines::setData(char *data, int length) {
int _lineLength = length;
_lineData = new char[_lineLength];
std::memcpy(_lineData, data, _lineLength);
_lineData[_lineLength-1] = 0;
}

View File

@ -29,14 +29,15 @@ public:
TextSplitter(const char *data, int len);
char *nextLine() {
_currLine = _nextLine;
processLine();
return _currLine;
}
char *currentLine() { return _currLine; }
const char *currentLine() const { return _currLine; }
bool eof() const { return _currLine == NULL; }
bool eof() const { return _lineIndex == _numLines; }
int getLineNumber() { return _lineIndex; }
void setLineNumber(int line) { _lineIndex = line-1; processLine(); }
// Check if the current line contains 'needle'
bool checkString(const char *needle);
@ -53,11 +54,26 @@ public:
__attribute__((format (scanf, 2, 4)))
#endif
;
class TextLines {
public:
TextLines() {};
~TextLines() { delete[] _lineData; }
void setData(char *data, int length);
char *getData() { return _lineData; }
~TextSplitter() { delete[] _data; }
protected:
char *_lineData;
int _lineLength;
friend class TextSplitter;
};
~TextSplitter() { delete[] _lines; }
private:
char *_data, *_currLine, *_nextLine;
char *_currLine;
int _numLines, _lineIndex;
TextLines *_lines;
void processLine();
};

View File

@ -20,8 +20,10 @@
#include "textsplit.h"
void Sector::load(TextSplitter &ts) {
// float height = 12345.f; // Yaz: this is in the original code...
char buf[256];
int id = 0;
int id = 0, i = 0;
Vector3d tempVert;
// Sector NAMES can be null, but ts isn't flexible enough
if (strlen(ts.currentLine()) > strlen(" sector"))
@ -32,16 +34,8 @@ void Sector::load(TextSplitter &ts) {
}
ts.scanString(" id %d", 1, &id);
load0(ts, buf, id);
}
void Sector::load0(TextSplitter &ts, char *name, int id) {
char buf[256];
int i = 0;
// float height = 12345.f; // Yaz: this is in the original code...
Vector3d tempVert;
_name = name;
_name = buf;
_id = id;
ts.scanString(" type %256s", 1, buf);

View File

@ -31,7 +31,6 @@ class TextSplitter;
class Sector {
public:
void load(TextSplitter &ts);
void load0(TextSplitter &ts, char *name, int id);
void setVisible(bool visible);