diff --git a/src/lib/csv/csv.c b/src/lib/csv/csv.c index e2d85d79c423048b2bed809d65ede1593218ccd5..46e32bfa921b59ceabdd42525306a96b96834f5d 100644 --- a/src/lib/csv/csv.c +++ b/src/lib/csv/csv.c @@ -328,13 +328,14 @@ csv_next(struct csv_iterator *it) return CSV_IT_ERROR; it->buf_begin = tail; - /* bufp == NULL means end of line */ - if (it->csv->bufp == NULL) - return CSV_IT_EOL; if (tail == it->buf_end) /* buffer is empty */ return CSV_IT_NEEDMORE; + /* bufp == NULL means end of line */ + if (it->csv->bufp == NULL) + return CSV_IT_EOL; + /* return field via iterator structure */ it->field = it->csv->buf; it->field_len = it->csv->bufp - it->csv->buf; diff --git a/test/app-tap/csv.result b/test/app-tap/csv.result index 8b6f866b0422a9f0e2927ebcc83162f557270494..1596c0d10bb043bf1c3d173300ccbc99b52508bd 100644 --- a/test/app-tap/csv.result +++ b/test/app-tap/csv.result @@ -1,5 +1,5 @@ TAP version 13 -1..9 +1..11 ok - obj test1 ok - obj test2 ok - obj test3 @@ -9,3 +9,5 @@ ok - fio test3 ok - test roundtrip ok - test load(dump(t)) ok - final comma +ok - gh-1210 (1) +ok - gh-1210 (2) diff --git a/test/app-tap/csv.test.lua b/test/app-tap/csv.test.lua index a20024ae6f0e9dc0ef750a88c1ec1ad70aa0ea75..472a8d23e4f54ee1a20b09d37727b0eb42b9fba1 100755 --- a/test/app-tap/csv.test.lua +++ b/test/app-tap/csv.test.lua @@ -36,7 +36,7 @@ local test6_ans = "|23|\t|456|\t|abcac|\t|'multiword field 4'|\t\n|none|" .. "lag[ flag ])|\t\n||\t||\t||\t\n" test = tap.test("csv") -test:plan(9) +test:plan(11) readable = {} readable.read = myread @@ -56,6 +56,7 @@ tmpdir = fio.tempdir() file1 = fio.pathjoin(tmpdir, 'file.1') file2 = fio.pathjoin(tmpdir, 'file.2') file3 = fio.pathjoin(tmpdir, 'file.3') +file4 = fio.pathjoin(tmpdir, 'file.4') local f = fio.open(file1, { 'O_WRONLY', 'O_TRUNC', 'O_CREAT' }, 0777) f:write("123 , 5 , 92 , 0, 0\n" .. @@ -109,7 +110,22 @@ test:is(table2str(t), table2str(csv.load(csv.dump(t))), "test load(dump(t))") test:is(table2str(csv.load('a,b,c,')), '|a|\t|b|\t|c|\t||\t\n', "final comma") +local str = "ÑчÑмитьб-Pincall;79031111111\r\n" +str = str .. str .. str .. str .. str .. str +str = "Vendor;Prefix\r\n" .. str +f = fio.open(file4, { "O_WRONLY", "O_TRUNC" , "O_CREAT"}, 0x1FF) +f:write(str) +f:close() + +test:is(#csv.load(fio.open(file4, {'O_RDONLY'}), + {separator = ';', chunk_size = 3}), 7, "gh-1210 (1)") +test:is(#csv.load(fio.open(file4, {'O_RDONLY'}), + {separator = ';', chunk_size = 4}), 7, "gh-1210 (2)") + fio.unlink(file1) fio.unlink(file2) fio.unlink(file3) +fio.unlink(file4) fio.rmdir(tmpdir) + +test:check() diff --git a/test/unit/csv.c b/test/unit/csv.c index 0749f00dbbb5df797748ada27c41a8ed5fb93940..52d2e385d163890f2bf789e1c3a3862a787c8dff 100644 --- a/test/unit/csv.c +++ b/test/unit/csv.c @@ -310,6 +310,37 @@ void iter_test2() { footer(); } +void iter_test3() { + header(); + struct csv_iterator it; + struct csv csv; + csv_create(&csv); + csv_iterator_create(&it, &csv); + int st = 0; + const char *ar[] = {"1,2,3\r\n", "4,5,6", ""}; + int i = 0; + const char *buf = ar[i++]; + while((st = csv_next(&it)) != CSV_IT_EOF) { + switch(st) { + case CSV_IT_NEEDMORE: + csv_feed(&it, buf, strlen(buf)); + buf = ar[i++]; + break; + case CSV_IT_EOL: + print_endl(0); + break; + case CSV_IT_OK: + print_field(0, it.field, it.field + it.field_len); + break; + case CSV_IT_ERROR: + printf("\nerror"); + break; + } + } + csv_destroy(&csv); + footer(); +} + void csv_out() { header(); @@ -392,6 +423,7 @@ int main() { //iterator tests iter_test1(); iter_test2(); + iter_test3(); //output test csv_out(); diff --git a/test/unit/csv.result b/test/unit/csv.result index ecf954d2af3a3936da0ff650339c73abac45674f..8f9dab5b2239cedf46b10a35395fc5e060d74234 100644 --- a/test/unit/csv.result +++ b/test/unit/csv.result @@ -93,6 +93,10 @@ ha| |1| |23| *** iter_test2: done *** + *** iter_test3 *** +|1| |2| |3| +|4| |5| |6| + *** iter_test3: done *** *** csv_out *** abc<len=3>,"with,comma"<len=12>,""in quotes""<len=13>,1 "" quote<len=10> *** csv_out: done ***