diff --git a/src/gmio_core/internal/safe_cast.h b/src/gmio_core/internal/safe_cast.h new file mode 100644 index 0000000..b088d57 --- /dev/null +++ b/src/gmio_core/internal/safe_cast.h @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** GeomIO Library +** Copyright FougSys (2 Mar. 2015) +** contact@fougsys.fr +** +** 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". +** +****************************************************************************/ + +/* Warning : this header has no multi-inclusion guard. It must be included only once in the + * translation unit of use. The reason is that all functions defined here are meant to + * be inlined for performance purpose + */ + +#include "../global.h" + +#include + +/*! Returns \p val safely casted to unsigned 32b integer */ +GMIO_INLINE static uint32_t gmio_size_to_uint32(size_t val) +{ +#if GMIO_TARGET_ARCH_BIT_SIZE > 32 + return val > 0xFFFFFFFF ? 0xFFFFFFFF : (uint32_t)val; +#else + return val; +#endif +} diff --git a/src/gmio_core/stream.c b/src/gmio_core/stream.c index 570056f..12c5c58 100644 --- a/src/gmio_core/stream.c +++ b/src/gmio_core/stream.c @@ -65,7 +65,7 @@ gmio_bool_t gmio_stream_at_end(gmio_stream_t* stream) { if (stream != NULL && stream->at_end_func != NULL) return stream->at_end_func(stream->cookie); - return 0; + return GMIO_FALSE; } int gmio_stream_error(gmio_stream_t* stream) diff --git a/src/gmio_stl/stla_write.c b/src/gmio_stl/stla_write.c index b4cdbca..4df54bc 100644 --- a/src/gmio_stl/stla_write.c +++ b/src/gmio_stl/stla_write.c @@ -22,6 +22,7 @@ #include "../gmio_core/error.h" #include "../gmio_core/internal/min_max.h" +#include "../gmio_core/internal/safe_cast.h" #include #include @@ -119,7 +120,9 @@ int gmio_stla_write(const gmio_stl_mesh_t* mesh, const char* solid_name = options != NULL ? options->solid_name : NULL; const uint8_t real32_prec = options != NULL ? options->real32_prec : 9; const uint32_t total_facet_count = mesh != NULL ? mesh->triangle_count : 0; - const uint32_t buffer_facet_count = trsf != NULL ? trsf->buffer_size / GMIO_STLA_FACET_SIZE_P2 : 0; + const uint32_t buffer_facet_count = + trsf != NULL ? + gmio_size_to_uint32(trsf->buffer_size / GMIO_STLA_FACET_SIZE_P2) : 0; uint32_t ifacet = 0; char* buffer_iterator = trsf != NULL ? trsf->buffer : NULL; char coords_format[64]; diff --git a/src/gmio_stl/stlb_read.c b/src/gmio_stl/stlb_read.c index 49e3255..c8283c8 100644 --- a/src/gmio_stl/stlb_read.c +++ b/src/gmio_stl/stlb_read.c @@ -23,8 +23,9 @@ #include "../gmio_core/endian.h" #include "../gmio_core/error.h" -#include "../gmio_core/internal/convert.h" #include "../gmio_core/internal/byte_swap.h" +#include "../gmio_core/internal/convert.h" +#include "../gmio_core/internal/safe_cast.h" #include @@ -66,10 +67,13 @@ int gmio_stlb_read(gmio_stl_mesh_creator_t *creator, const gmio_stlb_read_options_t* options) { const gmio_endianness_t host_byte_order = gmio_host_endianness(); - const gmio_endianness_t byte_order = options != NULL ? options->byte_order : host_byte_order; + const gmio_endianness_t byte_order = + options != NULL ? options->byte_order : host_byte_order; + const uint32_t max_facet_count_per_read = + gmio_size_to_uint32(trsf->buffer_size / GMIO_STLB_TRIANGLE_RAWSIZE); gmio_stlb_readwrite_helper_t rparams = {0}; uint8_t header_data[GMIO_STLB_HEADER_SIZE]; - uint32_t total_facet_count = 0; /* Count of facets as declared in the stream */ + uint32_t total_facet_count = 0; /* Count of facets as declared in the stream */ int error = GMIO_NO_ERROR; /* Helper variable to store function result error code */ /* Check validity of input parameters */ @@ -103,10 +107,13 @@ int gmio_stlb_read(gmio_stl_mesh_creator_t *creator, while (gmio_no_error(error) && rparams.i_facet_offset < total_facet_count) { - rparams.facet_count = gmio_stream_read(&trsf->stream, - trsf->buffer, - GMIO_STLB_TRIANGLE_RAWSIZE, - trsf->buffer_size / GMIO_STLB_TRIANGLE_RAWSIZE); + rparams.facet_count = + gmio_size_to_uint32( + gmio_stream_read( + &trsf->stream, + trsf->buffer, + GMIO_STLB_TRIANGLE_RAWSIZE, + max_facet_count_per_read)); if (gmio_stream_error(&trsf->stream) != 0) error = GMIO_STREAM_ERROR; else if (rparams.facet_count > 0) diff --git a/src/gmio_stl/stlb_write.c b/src/gmio_stl/stlb_write.c index 24e5106..fb1f0c9 100644 --- a/src/gmio_stl/stlb_write.c +++ b/src/gmio_stl/stlb_write.c @@ -24,6 +24,8 @@ #include "../gmio_core/endian.h" #include "../gmio_core/error.h" #include "../gmio_core/internal/byte_codec.h" +#include "../gmio_core/internal/min_max.h" +#include "../gmio_core/internal/safe_cast.h" #include @@ -80,7 +82,7 @@ int gmio_stlb_write(const gmio_stl_mesh_t* mesh, /* Initialize wparams */ if (host_byte_order != byte_order) wparams.fix_endian_func = gmio_stl_triangle_bswap; - wparams.facet_count = trsf->buffer_size / GMIO_STLB_TRIANGLE_RAWSIZE; + wparams.facet_count = gmio_size_to_uint32(trsf->buffer_size / GMIO_STLB_TRIANGLE_RAWSIZE); /* Write header */ if (header_data == NULL) { @@ -105,8 +107,8 @@ int gmio_stlb_write(const gmio_stl_mesh_t* mesh, i_facet += wparams.facet_count) { /* Write to buffer */ - if (wparams.facet_count > (facet_count - wparams.i_facet_offset)) - wparams.facet_count = facet_count - wparams.i_facet_offset; + wparams.facet_count = _GMIO_INTERNAL_MIN(wparams.facet_count, + facet_count - wparams.i_facet_offset); gmio_stlb_write_facets(mesh, trsf->buffer, &wparams); wparams.i_facet_offset += wparams.facet_count;