gmio: add get/set_pos functions to gmio_stream

This commit is contained in:
Hugues Delorme 2015-09-18 14:33:23 +02:00
parent 035e9c2ba6
commit b0517b2f39
9 changed files with 133 additions and 27 deletions

View File

@ -60,11 +60,21 @@ GMIO_INLINE size_t gmio_stream_size(gmio_stream_t* stream)
return 0;
}
/*! Safe and convenient function for gmio_stream::func_rewind() */
GMIO_INLINE void gmio_stream_rewind(gmio_stream_t* stream)
/*! Safe and convenient function for gmio_stream::func_get_pos() */
GMIO_INLINE int gmio_stream_get_pos(
gmio_stream_t* stream, gmio_stream_pos_t* pos)
{
if (stream != NULL && stream->func_rewind != NULL)
stream->func_rewind(stream->cookie);
if (stream != NULL && stream->func_get_pos != NULL)
return stream->func_get_pos(stream->cookie, pos);
return -1;
}
/*! Safe and convenient function for gmio_stream::func_set_pos() */
GMIO_INLINE int gmio_stream_set_pos(
gmio_stream_t* stream, const gmio_stream_pos_t* pos)
{
if (stream != NULL && stream->func_set_pos != NULL)
return stream->func_set_pos(stream->cookie, pos);
return -1;
}
#endif /* GMIO_INTERNAL_HELPER_STREAM_H */

View File

@ -129,9 +129,19 @@ static size_t gmio_stream_stdio_size(void* cookie)
#endif
}
static void gmio_stream_stdio_rewind(void* cookie)
static int gmio_stream_stdio_get_pos(void* cookie, gmio_stream_pos_t* pos)
{
rewind((FILE*) cookie);
fpos_t fpos;
int res = fgetpos((FILE*)cookie, &fpos);
memcpy(&pos->cookie[0], &fpos, sizeof(fpos_t));
return res;
}
static int gmio_stream_stdio_set_pos(void* cookie, const gmio_stream_pos_t* pos)
{
fpos_t fpos;
memcpy(&fpos, &pos->cookie[0], sizeof(fpos_t));
return fsetpos((FILE*)cookie, &fpos);
}
gmio_stream_t gmio_stream_stdio(FILE* file)
@ -143,6 +153,7 @@ gmio_stream_t gmio_stream_stdio(FILE* file)
stream.func_read = gmio_stream_stdio_read;
stream.func_write = gmio_stream_stdio_write;
stream.func_size = gmio_stream_stdio_size;
stream.func_rewind = gmio_stream_stdio_rewind;
stream.func_get_pos = gmio_stream_stdio_get_pos;
stream.func_set_pos = gmio_stream_stdio_set_pos;
return stream;
}

View File

@ -24,6 +24,7 @@
#define GMIO_STREAM_H
#include "global.h"
#include "stream_pos.h"
#include <stdio.h>
/*! Stream that can get input from an arbitrary data source or can write
@ -94,17 +95,13 @@ struct gmio_stream
/*! Pointer on a function that returns the size(in bytes) of the stream */
size_t (*func_size)(void* cookie);
/*! Pointer on a function that moves the position indicator within the
* stream to the beginning
*
* The function should behaves like C standard [rewind()]
* (http://pubs.opengroup.org/onlinepubs/007904975/functions/rewind.html)
*/
void (*func_rewind)(void* cookie);
int (*func_get_pos)(void* cookie, gmio_stream_pos_t* pos);
int (*func_set_pos)(void* cookie, const gmio_stream_pos_t* pos);
};
typedef struct gmio_stream gmio_stream_t;
GMIO_C_LINKAGE_BEGIN
/* Initialization */

View File

@ -0,0 +1,25 @@
/****************************************************************************
** 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 "stream_pos.h"
#include <stdio.h>
#include <stdlib.h>
gmio_stream_pos_t gmio_stream_pos_null()
{
gmio_stream_pos_t pos = {0};
return pos;
}

View File

@ -0,0 +1,46 @@
/****************************************************************************
** 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".
****************************************************************************/
/*! \file stream_pos.h
* Declaration of gmio_stream_pos and utility functions
*
* \addtogroup gmio_core
* @{
*/
#ifndef GMIO_STREAM_POS_H
#define GMIO_STREAM_POS_H
#include "global.h"
enum { GMIO_STREAM_POS_COOKIE_SIZE = 32 }; /* 32 bytes */
/*! Stream position
*
*/
struct gmio_stream_pos
{
uint8_t cookie[GMIO_STREAM_POS_COOKIE_SIZE];
};
typedef struct gmio_stream_pos gmio_stream_pos_t;
GMIO_C_LINKAGE_BEGIN
GMIO_LIB_EXPORT gmio_stream_pos_t gmio_stream_pos_null();
GMIO_C_LINKAGE_END
#endif /* GMIO_STREAM_POS_H */
/*! @} */

View File

@ -33,16 +33,20 @@ gmio_stl_format_t gmio_stl_get_format(gmio_stream_t *stream)
{
char fixed_buffer[GMIO_FIXED_BUFFER_SIZE];
size_t read_size = 0;
gmio_stream_pos_t stream_start_pos = gmio_stream_pos_null();
if (stream == NULL)
return GMIO_STL_FORMAT_UNKNOWN;
/* Read a chunk of bytes from stream, then try to find format from that */
/* Read a chunk of bytes from stream, then try to find format from that
*
* First keep stream start position, it will be restored after read
*/
gmio_stream_get_pos(stream, &stream_start_pos);
memset(fixed_buffer, 0, GMIO_FIXED_BUFFER_SIZE);
read_size = gmio_stream_read(stream, &fixed_buffer, 1, GMIO_FIXED_BUFFER_SIZE);
read_size = GMIO_MIN(read_size, GMIO_FIXED_BUFFER_SIZE);
gmio_stream_rewind(stream);
gmio_stream_set_pos(stream, &stream_start_pos);
/* Binary STL ? */
if (read_size >= (GMIO_STLB_HEADER_SIZE + 4)) {

View File

@ -18,6 +18,8 @@
#include <QtCore/QFile>
#include <QtCore/QIODevice>
#include <cstring>
QT_USE_NAMESPACE
static gmio_bool_t gmio_stream_qiodevice_at_end(void* cookie)
@ -62,10 +64,23 @@ static size_t gmio_stream_qiodevice_size(void* cookie)
return device->size();
}
static void gmio_stream_qiodevice_rewind(void* cookie)
static int gmio_stream_qiodevice_get_pos(void* cookie, gmio_stream_pos_t* pos)
{
QIODevice* device = static_cast<QIODevice*>(cookie);
device->seek(0);
qint64 qpos = device->pos();
std::memcpy(&pos->cookie[0], &qpos, sizeof(qint64));
return 0;
}
static int gmio_stream_qiodevice_set_pos(
void* cookie, const gmio_stream_pos_t* pos)
{
QIODevice* device = static_cast<QIODevice*>(cookie);
qint64 qpos;
std::memcpy(&qpos, &pos->cookie[0], sizeof(qint64));
if (device->seek(qpos))
return 0;
return -1; /* TODO: return error code */
}
gmio_stream_t gmio_stream_qiodevice(QIODevice* device)
@ -77,6 +92,7 @@ gmio_stream_t gmio_stream_qiodevice(QIODevice* device)
stream.func_read = gmio_stream_qiodevice_read;
stream.func_write = gmio_stream_qiodevice_write;
stream.func_size = gmio_stream_qiodevice_size;
stream.func_rewind = gmio_stream_qiodevice_rewind;
stream.func_get_pos = gmio_stream_qiodevice_get_pos;
stream.func_set_pos = gmio_stream_qiodevice_set_pos;
return stream;
}

View File

@ -22,6 +22,9 @@ public:
virtual qint64 size() const
{ return 0; }
virtual qint64 pos() const
{ return 0; }
virtual bool seek(qint64 /*pos*/)
{ return true; }
};

View File

@ -84,12 +84,6 @@ static size_t gmio_stream_buffer_size(void* cookie)
return buff->len;
}
static void gmio_stream_buffer_rewind(void* cookie)
{
gmio_stream_buffer_t* buff = (gmio_stream_buffer_t*)cookie;
buff->pos = 0;
}
void gmio_stream_set_buffer(gmio_stream_t *stream, gmio_stream_buffer_t* buff)
{
stream->cookie = buff;
@ -98,5 +92,5 @@ void gmio_stream_set_buffer(gmio_stream_t *stream, gmio_stream_buffer_t* buff)
stream->func_read = gmio_stream_buffer_read;
stream->func_write = gmio_stream_buffer_write;
stream->func_size = gmio_stream_buffer_size;
stream->func_rewind = gmio_stream_buffer_rewind;
/* TODO: implement func_get/set_pos functions */
}