5 // to be moved in ecere?
6 public class FileHandler
16 public struct CSVParserParameters
20 int expectedFieldCount;
21 bool tolerateNewLineInValues;
26 CSVParserParameters classicParameters = { ',', '\"', 0, false };
28 public struct CSVParserState
36 public class CSVParser : public FileHandler
39 CSVParserParameters options { ',', '\"', 0, false };
42 void PrintMessage(typed_object object, ...)
46 va_start(args, object);
47 PrintStdArgsToBuffer(buffer, sizeof(buffer), object, args);
52 virtual bool OnMessage(String message)
54 ::PrintLn(this._class.name, ": ", message,
55 " lineNum=", info.lineNum,
56 " charNum=", info.charNum,
57 " rowNum=", info.rowNum,
58 " fieldNum=", info.fieldNum);
61 virtual bool OnRowStrings(Array<String> strings);
63 virtual void Process()
65 bool quoted = false, status = true;
66 Array<String> values { };
68 int start = 0, end = 0;
70 Array<char> buffer { minAllocSize = 4096 };
77 while(!file.Eof() && status)
83 offset = readCount - start;
84 if(offset > buffer.minAllocSize / 2)
85 buffer.minAllocSize += 4096;
86 memmove(&buffer[0], &buffer[start], offset);
91 readCount = offset + file.Read(&buffer[offset], 1, buffer.minAllocSize - offset);
92 for(c = offset; c < readCount && status; c++)
97 if(ch == options.valueQuotes)
105 if(ch == options.valueQuotes)
111 //else if(ch == options.fieldSeparator || ch == '\n')
112 else if(ch == options.fieldSeparator ||
113 (ch == '\n' && (!options.tolerateNewLineInValues || info.fieldNum >= options.expectedFieldCount-1)))
115 if(values.count < options.expectedFieldCount)
117 int len = started ? (end-start) : 0;
118 String value = new char[len+1];
119 memcpy(value, &buffer[start], len);
130 status = OnRowStrings(values);
153 String value = new char[len+1];
154 memcpy(value, &buffer[start], len);
158 if(values.count && status)
160 status = OnRowStrings(values);