gmio_stl: fix ending error when reading multiple STL solids from stream

This fixes GitHub issue #2
This commit is contained in:
Hugues Delorme 2016-09-29 16:26:23 +02:00
parent 0f1cc05d59
commit a525eca318
5 changed files with 41 additions and 14 deletions

View File

@ -183,13 +183,26 @@ int gmio_stla_infos_get(
gmio_stringstream_skip_until_ascii_space(&sstream);
}
}
{ /* Eat whole line */
{
/* Eat whole line containing "endsolid" */
const char* c = gmio_stringstream_current_char(&sstream);
while (c != NULL && *c != '\n' && *c != '\r')
c = gmio_stringstream_next_char(&sstream);
/* Try to move stream pos on EOF or next solid */
gmio_stringstream_skip_ascii_spaces(&sstream);
}
{
/* Whitespaces were just previously skipped, the stream pos can at
* either :
* - on EOF => fine, stream is exhausted
* - on some non-W/S => stream is then one char too far
* These two cases are detected by testing result of the
* stringstream's current char */
const int end_offset =
gmio_stringstream_current_char(&sstream) != NULL ? 1 : 0;
infos->size -= sstream.strbuff_end - sstream.strbuff_at + end_offset;
infos->size = GMIO_MAX(0, infos->size);
}
infos->size -= sstream.strbuff_end - sstream.strbuff_at;
infos->size = GMIO_MAX(0, infos->size);
}
return err;

View File

@ -190,11 +190,23 @@ int gmio_stlb_read(
gmio_task_iface_handle_progress(task, i_facet, total_facet_count);
} /* end while */
if (gmio_no_error(error))
if (gmio_no_error(error)) {
gmio_stl_mesh_creator_end_solid(mesh_creator);
if (gmio_no_error(error) && i_facet != total_facet_count)
error = GMIO_STL_ERROR_FACET_COUNT;
if (i_facet != total_facet_count) {
error = GMIO_STL_ERROR_FACET_COUNT;
goto label_end;
}
/* Try to eat EOF by probing next byte in stream */
if (!gmio_stream_at_end(stream)) {
struct gmio_streampos oldpos;
if (gmio_stream_get_pos(stream, &oldpos) == 0) {
uint8_t c;
gmio_stream_read_bytes(stream, &c, 1);
if (!gmio_stream_at_end(stream))
gmio_stream_set_pos(stream, &oldpos);
}
}
}
label_end:
gmio_memblock_helper_release(&mblock_helper);

View File

@ -50,6 +50,10 @@ const char* all_tests()
gmio_memblock_set_default_constructor(gmio_memblock_for_tests);
#if 0
generate_stlb_tests_models();
#endif
UTEST_RUN(test_stl_coords_packing);
UTEST_RUN(test_stl_triangle_packing);
UTEST_RUN(test_stl_triangle_compute_normal);
@ -69,10 +73,6 @@ const char* all_tests()
UTEST_RUN(test_stlb_header_str);
UTEST_RUN(test_stlb_header_to_printable_str);
#if 0
generate_stlb_tests_models();
#endif
return NULL;
}
UTEST_MAIN(all_tests)

Binary file not shown.

View File

@ -34,9 +34,10 @@
#include "stl_utils.h"
#include "../src/gmio_core/error.h"
#include "../src/gmio_core/internal/helper_stream.h"
#include "../src/gmio_core/internal/locale_utils.h"
#include "../src/gmio_core/internal/min_max.h"
#include "../src/gmio_core/internal/string.h"
#include "../src/gmio_core/internal/locale_utils.h"
#include "../src/gmio_stl/stl_error.h"
#include "../src/gmio_stl/stl_infos.h"
#include "../src/gmio_stl/stl_io.h"
@ -333,12 +334,13 @@ static const char* __tstl__test_stl_read_multi_solid(
struct gmio_stl_read_options roptions = {0};
struct gmio_stl_mesh_creator null_creator = {0};
roptions.func_stla_get_streamsize = gmio_stla_infos_get_streamsize;
while (gmio_no_error(error)) {
while (gmio_no_error(error) && !gmio_stream_at_end(&stream)) {
error = gmio_stl_read(&stream, &null_creator, &roptions);
if (gmio_no_error(error))
++solid_count;
}
fclose(infile);
UTEST_ASSERT(gmio_no_error(error));
UTEST_COMPARE_UINT(expected_solid_count, solid_count);
}
else {
@ -434,7 +436,7 @@ static void generate_stlb_tests_models()
struct gmio_stream ostream = gmio_stream_stdio(outfile);
struct gmio_stl_read_options ropts = {0};
ropts.func_stla_get_streamsize = gmio_stla_infos_get_streamsize;
while (gmio_no_error(read_error)) {
while (gmio_no_error(read_error) && !gmio_stream_at_end(&istream)) {
struct gmio_stl_data data = {0};
struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data);
struct gmio_stl_mesh mesh = {0};