88
99// #include "mem_check.h" // COMMENT-OUT BEFORE UPLOAD
1010
11- // Stream * CSV_Parser::debug_serial = &Serial;
11+ // Stream * CSV_Parser::debug_serial = &Serial;
1212
1313/* Helper function useful for handling unsigned format specifiers. */
1414char * CSV_Parser::strdup_ignoring_u (const char *s) {
@@ -189,25 +189,26 @@ char * CSV_Parser::parseStringValue(const char * s, int * chars_occupied) {
189189 if (*s != quote_char) {
190190 char * first_delim = strpbrk (s, delim_chars);
191191 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 ;
207196 }
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;
211212 }
212213
213214 /* 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) {
224225 len--;
225226 continue ;
226227 }
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+ }
227234 ending_quote_found = true ;
228235
229236 *chars_occupied += next_quote - base;
@@ -417,21 +424,21 @@ void CSV_Parser::supplyChunk(const char *s) {
417424 if (leftover) {
418425 int leftover_len = strlen (leftover);
419426
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+
429436 int s_len = strlen (s);
430437 // debug_serial->println("leftover_len = " + String(leftover_len) + ", s_len = " + String(s_len));
431438 leftover = (char *)realloc (leftover, leftover_len + s_len + 1 );
432439
433- // if (!leftover)
434- // debug_serial->println("leftover realloc failed");
440+ // if (!leftover)
441+ // debug_serial->println("leftover realloc failed");
435442 strcat (leftover, s);
436443 s = leftover;
437444 // debug_serial->println("merged leftover = " + String(leftover));
@@ -440,7 +447,7 @@ void CSV_Parser::supplyChunk(const char *s) {
440447 int chars_occupied = 0 ;
441448 char * val = 0 ;
442449 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));
444451 if (fmt[current_col] != ' -' ) {
445452 if (!header_parsed) {
446453 keys[current_col] = strdup_trimmed (val);
0 commit comments