8
8
9
9
// #include "mem_check.h" // COMMENT-OUT BEFORE UPLOAD
10
10
11
- // Stream * CSV_Parser::debug_serial = &Serial;
11
+ // Stream * CSV_Parser::debug_serial = &Serial;
12
12
13
13
/* Helper function useful for handling unsigned format specifiers. */
14
14
char * CSV_Parser::strdup_ignoring_u (const char *s) {
@@ -189,25 +189,26 @@ char * CSV_Parser::parseStringValue(const char * s, int * chars_occupied) {
189
189
if (*s != quote_char) {
190
190
char * first_delim = strpbrk (s, delim_chars);
191
191
int val_len = 0 ;
192
- if (first_delim || whole_csv_supplied) {
193
- if (first_delim) {
194
- val_len = first_delim - s;
195
- *chars_occupied = val_len + (*first_delim == delimiter) + strspn (first_delim, " \r\n " );
196
- }
197
- else {
198
- val_len = strlen (s);
199
- *chars_occupied = val_len;
200
- }
201
-
202
- // return strndup(s, *chars_occupied); // available for Esp8266 but not for Arduino :(
203
- char *str = (char *)malloc (val_len + 1 );
204
- memcpy (str, s, val_len);
205
- str[val_len] = 0 ;
206
- return str;
192
+ if (!first_delim && !whole_csv_supplied) {
193
+ // delim_chars not found in string
194
+ *chars_occupied = 0 ;
195
+ return 0 ;
207
196
}
208
- // delim_chars not found in string
209
- *chars_occupied = 0 ;
210
- return 0 ;
197
+
198
+ if (first_delim) {
199
+ val_len = first_delim - s;
200
+ *chars_occupied = val_len + (*first_delim == delimiter) + strspn (first_delim, " \r\n " );
201
+ }
202
+ else {
203
+ val_len = strlen (s);
204
+ *chars_occupied = val_len;
205
+ }
206
+
207
+ // return strndup(s, *chars_occupied); // available for Esp8266 but not for Arduino :(
208
+ char *str = (char *)malloc (val_len + 1 );
209
+ memcpy (str, s, val_len);
210
+ str[val_len] = 0 ;
211
+ return str;
211
212
}
212
213
213
214
/* If value is enclosed in double quotes. Being enclosed in double quotes automatically
@@ -224,6 +225,12 @@ char * CSV_Parser::parseStringValue(const char * s, int * chars_occupied) {
224
225
len--;
225
226
continue ;
226
227
}
228
+ // only assume the current quote is the ending quote if the next character is a delimiter or a new line
229
+ // WARNING: parseLeftover does not need such condition, "whole_csv_supplied" can be used to check if parseLeftover was used
230
+ if (!whole_csv_supplied && !strpbrk (next_quote + 1 , delim_chars)) {
231
+ s = next_quote + 1 ;
232
+ continue ;
233
+ }
227
234
ending_quote_found = true ;
228
235
229
236
*chars_occupied += next_quote - base;
@@ -417,21 +424,21 @@ void CSV_Parser::supplyChunk(const char *s) {
417
424
if (leftover) {
418
425
int leftover_len = strlen (leftover);
419
426
420
- // If there's no leftover and first supplied char is '\n' then it could be the case that the last char was "\r",
421
- // so '\n' should be ignored.
422
- // The same applies to situation where " (quote char) was previously received and the supplied char is '\r'
423
- if (leftover_len == 0 && ignore_next_delimchar && (*s == ' \n ' || *s == ' \r ' || *s == delimiter)) {
424
- if (*s != ' \r ' )
425
- ignore_next_delimchar = false ;
426
- s++;
427
- }
428
-
427
+ // If there's no leftover and first supplied char is '\n' then it could be the case that the last char was "\r",
428
+ // so '\n' should be ignored.
429
+ // The same applies to situation where " (quote char) was previously received and the supplied char is '\r'
430
+ if (leftover_len == 0 && ignore_next_delimchar && (*s == ' \n ' || *s == ' \r ' || *s == delimiter)) {
431
+ if (*s != ' \r ' )
432
+ ignore_next_delimchar = false ;
433
+ s++;
434
+ }
435
+
429
436
int s_len = strlen (s);
430
437
// debug_serial->println("leftover_len = " + String(leftover_len) + ", s_len = " + String(s_len));
431
438
leftover = (char *)realloc (leftover, leftover_len + s_len + 1 );
432
439
433
- // if (!leftover)
434
- // debug_serial->println("leftover realloc failed");
440
+ // if (!leftover)
441
+ // debug_serial->println("leftover realloc failed");
435
442
strcat (leftover, s);
436
443
s = leftover;
437
444
// debug_serial->println("merged leftover = " + String(leftover));
@@ -440,7 +447,7 @@ void CSV_Parser::supplyChunk(const char *s) {
440
447
int chars_occupied = 0 ;
441
448
char * val = 0 ;
442
449
while ((val = parseStringValue (s, &chars_occupied))) {
443
- // debug_serial->println("rows_count = " + String(rows_count) + ", current_col = " + String(current_col) + ", val = " + String(val));
450
+ // debug_serial->println("rows_count = " + String(rows_count) + ", current_col = " + String(current_col) + ", val = " + String(val));
444
451
if (fmt[current_col] != ' -' ) {
445
452
if (!header_parsed) {
446
453
keys[current_col] = strdup_trimmed (val);
0 commit comments