Skip to content

Commit e4f8b69

Browse files
committed
parseRow() efficiency + related realloc fix
1 parent 7569694 commit e4f8b69

File tree

5 files changed

+232
-10
lines changed

5 files changed

+232
-10
lines changed

CSV_Parser.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ CSV_Parser::CSV_Parser(const char * s, const char * fmt_, bool has_header_, char
8686
keys = (char**)calloc(cols_count, sizeof(char*)); // calloc fills memory with 0's so then I can simply use "if(keys[i]) { do something with key[i] }"
8787
values = (void**)calloc(cols_count, sizeof(void*));
8888

89+
for (int col = 0; col < cols_count; col++)
90+
values[col] = malloc(getTypeSize(fmt[col]));
91+
8992
/*mem.check("constructor");
9093
mem.check("after calloc 1, should be = " + String(cols_count * sizeof(char*)));
9194
mem.check("after calloc 2, should be = " + String(cols_count * sizeof(void*)));*/
@@ -123,9 +126,11 @@ bool CSV_Parser::parseRow() {
123126
// (by "original way of parsing" I mean: by using "cp <<" operator or by supplying whole csv at once)
124127
// parseRow() requires feedRowParser() and rowParserFinished() to be defined by the user
125128
// It then allows to read the first row in the same way as default parsing way, like:
126-
// while (cp.parseRow()) {
127-
// char *str = ((char**)cp["my_strings"])[0];
128-
// }
129+
//
130+
// char **strings = (char**)cp[0]; // string based indexing can't be used here because header was not supplied yet
131+
// while (cp.parseRow()) {
132+
// char *str = strings[0];
133+
// }
129134

130135
if (rowParserFinished())
131136
return false;
@@ -441,7 +446,8 @@ void CSV_Parser::supplyChunk(const char *s) {
441446
keys[current_col] = strdup_trimmed(val);
442447
} else {
443448
//mem.check("values[" + String(current_col) + "]");
444-
values[current_col] = (char*)realloc(values[current_col], (rows_count+1) * getTypeSize(fmt[current_col]));
449+
if (rows_count > 0)
450+
values[current_col] = (char*)realloc(values[current_col], (rows_count+1) * getTypeSize(fmt[current_col]));
445451
saveNewValue(val, fmt[current_col], rows_count, current_col, is_fmt_unsigned[current_col]);
446452
}
447453
}
@@ -500,7 +506,8 @@ void CSV_Parser::parseLeftover() {
500506
int chars_occupied = 0;
501507
if (char * val = parseStringValue(leftover, &chars_occupied)) {
502508
if (fmt[current_col] != '-') {
503-
values[current_col] = realloc(values[current_col], (rows_count+1) * getTypeSize(fmt[current_col]));
509+
if (rows_count > 0)
510+
values[current_col] = realloc(values[current_col], (rows_count+1) * getTypeSize(fmt[current_col]));
504511
saveNewValue(val, fmt[current_col], rows_count, current_col, is_fmt_unsigned[current_col]);
505512
}
506513
if (++current_col == cols_count) {

examples/parsing_row_by_row/parsing_row_by_row.ino

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,24 @@ void setup() {
7777
CSV_Parser cp(/*format*/ "sL");
7878

7979
Serial.println("Accessing values by column name:");
80+
81+
// WARNING: String indexing can't be used here because the header was not supplied to the cp object yet.
82+
// char **strings = (char**)cp["my_strings"];
83+
// int32_t *numbers = (int32_t*)cp["my_numbers"];
84+
85+
char **strings = (char**)cp[0];
86+
int32_t *numbers = (int32_t*)cp[1];
8087

8188
// parseRow calls feedRowParser() continuously until it reads a
8289
// full row or until the rowParserFinished() returns true
8390
int row_index = 0;
8491
while (cp.parseRow()) {
85-
char *string = ((char**)cp["my_strings"])[0];
86-
int32_t number = ((int32_t*)cp["my_numbers"])[0];
92+
// Here we could use string indexing but it would be much slower.
93+
// char *string = ((char**)cp["my_strings"])[0];
94+
// int32_t number = ((int32_t*)cp["my_numbers"])[0];
8795

88-
// char *string = ((char**)cp[0])[0];
89-
// int32_t number = ((int32_t*)cp[1])[0];
96+
char *string = strings[0];
97+
int32_t number = numbers[0];
9098

9199
Serial.print(String(row_index) + ". String = ");
92100
Serial.println(string);

0 commit comments

Comments
 (0)