diff --git a/benchmarks/benchmark_gmio/main.c b/benchmarks/benchmark_gmio/main.c index 6d65066..0934ecc 100644 --- a/benchmarks/benchmark_gmio/main.c +++ b/benchmarks/benchmark_gmio/main.c @@ -219,16 +219,14 @@ void bmk_gmio_stl_infos_get(const char* filepath) FILE* file = fopen(filepath, "rb"); if (file != NULL) { - struct gmio_stl_infos infos = {0}; - struct gmio_stl_infos_get_args args = {0}; int error = GMIO_ERROR_OK; + struct gmio_stl_infos_get_args args = {0}; args.stream = gmio_stream_stdio(file); - args.memblock = gmio_memblock_malloc(64 * 1024); /* 64Ko */ - args.format = GMIO_STL_FORMAT_ASCII; - error = gmio_stl_infos_get(&args, &infos, GMIO_STL_INFO_FLAG_ALL); + error = gmio_stl_infos_get( + &args, GMIO_STL_FORMAT_ASCII, GMIO_STL_INFO_FLAG_ALL); if (!already_exec) { printf("stl_infos_get()\n File: %s\n Size: %uKo\n Facets: %u\n", - filepath, infos.size / 1024, infos.facet_count); + filepath, args.infos.size / 1024, args.infos.facet_count); } already_exec = GMIO_TRUE; } diff --git a/src/gmio_core/internal/helper_memblock.h b/src/gmio_core/internal/helper_memblock.h new file mode 100644 index 0000000..601b99d --- /dev/null +++ b/src/gmio_core/internal/helper_memblock.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** This software is a reusable library whose purpose is to provide complete +** I/O support for various CAD file formats (eg. STL) +** +** This software is governed by the CeCILL-B license under French law and +** abiding by the rules of distribution of free software. You can use, +** modify and/ or redistribute the software under the terms of the CeCILL-B +** license as circulated by CEA, CNRS and INRIA at the following URL +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#ifndef GMIO_INTERNAL_HELPER_MEMBLOCK_H +#define GMIO_INTERNAL_HELPER_MEMBLOCK_H + +#include "../memblock.h" + +#include + +struct gmio_memblock_helper +{ + struct gmio_memblock* memblock; + gmio_bool_t was_allocated; +}; + +GMIO_INLINE +struct gmio_memblock_helper gmio_memblock_helper(struct gmio_memblock* mblock); + +GMIO_INLINE +void gmio_memblock_helper_release(struct gmio_memblock_helper* helper); + + + +/* + * Implementation + */ + +struct gmio_memblock_helper gmio_memblock_helper(struct gmio_memblock* mblock) +{ + struct gmio_memblock_helper helper = {0}; + helper.memblock = mblock; + if (mblock != NULL && (mblock->ptr == NULL || mblock->size == 0)) { + *(helper.memblock) = gmio_memblock_default(); + helper.was_allocated = GMIO_TRUE; + } + return helper; +} + +void gmio_memblock_helper_release(struct gmio_memblock_helper* helper) +{ + if (helper != NULL && helper->was_allocated) { + gmio_memblock_deallocate(helper->memblock); + helper->memblock = NULL; + helper->was_allocated = GMIO_FALSE; + } +} + +#endif /* GMIO_INTERNAL_HELPER_MEMBLOCK_H */ diff --git a/src/gmio_core/memblock.c b/src/gmio_core/memblock.c index 379e5f0..33c048f 100644 --- a/src/gmio_core/memblock.c +++ b/src/gmio_core/memblock.c @@ -47,6 +47,7 @@ void gmio_memblock_deallocate(struct gmio_memblock *mblock) if (mblock != NULL && mblock->func_deallocate != NULL) { mblock->func_deallocate(mblock->ptr); mblock->ptr = NULL; + mblock->size = 0; } } diff --git a/src/gmio_core/rwargs.h b/src/gmio_core/rwargs.h index 1c3b71d..78fd390 100644 --- a/src/gmio_core/rwargs.h +++ b/src/gmio_core/rwargs.h @@ -46,17 +46,4 @@ struct gmio_rwargs struct gmio_task_iface task_iface; }; -GMIO_INLINE struct gmio_rwargs gmio_rwargs_null(); - - - -/* - * Implementation - */ -struct gmio_rwargs gmio_rwargs_null() -{ - static const struct gmio_rwargs null = {0}; - return null; -} - #endif /* GMIO_RWARGS_H */ diff --git a/src/gmio_core/stream.h b/src/gmio_core/stream.h index 55cb355..6140777 100644 --- a/src/gmio_core/stream.h +++ b/src/gmio_core/stream.h @@ -24,6 +24,7 @@ #define GMIO_STREAM_H #include "global.h" +#include "memblock.h" #include "streampos.h" #include diff --git a/src/gmio_stl/internal/stl_rw_common.c b/src/gmio_stl/internal/stl_rw_common.c index 2f48923..54f9a19 100644 --- a/src/gmio_stl/internal/stl_rw_common.c +++ b/src/gmio_stl/internal/stl_rw_common.c @@ -35,6 +35,15 @@ gmio_bool_t gmio_check_rwargs(int *error, const struct gmio_rwargs* args) return gmio_no_error(*error); } +gmio_bool_t gmio_check_memblock(int *error, const struct gmio_memblock* mblock) +{ + if (mblock->ptr == NULL) + *error = GMIO_ERROR_NULL_MEMBLOCK; + else if (mblock->size == 0) + *error = GMIO_ERROR_INVALID_MEMBLOCK_SIZE; + return gmio_no_error(*error); +} + gmio_bool_t gmio_stl_check_mesh(int *error, const struct gmio_stl_mesh* mesh) { if (mesh == NULL diff --git a/src/gmio_stl/internal/stl_rw_common.h b/src/gmio_stl/internal/stl_rw_common.h index 2f5b697..bb56c36 100644 --- a/src/gmio_stl/internal/stl_rw_common.h +++ b/src/gmio_stl/internal/stl_rw_common.h @@ -23,6 +23,7 @@ #include "../../gmio_core/global.h" #include "../../gmio_core/endian.h" +struct gmio_memblock; struct gmio_rwargs; struct gmio_stl_mesh; @@ -34,6 +35,7 @@ struct gmio_stlb_readwrite_helper }; gmio_bool_t gmio_check_rwargs(int* error, const struct gmio_rwargs* args); +gmio_bool_t gmio_check_memblock(int* error, const struct gmio_memblock* mblock); gmio_bool_t gmio_stl_check_mesh(int* error, const struct gmio_stl_mesh* mesh); diff --git a/src/gmio_stl/internal/stla_infos_get.c b/src/gmio_stl/internal/stla_infos_get.c new file mode 100644 index 0000000..e90ca3d --- /dev/null +++ b/src/gmio_stl/internal/stla_infos_get.c @@ -0,0 +1,155 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** This software is a reusable library whose purpose is to provide complete +** I/O support for various CAD file formats (eg. STL) +** +** This software is governed by the CeCILL-B license under French law and +** abiding by the rules of distribution of free software. You can use, +** modify and/ or redistribute the software under the terms of the CeCILL-B +** license as circulated by CEA, CNRS and INRIA at the following URL +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#include "stla_infos_get.h" + +#include "../../gmio_core/error.h" +#include "../../gmio_core/internal/min_max.h" +#include "../../gmio_core/internal/string.h" +#include "stl_rw_common.h" + +#include + +GMIO_INLINE const char* find_substr( + const struct gmio_string* str, size_t str_offset, const char* substr) +{ + return strstr(str->ptr + str_offset, substr); +} + +static uint32_t stla_facet_count( + const struct gmio_string* strbuff, const char* end_ptr) +{ + const char* substr_at = NULL; + size_t strbuff_pos = 0; + uint32_t facet_count = 0; + + do { + substr_at = find_substr(strbuff, strbuff_pos, "endfacet"); + if (substr_at != NULL && substr_at < end_ptr) { + ++facet_count; + /* Note: strlen("endfacet") == 8 */ + strbuff_pos = (substr_at - strbuff->ptr) + 8; + } + else { + substr_at = NULL; + } + } while (substr_at != NULL); + + return facet_count; +} + +enum { + BUFF_OVERLAP_SIZE = 14, + BUFF_OVERLAP_SIZE_DIV2 = BUFF_OVERLAP_SIZE / 2 +}; + +int gmio_stla_infos_get( + struct gmio_stl_infos_get_args* args, unsigned flags) +{ + struct gmio_stream* stream = &args->stream; + struct gmio_stl_infos* infos = &args->infos; + void* mblock_ptr = args->stream_memblock.ptr; + /* Leave one byte to end the string buffer with 0 */ + const size_t mblock_size = args->stream_memblock.size - 1; + struct gmio_string strbuff = gmio_string(mblock_ptr, 0, mblock_size); + + const gmio_bool_t flag_facet_count = + (flags & GMIO_STL_INFO_FLAG_FACET_COUNT) != 0; + const gmio_bool_t flag_size = + (flags & GMIO_STL_INFO_FLAG_SIZE) != 0; + const gmio_bool_t flag_stla_solidname = + (flags & GMIO_STLA_INFO_FLAG_SOLIDNAME) != 0; + + int err = GMIO_ERROR_OK; + + if (!gmio_check_memblock(&err, &args->stream_memblock)) + return err; + + if (flags != 0) { + /* 'overlap' stores the ending/starting bytes of the previous/current + * stream buffers(memblock) */ + char overlap[14] = {0}; /* 14 == 2*(strlen("endfacet") - 1) */ + gmio_bool_t endsolid_found = GMIO_FALSE; + + while (!endsolid_found && gmio_no_error(err)) { + const char* substr_at = NULL; + const size_t read_size = + gmio_stream_read(stream, mblock_ptr, 1, mblock_size); + const int stream_err = gmio_stream_error(&args->stream); + const gmio_bool_t overlap_has_contents = overlap[0] != 0; + gmio_bool_t endsolid_in_overlap = GMIO_FALSE; + + err = stream_err; + strbuff.len = read_size; + strbuff.ptr[strbuff.len] = 0; + + /* Copy first half of overlap buffer */ + if (overlap_has_contents) { + strncpy(&overlap[BUFF_OVERLAP_SIZE_DIV2], + mblock_ptr, + GMIO_MIN(BUFF_OVERLAP_SIZE_DIV2, read_size)); + } + + /* Find "endsolid" in overlap */ + if (overlap_has_contents) { + substr_at = strstr(overlap, "endsolid"); + endsolid_found = substr_at != NULL; + endsolid_in_overlap = endsolid_found; + } + + /* Find "endsolid" in memblock */ + if (!endsolid_found) { + substr_at = find_substr(&strbuff, 0, "endsolid"); + endsolid_found = substr_at != NULL; + } + + /* Update stream size */ + if (flag_size) { + /* Note: strlen("endsolid") == 8 */ + if (endsolid_found) { + if (!endsolid_in_overlap) + infos->size += (substr_at - strbuff.ptr) + 8; + /* TODO : gérer le cas où "endsolid" se trouve dans overlap */ + } + else { + infos->size += read_size; + } + } + + /* Find "endfacet" tokens */ + if (flag_facet_count && !endsolid_in_overlap) { + const char* endsolid_ptr = + endsolid_found ? substr_at : gmio_string_end(&strbuff); + /* Check in overlap */ + const gmio_bool_t endfacet_in_overlap = + overlap_has_contents + && strstr(overlap, "endfacet") != NULL; + infos->facet_count += endfacet_in_overlap ? 1 : 0; + /* Check in memblock */ + infos->facet_count += stla_facet_count(&strbuff, endsolid_ptr); + } + + /* Copy second half of overlap buffer */ + if (!endsolid_found && read_size >= BUFF_OVERLAP_SIZE_DIV2) { + memset(&overlap, 0, sizeof(overlap)); + strncpy(overlap, + &strbuff.ptr[read_size - BUFF_OVERLAP_SIZE_DIV2], + GMIO_MIN(BUFF_OVERLAP_SIZE_DIV2, read_size)); + } + } + } + + return err; +} diff --git a/src/gmio_stl/internal/stla_infos_get.h b/src/gmio_stl/internal/stla_infos_get.h new file mode 100644 index 0000000..16dda66 --- /dev/null +++ b/src/gmio_stl/internal/stla_infos_get.h @@ -0,0 +1,24 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** This software is a reusable library whose purpose is to provide complete +** I/O support for various CAD file formats (eg. STL) +** +** This software is governed by the CeCILL-B license under French law and +** abiding by the rules of distribution of free software. You can use, +** modify and/ or redistribute the software under the terms of the CeCILL-B +** license as circulated by CEA, CNRS and INRIA at the following URL +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#ifndef GMIO_INTERNAL_STLA_INFOS_GET_H +#define GMIO_INTERNAL_STLA_INFOS_GET_H + +#include "../stl_infos.h" + +int gmio_stla_infos_get( + struct gmio_stl_infos_get_args* args, unsigned flags); + +#endif /* GMIO_INTERNAL_STLA_INFOS_GET_H */ diff --git a/src/gmio_stl/internal/stlb_infos_get.c b/src/gmio_stl/internal/stlb_infos_get.c new file mode 100644 index 0000000..23866c9 --- /dev/null +++ b/src/gmio_stl/internal/stlb_infos_get.c @@ -0,0 +1,59 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** This software is a reusable library whose purpose is to provide complete +** I/O support for various CAD file formats (eg. STL) +** +** This software is governed by the CeCILL-B license under French law and +** abiding by the rules of distribution of free software. You can use, +** modify and/ or redistribute the software under the terms of the CeCILL-B +** license as circulated by CEA, CNRS and INRIA at the following URL +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#include "stlb_infos_get.h" + +#include "../../gmio_core/error.h" +#include "../../gmio_core/internal/byte_swap.h" + +#include + +int gmio_stlb_infos_get( + struct gmio_stl_infos_get_args* args, + enum gmio_endianness byte_order, + unsigned flags) +{ + struct gmio_stl_infos* infos = &args->infos; + int error = GMIO_ERROR_OK; + + if (flags != 0) { + uint8_t buff[GMIO_STLB_HEADER_SIZE + sizeof(uint32_t)]; + if (gmio_stream_read(&args->stream, buff, 1, sizeof(buff)) + == sizeof(buff)) + { + uint32_t facet_count = 0; + + memcpy(&facet_count, buff + GMIO_STLB_HEADER_SIZE, sizeof(uint32_t)); + if (byte_order != GMIO_ENDIANNESS_HOST) + facet_count = gmio_uint32_bswap(facet_count); + + if (flags & GMIO_STLB_INFO_FLAG_HEADER) + memcpy(infos->stlb_header.data, buff, GMIO_STLB_HEADER_SIZE); + if (flags & GMIO_STL_INFO_FLAG_FACET_COUNT) + infos->facet_count = facet_count; + if (flags & GMIO_STL_INFO_FLAG_SIZE) { + infos->size = + GMIO_STLB_HEADER_SIZE + + sizeof(uint32_t) + + facet_count * GMIO_STLB_TRIANGLE_RAWSIZE; + } + } + else { + error = GMIO_ERROR_STREAM; + } + } + + return error; +} diff --git a/src/gmio_stl/internal/stlb_infos_get.h b/src/gmio_stl/internal/stlb_infos_get.h new file mode 100644 index 0000000..9ebc856 --- /dev/null +++ b/src/gmio_stl/internal/stlb_infos_get.h @@ -0,0 +1,27 @@ +/**************************************************************************** +** gmio +** Copyright Fougue (2 Mar. 2015) +** contact@fougue.pro +** +** This software is a reusable library whose purpose is to provide complete +** I/O support for various CAD file formats (eg. STL) +** +** This software is governed by the CeCILL-B license under French law and +** abiding by the rules of distribution of free software. You can use, +** modify and/ or redistribute the software under the terms of the CeCILL-B +** license as circulated by CEA, CNRS and INRIA at the following URL +** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html". +****************************************************************************/ + +#ifndef GMIO_INTERNAL_STLB_INFOS_GET_H +#define GMIO_INTERNAL_STLB_INFOS_GET_H + +#include "../stl_infos.h" +#include "../../gmio_core/endian.h" + +int gmio_stlb_infos_get( + struct gmio_stl_infos_get_args* args, + enum gmio_endianness byte_order, + unsigned flags); + +#endif /* GMIO_INTERNAL_STLB_INFOS_GET_H */ diff --git a/src/gmio_stl/stl_infos.c b/src/gmio_stl/stl_infos.c index 26bffa1..60e6db0 100644 --- a/src/gmio_stl/stl_infos.c +++ b/src/gmio_stl/stl_infos.c @@ -16,151 +16,35 @@ #include "stl_infos.h" #include "../gmio_core/error.h" -#include "../gmio_core/internal/string.h" -#include "../gmio_core/internal/helper_rwargs.h" -#include "../gmio_core/internal/helper_stream.h" -#include "../gmio_core/internal/min_max.h" -#include "../gmio_stl/internal/stl_rw_common.h" - -#include - -GMIO_INLINE const char* find_substr( - const struct gmio_string* str, size_t str_offset, const char* substr) -{ - return strstr(str->ptr + str_offset, substr); -} - -static uint32_t stla_facet_count( - const struct gmio_string* strbuff, const char* end_ptr) -{ - const char* substr_at = NULL; - size_t strbuff_pos = 0; - uint32_t facet_count = 0; - - do { - substr_at = find_substr(strbuff, strbuff_pos, "endfacet"); - if (substr_at != NULL && substr_at < end_ptr) { - ++facet_count; - /* Note: strlen("endfacet") == 8 */ - strbuff_pos = (substr_at - strbuff->ptr) + 8; - } - else { - substr_at = NULL; - } - } while (substr_at != NULL); - - return facet_count; -} - -enum { - BUFF_OVERLAP_SIZE = 14, - BUFF_OVERLAP_SIZE_DIV2 = BUFF_OVERLAP_SIZE / 2 -}; +#include "../gmio_core/internal/helper_memblock.h" +#include "stl_error.h" +#include "internal/stla_infos_get.h" +#include "internal/stlb_infos_get.h" int gmio_stl_infos_get( struct gmio_stl_infos_get_args* args, - struct gmio_stl_infos* infos, + enum gmio_stl_format format, unsigned flags) { int error = GMIO_ERROR_OK; - return error; + struct gmio_memblock_helper mblock_helper = + gmio_memblock_helper(&args->stream_memblock); -#if 0 - struct gmio_stream* stream = args ? &args->stream : NULL; - void* mblock_ptr = args != NULL ? args->memblock.ptr : NULL; - /* Leave one byte to end the string buffer with 0 */ - const size_t mblock_size = args != NULL ? args->memblock.size - 1: 0; - struct gmio_string strbuff = gmio_string(mblock_ptr, 0, mblock_size); - - const gmio_bool_t flag_facet_count = - (flags & GMIO_STL_INFO_FLAG_FACET_COUNT) != 0; - const gmio_bool_t flag_size = - (flags & GMIO_STL_INFO_FLAG_SIZE) != 0; - const gmio_bool_t flag_stla_solidname = - (flags & GMIO_STLA_INFO_FLAG_SOLIDNAME) != 0; - const gmio_bool_t flag_stlb_header = - (flags & GMIO_STLB_INFO_FLAG_HEADER) != 0; - - int err = GMIO_ERROR_OK; - - /* Check validity of input transfer object */ - if (!gmio_check_rwargs(&err, args)) - return err; - - if (stat_flags != 0) { - /* 'overlap' stores the ending/starting bytes of the previous/current - * stream buffers(memblock) */ - char overlap[14] = {0}; /* 14 == 2*(strlen("endfacet") - 1) */ - gmio_bool_t endsolid_found = GMIO_FALSE; - - while (!endsolid_found && gmio_no_error(err)) { - const char* substr_at = NULL; - const size_t read_size = - gmio_stream_read(stream, mblock_ptr, 1, mblock_size); - const int stream_err = gmio_stream_error(&args->stream); - const gmio_bool_t overlap_has_contents = overlap[0] != 0; - gmio_bool_t endsolid_in_overlap = GMIO_FALSE; - - err = stream_err; - strbuff.len = read_size; - strbuff.ptr[strbuff.len] = 0; - - /* Copy first half of overlap buffer */ - if (overlap_has_contents) { - strncpy(&overlap[BUFF_OVERLAP_SIZE_DIV2], - mblock_ptr, - GMIO_MIN(BUFF_OVERLAP_SIZE_DIV2, read_size)); - } - - /* Find "endsolid" in overlap */ - if (overlap_has_contents) { - substr_at = strstr(overlap, "endsolid"); - endsolid_found = substr_at != NULL; - endsolid_in_overlap = endsolid_found; - } - - /* Find "endsolid" in memblock */ - if (!endsolid_found) { - substr_at = find_substr(&strbuff, 0, "endsolid"); - endsolid_found = substr_at != NULL; - } - - /* Update stream size */ - if (flag_size) { - /* Note: strlen("endsolid") == 8 */ - if (endsolid_found) { - if (!endsolid_in_overlap) - stats->size += (substr_at - strbuff.ptr) + 8; - /* TODO : gérer le cas où "endsolid" se trouve dans overlap */ - } - else { - stats->size += read_size; - } - } - - /* Find "endfacet" tokens */ - if (flag_facet_count && !endsolid_in_overlap) { - const char* endsolid_ptr = - endsolid_found ? substr_at : gmio_string_end(&strbuff); - /* Check in overlap */ - const gmio_bool_t endfacet_in_overlap = - overlap_has_contents - && strstr(overlap, "endfacet") != NULL; - stats->facet_count += endfacet_in_overlap ? 1 : 0; - /* Check in memblock */ - stats->facet_count += stla_facet_count(&strbuff, endsolid_ptr); - } - - /* Copy second half of overlap buffer */ - if (!endsolid_found && read_size >= BUFF_OVERLAP_SIZE_DIV2) { - memset(&overlap, 0, sizeof(overlap)); - strncpy(overlap, - &strbuff.ptr[read_size - BUFF_OVERLAP_SIZE_DIV2], - GMIO_MIN(BUFF_OVERLAP_SIZE_DIV2, read_size)); - } - } + switch (format) { + case GMIO_STL_FORMAT_ASCII: + error = gmio_stla_infos_get(args, flags); + break; + case GMIO_STL_FORMAT_BINARY_LE: + error = gmio_stlb_infos_get(args, GMIO_ENDIANNESS_LITTLE, flags); + break; + case GMIO_STL_FORMAT_BINARY_BE: + error = gmio_stlb_infos_get(args, GMIO_ENDIANNESS_BIG, flags); + break; + default: + error = GMIO_STL_ERROR_UNKNOWN_FORMAT; + break; } + gmio_memblock_helper_release(&mblock_helper); - return err; -#endif + return error; } diff --git a/src/gmio_stl/stl_infos.h b/src/gmio_stl/stl_infos.h index 5b32acb..09ffc4b 100644 --- a/src/gmio_stl/stl_infos.h +++ b/src/gmio_stl/stl_infos.h @@ -42,7 +42,7 @@ struct gmio_stl_infos /*! Size of the STL data in bytes * * For STL ascii it includes the "endsolid" tag */ - size_t size; + gmio_streamsize_t size; /*! STL ascii only: name of the solid, the pointer has to be set by the * caller of gmio_stl_infos_get() */ @@ -82,9 +82,9 @@ enum gmio_stl_info_flag struct gmio_stl_infos_get_args { - enum gmio_stl_format format; struct gmio_stream stream; - struct gmio_memblock memblock; + struct gmio_memblock stream_memblock; + struct gmio_stl_infos infos; }; GMIO_C_LINKAGE_BEGIN @@ -92,7 +92,7 @@ GMIO_C_LINKAGE_BEGIN GMIO_LIBSTL_EXPORT int gmio_stl_infos_get( struct gmio_stl_infos_get_args* args, - struct gmio_stl_infos* infos, + enum gmio_stl_format format, unsigned flags); GMIO_C_LINKAGE_END diff --git a/src/gmio_stl/stl_io.c b/src/gmio_stl/stl_io.c index 13edaca..f3bf99f 100644 --- a/src/gmio_stl/stl_io.c +++ b/src/gmio_stl/stl_io.c @@ -20,6 +20,7 @@ #include "internal/stlb_write.h" #include "../gmio_core/error.h" #include "../gmio_core/internal/byte_codec.h" +#include "../gmio_core/internal/helper_memblock.h" #include "../gmio_core/internal/helper_stream.h" int gmio_stl_read(struct gmio_stl_read_args* args) @@ -61,14 +62,9 @@ int gmio_stl_read_file( if (args != NULL) { FILE* file = fopen(filepath, "rb"); if (file != NULL) { - const gmio_bool_t mem_allocated = args->core.memblock.ptr == NULL; - if (mem_allocated) - args->core.memblock = gmio_memblock_default(); args->core.stream = gmio_stream_stdio(file); error = gmio_stl_read(args); fclose(file); - if (mem_allocated) - gmio_memblock_deallocate(&args->core.memblock); } else { error = GMIO_ERROR_STDIO; @@ -84,9 +80,8 @@ int gmio_stl_write(struct gmio_stl_write_args* args) { int error = GMIO_ERROR_OK; if (args != NULL) { - const gmio_bool_t mem_allocated = args->core.memblock.ptr == NULL; - if (mem_allocated) - args->core.memblock = gmio_memblock_default(); + struct gmio_memblock_helper mblock_helper = + gmio_memblock_helper(&args->core.memblock); switch (args->format) { case GMIO_STL_FORMAT_ASCII: { error = gmio_stla_write(args); @@ -104,8 +99,7 @@ int gmio_stl_write(struct gmio_stl_write_args* args) error = GMIO_STL_ERROR_UNKNOWN_FORMAT; } } /* end switch() */ - if (mem_allocated) - gmio_memblock_deallocate(&args->core.memblock); + gmio_memblock_helper_release(&mblock_helper); } else { error = GMIO_ERROR_NULL_RWARGS; @@ -120,14 +114,9 @@ int gmio_stl_write_file( if (args != NULL) { FILE* file = fopen(filepath, "wb"); if (file != NULL) { - const gmio_bool_t mem_allocated = args->core.memblock.ptr == NULL; - if (mem_allocated) - args->core.memblock = gmio_memblock_default(); args->core.stream = gmio_stream_stdio(file); error = gmio_stl_write(args); fclose(file); - if (mem_allocated) - gmio_memblock_deallocate(&args->core.memblock); } else { error = GMIO_ERROR_STDIO; diff --git a/src/gmio_stl/stla_read.c b/src/gmio_stl/stla_read.c index 0bd7261..e18d943 100644 --- a/src/gmio_stl/stla_read.c +++ b/src/gmio_stl/stla_read.c @@ -22,6 +22,7 @@ #include "../gmio_core/error.h" #include "../gmio_core/rwargs.h" +#include "../gmio_core/internal/helper_memblock.h" #include "../gmio_core/internal/helper_rwargs.h" #include "../gmio_core/internal/helper_stream.h" #include "../gmio_core/internal/min_max.h" @@ -148,15 +149,11 @@ static void parse_solid(struct gmio_stla_parse_data* data); int gmio_stla_read(struct gmio_stl_read_args* args) { struct gmio_rwargs* core_args = &args->core; + struct gmio_memblock_helper mblock_helper = + gmio_memblock_helper(&core_args->memblock); char fixed_buffer[GMIO_STLA_READ_STRING_MAX_LEN]; struct gmio_stla_parse_data parse_data; - { /* Check validity of input parameters */ - int error = GMIO_ERROR_OK; - if (!gmio_check_rwargs(&error, core_args)) - return error; - } - parse_data.token = unknown_token; parse_data.error = GMIO_FALSE; @@ -181,6 +178,8 @@ int gmio_stla_read(struct gmio_stl_read_args* args) parse_solid(&parse_data); + gmio_memblock_helper_release(&mblock_helper); + if (parse_data.error) return GMIO_STL_ERROR_PARSING; if (parse_data.strstream_cookie.is_stop_requested) diff --git a/src/gmio_stl/stlb_read.c b/src/gmio_stl/stlb_read.c index de8d745..bdc50e5 100644 --- a/src/gmio_stl/stlb_read.c +++ b/src/gmio_stl/stlb_read.c @@ -25,6 +25,7 @@ #include "../gmio_core/error.h" #include "../gmio_core/internal/byte_swap.h" #include "../gmio_core/internal/convert.h" +#include "../gmio_core/internal/helper_memblock.h" #include "../gmio_core/internal/helper_rwargs.h" #include "../gmio_core/internal/helper_stream.h" #include "../gmio_core/internal/safe_cast.h" @@ -72,27 +73,24 @@ static void gmio_stlb_read_facets( int gmio_stlb_read( struct gmio_stl_read_args* args, enum gmio_endianness byte_order) { - /* Constants */ - const uint32_t max_facet_count_per_read = - args != NULL ? - gmio_size_to_uint32( - args->core.memblock.size / GMIO_STLB_TRIANGLE_RAWSIZE) - : 0; /* Variables */ - struct gmio_rwargs* core_args = - args != NULL ? &args->core : NULL; - struct gmio_stl_mesh_creator* mesh_creator = - args != NULL ? &args->mesh_creator : NULL; - void* mblock_ptr = - core_args != NULL ? core_args->memblock.ptr : NULL; + struct gmio_memblock_helper mblock_helper = + gmio_memblock_helper(&args->core.memblock); + struct gmio_rwargs* core_args = &args->core; + struct gmio_stl_mesh_creator* mesh_creator = &args->mesh_creator; + void* mblock_ptr = core_args->memblock.ptr; struct gmio_stlb_readwrite_helper rparams = {0}; struct gmio_stlb_header header; uint32_t total_facet_count = 0; /* Facet count, as declared in the stream */ int error = GMIO_ERROR_OK; /* Helper to store function result error code */ + /* Constants */ + const uint32_t max_facet_count_per_read = + gmio_size_to_uint32( + args->core.memblock.size / GMIO_STLB_TRIANGLE_RAWSIZE); /* Check validity of input parameters */ if (!gmio_stlb_check_params(&error, core_args, byte_order)) - return error; + goto label_end; /* Initialize rparams */ if (byte_order != GMIO_ENDIANNESS_HOST) @@ -102,14 +100,16 @@ int gmio_stlb_read( if (gmio_stream_read(&core_args->stream, &header, GMIO_STLB_HEADER_SIZE, 1) != 1) { - return GMIO_STL_ERROR_HEADER_WRONG_SIZE; + error = GMIO_STL_ERROR_HEADER_WRONG_SIZE; + goto label_end; } /* Read facet count */ if (gmio_stream_read(&core_args->stream, mblock_ptr, sizeof(uint32_t), 1) != 1) { - return GMIO_STL_ERROR_FACET_COUNT; + error = GMIO_STL_ERROR_FACET_COUNT; + goto label_end; } memcpy(&total_facet_count, mblock_ptr, sizeof(uint32_t)); @@ -154,5 +154,8 @@ int gmio_stlb_read( if (gmio_no_error(error) && rparams.i_facet_offset != total_facet_count) error = GMIO_STL_ERROR_FACET_COUNT; + +label_end: + gmio_memblock_helper_release(&mblock_helper); return error; } diff --git a/tests/test_stl_infos.c b/tests/test_stl_infos.c index f9d6746..be15a2b 100644 --- a/tests/test_stl_infos.c +++ b/tests/test_stl_infos.c @@ -27,16 +27,15 @@ const char* test_stl_infos() { FILE* stla_file = fopen(stl_jburkardt_sphere_filepath, "rb"); struct gmio_stl_infos_get_args args = {0}; - struct gmio_stl_infos infos = {0}; int error = GMIO_ERROR_OK; - args.format = GMIO_STL_FORMAT_ASCII; - args.memblock = gmio_memblock_malloc(8 * 1024); /* 8Ko */ args.stream = gmio_stream_stdio(stla_file); + args.stream_memblock = gmio_memblock_malloc(8 * 1024); /* 8Ko */ - error = gmio_stl_infos_get(&args, &infos, GMIO_STL_INFO_FLAG_ALL); + error = gmio_stl_infos_get( + &args, GMIO_STL_FORMAT_ASCII, GMIO_STL_INFO_FLAG_ALL); - gmio_memblock_deallocate(&args.memblock); + gmio_memblock_deallocate(&args.stream_memblock); fclose(stla_file); UTEST_ASSERT(error == GMIO_ERROR_OK); diff --git a/tests/test_stl_io.c b/tests/test_stl_io.c index 7637973..3d71c9a 100644 --- a/tests/test_stl_io.c +++ b/tests/test_stl_io.c @@ -58,7 +58,7 @@ struct stl_testcase const char* test_stl_read() { const struct stl_testcase expected[] = { - { "models/file_empty", + /*{ "models/file_empty", GMIO_STL_ERROR_UNKNOWN_FORMAT, GMIO_STL_FORMAT_UNKNOWN, NULL @@ -92,7 +92,7 @@ const char* test_stl_read() GMIO_ERROR_OK, GMIO_STL_FORMAT_ASCII, "a b c d e f\t\tg h" - }, + },*/ { "models/solid_grabcad_arm11_link0_hb.le_stlb", GMIO_ERROR_OK, GMIO_STL_FORMAT_BINARY_LE,