gmio/src/gmio_core/internal/ascii_parse.c

135 lines
3.6 KiB
C
Raw Normal View History

2015-03-03 00:38:33 +08:00
/****************************************************************************
**
** 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".
**
****************************************************************************/
#include "ascii_parse.h"
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
void gmio_ascii_stream_fwd_iterator_init(gmio_ascii_stream_fwd_iterator_t *it)
2014-01-28 05:57:10 +08:00
{
/* Trick: declaring the buffer exhausted will actually trigger the first call to
* gmio_stream_read() inside gmio_next_char()
2014-01-28 05:57:10 +08:00
*/
it->buffer.len = 0;
it->buffer_pos = it->buffer.max_len;
gmio_next_char(it);
2014-01-28 05:57:10 +08:00
}
char *gmio_current_char(const gmio_ascii_stream_fwd_iterator_t *it)
{
2014-01-28 05:57:10 +08:00
if (it != NULL && it->buffer_pos < it->buffer.len)
return it->buffer.ptr + it->buffer_pos;
return NULL;
}
char *gmio_next_char(gmio_ascii_stream_fwd_iterator_t *it)
{
if (it == NULL)
return NULL;
2014-01-28 05:57:10 +08:00
if ((it->buffer_pos + 1) < it->buffer.len) {
++(it->buffer_pos);
return it->buffer.ptr + it->buffer_pos;
}
else {
if (gmio_stream_error(it->stream) != 0 || gmio_stream_at_end(it->stream))
return NULL;
/* Read next chunk of data */
2014-01-28 05:57:10 +08:00
it->buffer_pos = 0;
it->buffer.len = gmio_stream_read(it->stream, it->buffer.ptr, sizeof(char), it->buffer.max_len);
if (gmio_stream_error(it->stream) == 0) {
if (it->stream_read_hook != NULL)
2014-01-28 05:57:10 +08:00
it->stream_read_hook(it->cookie, &it->buffer);
return it->buffer.ptr;
}
}
2014-01-28 05:57:10 +08:00
return NULL;
}
void gmio_skip_spaces(gmio_ascii_stream_fwd_iterator_t *it)
{
const char* curr_char = gmio_current_char(it);
while (curr_char != NULL && isspace(*curr_char))
curr_char = gmio_next_char(it);
}
int gmio_eat_word(gmio_ascii_stream_fwd_iterator_t *it, gmio_ascii_string_buffer_t *buffer)
{
const char* stream_curr_char = NULL;
int isspace_res = 0;
size_t i = 0;
2014-01-28 05:57:10 +08:00
if (buffer == NULL || buffer->ptr == NULL)
return -1;
2014-01-28 05:57:10 +08:00
buffer->len = 0;
gmio_skip_spaces(it);
stream_curr_char = gmio_current_char(it);
2014-01-28 05:57:10 +08:00
while (i < buffer->max_len && stream_curr_char != NULL && isspace_res == 0) {
isspace_res = isspace(*stream_curr_char);
if (isspace_res == 0) {
2014-01-28 05:57:10 +08:00
buffer->ptr[i] = *stream_curr_char;
stream_curr_char = gmio_next_char(it);
++i;
}
}
2014-01-28 05:57:10 +08:00
if (i < buffer->max_len) {
buffer->ptr[i] = 0; /* End string with terminating null byte */
buffer->len = i;
if (stream_curr_char != NULL || gmio_stream_at_end(it->stream))
return 0;
return -2;
}
return -3;
}
int gmio_get_real32(const char *str, gmio_real32_t *value_ptr)
{
char* end_ptr; /* for strtod() */
#ifdef GMIO_HAVE_STRTOF_FUNC
*value_ptr = strtof(str, &end_ptr); /* Requires C99 */
#else
*value_ptr = (gmio_real32_t)strtod(str, &end_ptr);
#endif
if (end_ptr == str || errno == ERANGE)
return -1;
return 0;
}
gmio_bool_t gmio_checked_next_chars(gmio_ascii_stream_fwd_iterator_t *it, const char *str)
{
size_t pos = 0;
const char* curr_char = gmio_current_char(it);
gmio_bool_t same = curr_char != NULL && *curr_char == *str;
while (same) {
curr_char = gmio_next_char(it);
same = curr_char != NULL && *curr_char == str[++pos];
}
return same;
}