c-lib: initial work about base C library of FougDataEx
This commit is contained in:
parent
598c376eb4
commit
5f4ed36e9f
2
qmake.build/c/c.pro
Normal file
2
qmake.build/c/c.pro
Normal file
@ -0,0 +1,2 @@
|
||||
TEMPLATE = subdirs
|
||||
SUBDIRS += libstl
|
50
qmake.build/c/libstl/libstl.pro
Normal file
50
qmake.build/c/libstl/libstl.pro
Normal file
@ -0,0 +1,50 @@
|
||||
isEmpty(PREFIX_DIR) {
|
||||
PREFIX_DIR = ../../..
|
||||
}
|
||||
|
||||
include(../../config.pri)
|
||||
|
||||
message($$PREFIX_DIR)
|
||||
|
||||
TEMPLATE = lib
|
||||
TARGET = fougstl-c$$TARGET_SUFFIX
|
||||
DESTDIR = $$PREFIX_DIR/lib
|
||||
CONFIG *= dll
|
||||
|
||||
dll {
|
||||
DEFINES *= FOUG_STL_DLL FOUG_STL_MAKE_DLL
|
||||
}
|
||||
|
||||
#*g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
|
||||
#*g++*:QMAKE_CXXFLAGS_RELEASE += -O3
|
||||
|
||||
INCLUDEPATH += ../../../src
|
||||
|
||||
HEADERS += \
|
||||
../../../src/c/foug_global.h \
|
||||
../../../src/c/memory.h \
|
||||
../../../src/c/stream.h \
|
||||
../../../src/c/task_control.h \
|
||||
../../../src/c/libstl/stlb.h \
|
||||
../../../src/c/libstl/triangle.h
|
||||
|
||||
SOURCES += \
|
||||
../../../src/c/stream.c \
|
||||
../../../src/c/task_control.c \
|
||||
../../../src/c/libstl/stlb.c
|
||||
|
||||
*-g++*:QMAKE_CFLAGS += -ansi
|
||||
|
||||
global_inc.path = $$PREFIX_DIR/include
|
||||
global_inc.files = ../../../src/*.h
|
||||
c_global_inc.path = $$PREFIX_DIR/include/c
|
||||
c_global_inc.files = ../../../src/c/*.h
|
||||
c_streams_inc.path = $$PREFIX_DIR/include/c/streams
|
||||
c_streams_inc.files = ../../../src/c/streams/*.h
|
||||
c_libstl_inc.path = $$PREFIX_DIR/include/c/libstl
|
||||
c_libstl_inc.files = ../../../src/c/libstl/*.h
|
||||
INSTALLS += global_inc c_global_inc c_streams_inc c_libstl_inc
|
||||
|
||||
VER_MAJ = 0
|
||||
VER_MIN = 1
|
||||
VER_PAT = 0
|
@ -1,4 +1,4 @@
|
||||
TEMPLATE = subdirs
|
||||
CONFIG *= ordered
|
||||
|
||||
SUBDIRS += c++
|
||||
SUBDIRS += c c++
|
||||
|
@ -1,38 +1,24 @@
|
||||
#ifndef FOUG_CPP_GLOBAL_H
|
||||
#define FOUG_CPP_GLOBAL_H
|
||||
|
||||
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
|
||||
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
# define FOUG_DECL_EXPORT __declspec(dllexport)
|
||||
# define FOUG_DECL_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# define FOUG_DECL_EXPORT
|
||||
# define FOUG_DECL_IMPORT
|
||||
#endif // WIN
|
||||
|
||||
//#include <QtCore/QtGlobal>
|
||||
#include "../c/foug_global.h"
|
||||
|
||||
namespace foug {
|
||||
|
||||
typedef char Int8;
|
||||
typedef unsigned char UInt8;
|
||||
typedef foug_int8 Int8;
|
||||
typedef foug_uint8 UInt8;
|
||||
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
typedef foug_int16 Int16;
|
||||
typedef foug_uint16 UInt16;
|
||||
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef foug_int32 Int32;
|
||||
typedef foug_uint32 UInt32;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
#else
|
||||
typedef long long Int64;
|
||||
typedef unsigned long long UInt64;
|
||||
#endif // _MSC_VER
|
||||
typedef foug_int64 Int64;
|
||||
typedef foug_uint64 UInt64;
|
||||
|
||||
typedef float Real32;
|
||||
typedef double Real64;
|
||||
typedef foug_real32 Real32;
|
||||
typedef foug_real64 Real64;
|
||||
|
||||
} // namespace foug
|
||||
|
||||
|
35
src/c/foug_global.h
Normal file
35
src/c/foug_global.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef FOUG_C_GLOBAL_H
|
||||
#define FOUG_C_GLOBAL_H
|
||||
|
||||
#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__)
|
||||
|| defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
|
||||
# define FOUG_DECL_EXPORT __declspec(dllexport)
|
||||
# define FOUG_DECL_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# define FOUG_DECL_EXPORT
|
||||
# define FOUG_DECL_IMPORT
|
||||
#endif /* WIN */
|
||||
|
||||
typedef char foug_int8;
|
||||
typedef unsigned char foug_uint8;
|
||||
|
||||
typedef foug_int8 foug_bool;
|
||||
|
||||
typedef short foug_int16;
|
||||
typedef unsigned short foug_uint16;
|
||||
|
||||
typedef int foug_int32;
|
||||
typedef unsigned int foug_uint32;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef __int64 foug_int64;
|
||||
typedef unsigned __int64 foug_uint64;
|
||||
#else
|
||||
typedef long long foug_int64;
|
||||
typedef unsigned long long foug_uint64;
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
typedef float foug_real32;
|
||||
typedef double foug_real64;
|
||||
|
||||
#endif /* FOUG_C_GLOBAL_H */
|
261
src/c/libstl/stlb.c
Normal file
261
src/c/libstl/stlb.c
Normal file
@ -0,0 +1,261 @@
|
||||
#include "stlb.h"
|
||||
|
||||
/*
|
||||
#include "../abstract_task_progress.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
// Read tools
|
||||
|
||||
template<typename NUMERIC>
|
||||
NUMERIC fromLittleEndian(const foug::UInt8* bytes)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<>
|
||||
foug::UInt16 fromLittleEndian<foug::UInt16>(const foug::UInt8* bytes)
|
||||
{
|
||||
// |BB|AA| -> 0xAABB
|
||||
return (bytes[1] << 8) | bytes[0];
|
||||
}
|
||||
|
||||
template<>
|
||||
foug::UInt32 fromLittleEndian<foug::UInt32>(const foug::UInt8* bytes)
|
||||
{
|
||||
// |DD|CC|BB|AA| -> 0xAABBCCDD
|
||||
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
|
||||
}
|
||||
|
||||
template<>
|
||||
foug::Real32 fromLittleEndian<foug::Real32>(const foug::UInt8* bytes)
|
||||
{
|
||||
union
|
||||
{
|
||||
foug::UInt32 asInteger;
|
||||
foug::Real32 asFloat;
|
||||
} helper;
|
||||
|
||||
helper.asInteger = fromLittleEndian<foug::UInt32>(bytes);
|
||||
return helper.asFloat;
|
||||
}
|
||||
|
||||
// Write tools
|
||||
|
||||
template<typename NUMERIC>
|
||||
void toLittleEndian(NUMERIC n, foug::UInt8* bytes)
|
||||
{
|
||||
union {
|
||||
NUMERIC asNumeric;
|
||||
foug::UInt8 asBytes[sizeof(NUMERIC)];
|
||||
} helper;
|
||||
helper.asNumeric = n;
|
||||
// std::copy(helper.asBytes, helper.asBytes + sizeof(NUMERIC), bytes);
|
||||
for (unsigned i = 0; i < sizeof(NUMERIC); ++i)
|
||||
bytes[i] = helper.asBytes[i];
|
||||
}
|
||||
|
||||
namespace foug {
|
||||
namespace stlb {
|
||||
|
||||
static const int stlFacetSize = 50;
|
||||
static const int stlMinFileSize = 284;
|
||||
static const int stlTriangleDataSize = (4 * 3) * sizeof(foug::Real32) + sizeof(foug::UInt16);
|
||||
|
||||
|
||||
void AbstractGeometryBuilder::endTriangles()
|
||||
{
|
||||
}
|
||||
|
||||
Io::Io(AbstractStream *stream)
|
||||
: IoBase(stream)
|
||||
{
|
||||
}
|
||||
|
||||
bool Io::read(AbstractGeometryBuilder* builder)
|
||||
{
|
||||
// // Check file size
|
||||
// const qint64 fileSize = stream->size();
|
||||
// if (((fileSize - stlHeaderSize - stlFacetCountSize) % stlFacetSize != 0)
|
||||
// || fileSize < stlMinFileSize) {
|
||||
// cpp::checkedAssign(err, WrongFileSizeBinaryStlLoadError);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// const int facetCount = (fileSize - stlHeaderSize - stlFacetCountSize) / stlFacetSize;
|
||||
|
||||
if (this->stream() == 0)
|
||||
return false;
|
||||
|
||||
AbstractStream* istream = this->stream();
|
||||
AbstractTaskProgress* progress = this->taskProgress();
|
||||
const UInt32 chunkSize = stlTriangleDataSize * 163;
|
||||
|
||||
UInt8 buffer[8192];
|
||||
char* charBuffer = reinterpret_cast<char*>(buffer);
|
||||
|
||||
// Read header
|
||||
Header headerData;
|
||||
if (istream->read(reinterpret_cast<char*>(&headerData), HeaderSize) != HeaderSize)
|
||||
return false;
|
||||
builder->processHeader(headerData);
|
||||
|
||||
// Read facet count
|
||||
if (istream->read(charBuffer, sizeof(UInt32)) != sizeof(UInt32))
|
||||
return false;
|
||||
const UInt32 facetCount = ::fromLittleEndian<UInt32>(buffer);
|
||||
builder->beginTriangles(facetCount);
|
||||
|
||||
if (progress != 0) {
|
||||
progress->reset();
|
||||
progress->setRange(0., facetCount);
|
||||
}
|
||||
|
||||
// Read triangles
|
||||
const UInt64 totalFacetSize = stlTriangleDataSize * facetCount;
|
||||
UInt64 amountReadSize = 0;
|
||||
stl::Triangle triangle;
|
||||
bool streamError = false;
|
||||
while (amountReadSize < totalFacetSize && !streamError) {
|
||||
const Int64 iReadSize = istream->read(charBuffer, chunkSize);
|
||||
if (iReadSize > 0 && (iReadSize % stlTriangleDataSize == 0)) {
|
||||
const UInt32 iFacetCount = iReadSize / stlTriangleDataSize;
|
||||
UInt32 bufferOffset = 0;
|
||||
for (UInt32 i = 0; i < iFacetCount; ++i) {
|
||||
// Read normal
|
||||
triangle.normal.x = ::fromLittleEndian<Real32>(buffer + bufferOffset);
|
||||
triangle.normal.y = ::fromLittleEndian<Real32>(buffer + 1*sizeof(Real32) + bufferOffset);
|
||||
triangle.normal.z = ::fromLittleEndian<Real32>(buffer + 2*sizeof(Real32) + bufferOffset);
|
||||
|
||||
// Read vertex1
|
||||
triangle.v1.x = ::fromLittleEndian<Real32>(buffer + 3*sizeof(Real32) + bufferOffset);
|
||||
triangle.v1.y = ::fromLittleEndian<Real32>(buffer + 4*sizeof(Real32) + bufferOffset);
|
||||
triangle.v1.z = ::fromLittleEndian<Real32>(buffer + 5*sizeof(Real32) + bufferOffset);
|
||||
|
||||
// Read vertex2
|
||||
triangle.v2.x = ::fromLittleEndian<Real32>(buffer + 6*sizeof(Real32) + bufferOffset);
|
||||
triangle.v2.y = ::fromLittleEndian<Real32>(buffer + 7*sizeof(Real32) + bufferOffset);
|
||||
triangle.v2.z = ::fromLittleEndian<Real32>(buffer + 8*sizeof(Real32) + bufferOffset);
|
||||
|
||||
// Read vertex3
|
||||
triangle.v3.x = ::fromLittleEndian<Real32>(buffer + 9*sizeof(Real32) + bufferOffset);
|
||||
triangle.v3.y = ::fromLittleEndian<Real32>(buffer + 10*sizeof(Real32) + bufferOffset);
|
||||
triangle.v3.z = ::fromLittleEndian<Real32>(buffer + 11*sizeof(Real32) + bufferOffset);
|
||||
|
||||
// Attribute byte count
|
||||
const UInt16 attributeByteCount =
|
||||
::fromLittleEndian<UInt16>(buffer + 12*sizeof(Real32) + bufferOffset);
|
||||
|
||||
// Add triangle
|
||||
builder->processNextTriangle(triangle, attributeByteCount);
|
||||
|
||||
bufferOffset += stlTriangleDataSize;
|
||||
} // end for
|
||||
|
||||
if (progress != 0) {
|
||||
if (progress->isTaskStopRequested()) {
|
||||
streamError = true;
|
||||
progress->taskStoppedEvent();
|
||||
}
|
||||
else {
|
||||
progress->setValue(amountReadSize / stlTriangleDataSize);
|
||||
}
|
||||
}
|
||||
|
||||
amountReadSize += iReadSize;
|
||||
}
|
||||
else {
|
||||
streamError = true;
|
||||
}
|
||||
} // end while
|
||||
|
||||
if (!streamError)
|
||||
builder->endTriangles();
|
||||
|
||||
return !streamError;
|
||||
}
|
||||
|
||||
bool Io::write(const stl::AbstractGeometry& geom, const AbstractGeometryExtraData* extraData)
|
||||
{
|
||||
if (this->stream() == 0)
|
||||
return false;
|
||||
|
||||
AbstractStream* ostream = this->stream();
|
||||
AbstractTaskProgress* progress = this->taskProgress();
|
||||
|
||||
UInt8 buffer[128];
|
||||
|
||||
// Write header
|
||||
Header headerData;
|
||||
if (extraData != 0)
|
||||
extraData->getHeader(headerData);
|
||||
else
|
||||
std::fill(headerData, headerData + HeaderSize, 0);
|
||||
|
||||
if (ostream->write(reinterpret_cast<char*>(&headerData), HeaderSize) != HeaderSize)
|
||||
return false;
|
||||
|
||||
// Write facet count
|
||||
const UInt32 facetCount = geom.triangleCount();
|
||||
::toLittleEndian<UInt32>(facetCount, buffer);
|
||||
if (ostream->write(reinterpret_cast<char*>(&buffer), sizeof(UInt32)) != sizeof(UInt32))
|
||||
return false;
|
||||
|
||||
if (progress != 0) {
|
||||
progress->reset();
|
||||
progress->setRange(0., facetCount);
|
||||
}
|
||||
|
||||
// Write triangles
|
||||
stl::Triangle triangle;
|
||||
for (UInt32 facet = 0; facet < facetCount; ++facet) {
|
||||
geom.getTriangle(facet, &triangle);
|
||||
|
||||
// Write normal
|
||||
::toLittleEndian<Real32>(triangle.normal.x, buffer);
|
||||
::toLittleEndian<Real32>(triangle.normal.y, buffer + 1*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.normal.z, buffer + 2*sizeof(Real32));
|
||||
|
||||
// Write vertex1
|
||||
::toLittleEndian<Real32>(triangle.v1.x, buffer + 3*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v1.y, buffer + 4*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v1.z, buffer + 5*sizeof(Real32));
|
||||
|
||||
// Write vertex2
|
||||
::toLittleEndian<Real32>(triangle.v2.x, buffer + 6*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v2.y, buffer + 7*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v2.z, buffer + 8*sizeof(Real32));
|
||||
|
||||
// Write vertex3
|
||||
::toLittleEndian<Real32>(triangle.v3.x, buffer + 9*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v3.y, buffer + 10*sizeof(Real32));
|
||||
::toLittleEndian<Real32>(triangle.v3.z, buffer + 11*sizeof(Real32));
|
||||
|
||||
// Attribute byte count
|
||||
const UInt16 attrByteCount = extraData != 0 ? extraData->attributeByteCount(facet) : 0;
|
||||
::toLittleEndian<UInt16>(attrByteCount, buffer + 12*sizeof(Real32));
|
||||
|
||||
// Write to stream
|
||||
if (ostream->write(reinterpret_cast<const char*>(buffer), stlTriangleDataSize)
|
||||
!= stlTriangleDataSize)
|
||||
return false;
|
||||
|
||||
if (progress != 0) {
|
||||
if (progress->isTaskStopRequested()) {
|
||||
progress->taskStoppedEvent();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
progress->setValue(facet + 1);
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace stlb
|
||||
} // namespace foug
|
||||
|
||||
*/
|
59
src/c/libstl/stlb.h
Normal file
59
src/c/libstl/stlb.h
Normal file
@ -0,0 +1,59 @@
|
||||
#ifndef FOUG_C_LIBSTL_STLB_H
|
||||
#define FOUG_C_LIBSTL_STLB_H
|
||||
|
||||
#include "triangle.h"
|
||||
#include "../foug_global.h"
|
||||
#include "../stream.h"
|
||||
#include "../task_control.h"
|
||||
|
||||
enum { foug_stlb_header_size = 80 };
|
||||
typedef foug_uint8 foug_stlb_header_t[foug_stlb_header_size];
|
||||
|
||||
/* foug_stlb_geom : opaque structure */
|
||||
typedef struct _internal_foug_stlb_geom foug_stlb_geom_t;
|
||||
typedef void (*foug_stlb_geom_input_process_header_func_t)(foug_stlb_geom_t,
|
||||
const foug_stlb_header_t);
|
||||
typedef void (*foug_stlb_geom_input_begin_triangles_func_t)(foug_stlb_geom_t, foug_uint32);
|
||||
typedef void (*foug_stlb_geom_input_process_next_triangle_func_t)(foug_stlb_geom_t,
|
||||
const foug_stl_triangle_t*,
|
||||
foug_uint16);
|
||||
typedef void (*foug_stlb_geom_input_end_triangles_func_t)(foug_stlb_geom_t);
|
||||
|
||||
typedef struct foug_stlb_geom_input_manip
|
||||
{
|
||||
foug_stlb_geom_input_process_header_func_t process_header_func;
|
||||
foug_stlb_geom_input_begin_triangles_func_t begin_triangles_func;
|
||||
foug_stlb_geom_input_process_next_triangle_func_t process_next_triangle_func;
|
||||
foug_stlb_geom_input_end_triangles_func_t end_triangles_func;
|
||||
} foug_stlb_geom_input_manip_t;
|
||||
|
||||
/*
|
||||
typedef struct foug_stlb_read_args
|
||||
{
|
||||
void* stream;
|
||||
foug_stream_manip_t stream_manip;
|
||||
|
||||
foug_stlb_geom_t geom;
|
||||
foug_stlb_geom_input_manip_t geom_manip;
|
||||
} foug_stlb_read_args_t;
|
||||
|
||||
int foug_stlb_read(foug_stlb_geom_t geom, foug_stlb_read_args_t args);
|
||||
*/
|
||||
|
||||
/*class FOUG_STL_EXPORT AbstractGeometryExtraData
|
||||
{
|
||||
public:
|
||||
virtual void getHeader(Header& data) const = 0;
|
||||
virtual UInt16 attributeByteCount(UInt32 triangleIndex) const = 0;
|
||||
};
|
||||
|
||||
class FOUG_STL_EXPORT Io : public IoBase
|
||||
{
|
||||
public:
|
||||
Io(AbstractStream* stream = 0);
|
||||
|
||||
bool read(AbstractGeometryBuilder* builder);
|
||||
bool write(const stl::AbstractGeometry& geom, const AbstractGeometryExtraData* extraData = 0);
|
||||
};*/
|
||||
|
||||
#endif /* FOUG_C_LIBSTL_STLB_H */
|
21
src/c/libstl/triangle.h
Normal file
21
src/c/libstl/triangle.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef FOUG_C_LIBSTL_TRIANGLE_H
|
||||
#define FOUG_C_LIBSTL_TRIANGLE_H
|
||||
|
||||
#include "../foug_global.h"
|
||||
|
||||
typedef struct foug_stl_coords
|
||||
{
|
||||
foug_real32 x;
|
||||
foug_real32 y;
|
||||
foug_real32 z;
|
||||
} foug_stl_coords_t;
|
||||
|
||||
typedef struct foug_stl_triangle
|
||||
{
|
||||
foug_stl_coords_t normal;
|
||||
foug_stl_coords_t v1;
|
||||
foug_stl_coords_t v2;
|
||||
foug_stl_coords_t v3;
|
||||
} foug_stl_triangle_t;
|
||||
|
||||
#endif /* FOUG_C_LIBSTL_TRIANGLE_H */
|
9
src/c/memory.h
Normal file
9
src/c/memory.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef FOUG_C_MEMORY_H
|
||||
#define FOUG_C_MEMORY_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef void* (*foug_malloc_func_t)(size_t);
|
||||
typedef void (*foug_free_func_t)(void*);
|
||||
|
||||
#endif /* FOUG_C_MEMORY_H */
|
95
src/c/stream.c
Normal file
95
src/c/stream.c
Normal file
@ -0,0 +1,95 @@
|
||||
#include "stream.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct _internal_foug_stream
|
||||
{
|
||||
void* cookie;
|
||||
foug_stream_manip_t manip;
|
||||
};
|
||||
|
||||
foug_stream_t* foug_stream_create(foug_malloc_func_t func, void* data, foug_stream_manip_t manip)
|
||||
{
|
||||
if (func == NULL)
|
||||
return NULL;
|
||||
foug_stream_t* stream = (*func)(sizeof(struct _internal_foug_stream));
|
||||
if (stream != NULL) {
|
||||
stream->cookie = data;
|
||||
stream->manip = manip;
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
foug_stream_manip_t foug_stream_manip_null()
|
||||
{
|
||||
foug_stream_manip_t manip;
|
||||
memset(&manip, 0, sizeof(foug_stream_manip_t));
|
||||
return manip;
|
||||
}
|
||||
|
||||
static foug_bool foug_stream_stdio_at_end(foug_stream_t* stream)
|
||||
{
|
||||
return feof((FILE*) stream->cookie);
|
||||
}
|
||||
|
||||
static foug_int32 foug_stream_stdio_seek(foug_stream_t* stream, foug_int64 pos)
|
||||
{
|
||||
return fseek((FILE*) stream->cookie, pos, SEEK_SET);
|
||||
}
|
||||
|
||||
static foug_uint64 foug_stream_stdio_read(foug_stream_t* stream, char* s, foug_uint64 max_size)
|
||||
{
|
||||
return fread(s, sizeof(char), max_size, (FILE*) stream->cookie);
|
||||
}
|
||||
|
||||
static foug_uint64 foug_stream_stdio_write(foug_stream_t* stream,
|
||||
const char* s,
|
||||
foug_uint64 max_size)
|
||||
{
|
||||
return fwrite(s, sizeof(char), max_size, (FILE*) stream->cookie);
|
||||
}
|
||||
|
||||
foug_stream_manip_t foug_stream_manip_stdio()
|
||||
{
|
||||
foug_stream_manip_t manip;
|
||||
manip.at_end_func = &foug_stream_stdio_at_end;
|
||||
manip.seek_func = &foug_stream_stdio_seek;
|
||||
manip.read_func = &foug_stream_stdio_read;
|
||||
manip.write_func = &foug_stream_stdio_write;
|
||||
return manip;
|
||||
}
|
||||
|
||||
foug_bool foug_stream_at_end(foug_stream_t* stream)
|
||||
{
|
||||
if (stream != NULL && stream->manip.at_end_func != NULL)
|
||||
return (*(stream->manip.at_end_func))(stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
foug_int32 foug_stream_seek(foug_stream_t* stream, foug_int64 max_size)
|
||||
{
|
||||
if (stream != NULL && stream->manip.seek_func != NULL)
|
||||
return (*(stream->manip.seek_func))(stream, max_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
foug_uint64 foug_stream_read(foug_stream_t* stream, char* s, foug_uint64 max_size)
|
||||
{
|
||||
if (stream != NULL && stream->manip.read_func != NULL)
|
||||
return (*(stream->manip.read_func))(stream, s, max_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
foug_uint64 foug_stream_write(foug_stream_t* stream, const char* s, foug_uint64 max_size)
|
||||
{
|
||||
if (stream != NULL && stream->manip.write_func != NULL)
|
||||
return (*(stream->manip.write_func))(stream, s, max_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* foug_stream_get_cookie(const foug_stream_t* stream)
|
||||
{
|
||||
return stream != NULL ? stream->cookie : NULL;
|
||||
}
|
35
src/c/stream.h
Normal file
35
src/c/stream.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef FOUG_C_STREAM_H
|
||||
#define FOUG_C_STREAM_H
|
||||
|
||||
#include "foug_global.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* foug_stream : opaque structure */
|
||||
typedef struct _internal_foug_stream foug_stream_t;
|
||||
|
||||
/* foug_stream_manip */
|
||||
typedef foug_bool (*foug_stream_at_end_func_t)(foug_stream_t*);
|
||||
typedef foug_int32 (*foug_stream_seek_func_t)(foug_stream_t*, foug_int64);
|
||||
typedef foug_uint64 (*foug_stream_read_func_t)(foug_stream_t*, char*, foug_uint64);
|
||||
typedef foug_uint64 (*foug_stream_write_func_t)(foug_stream_t*, const char*, foug_uint64);
|
||||
typedef struct foug_stream_manip
|
||||
{
|
||||
foug_stream_at_end_func_t at_end_func;
|
||||
foug_stream_seek_func_t seek_func;
|
||||
foug_stream_read_func_t read_func;
|
||||
foug_stream_write_func_t write_func;
|
||||
} foug_stream_manip_t;
|
||||
|
||||
foug_stream_manip_t foug_stream_manip_null();
|
||||
foug_stream_manip_t foug_stream_manip_stdio();
|
||||
|
||||
/* Services */
|
||||
foug_stream_t* foug_stream_create(foug_malloc_func_t func, void* data, foug_stream_manip_t manip);
|
||||
|
||||
foug_bool foug_stream_at_end(foug_stream_t* stream);
|
||||
foug_int32 foug_stream_seek(foug_stream_t* stream, foug_int64 max_size);
|
||||
foug_uint64 foug_stream_read(foug_stream_t* stream, char* s, foug_uint64 max_size);
|
||||
foug_uint64 foug_stream_write(foug_stream_t* stream, const char* s, foug_uint64 max_size);
|
||||
void* foug_stream_get_cookie(const foug_stream_t* stream);
|
||||
|
||||
#endif /* FOUG_C_STREAM_H */
|
161
src/c/task_control.c
Normal file
161
src/c/task_control.c
Normal file
@ -0,0 +1,161 @@
|
||||
#include "task_control.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
/* foug_task_control */
|
||||
|
||||
struct _internal_foug_task_control
|
||||
{
|
||||
foug_real32 range_min;
|
||||
foug_real32 range_max;
|
||||
foug_real32 range_length;
|
||||
foug_int32 step_id;
|
||||
foug_real32 progress_value;
|
||||
foug_real32 progress_threshold;
|
||||
foug_bool is_stop_requested;
|
||||
void* cookie;
|
||||
foug_task_control_manip_t manip;
|
||||
};
|
||||
|
||||
foug_task_control_t* foug_task_control_create(foug_malloc_func_t func,
|
||||
void* data, foug_task_control_manip_t manip)
|
||||
{
|
||||
if (func == NULL)
|
||||
return NULL;
|
||||
|
||||
foug_task_control_t* ctrl = (*func)(sizeof(struct _internal_foug_task_control));
|
||||
if (ctrl != 0) {
|
||||
ctrl->range_min = -1.;
|
||||
ctrl->range_max = -2.;
|
||||
ctrl->range_length = -0.;
|
||||
ctrl->step_id = -1;
|
||||
ctrl->progress_value = -1.;
|
||||
ctrl->progress_threshold = 0.01; /* Notifies each percent only */
|
||||
ctrl->is_stop_requested = 0;
|
||||
ctrl->cookie = data;
|
||||
ctrl->manip = manip;
|
||||
}
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
/* foug_task_control_manip */
|
||||
|
||||
void foug_task_control_manip_init(foug_task_control_manip_t* manip)
|
||||
{
|
||||
if (manip != NULL)
|
||||
memset(manip, 0, sizeof(foug_task_control_manip_t));
|
||||
}
|
||||
|
||||
/* Range */
|
||||
|
||||
foug_real32 foug_task_control_get_range_min(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->range_min : -1.;
|
||||
}
|
||||
|
||||
foug_real32 foug_task_control_get_range_max(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->range_max : -2.;
|
||||
}
|
||||
|
||||
void foug_task_control_set_range(foug_task_control_t* ctrl, foug_real32 min, foug_real32 max)
|
||||
{
|
||||
if (ctrl != NULL) {
|
||||
ctrl->range_min = min;
|
||||
ctrl->range_max = max;
|
||||
ctrl->range_length = max - min;
|
||||
}
|
||||
}
|
||||
|
||||
/* Step id */
|
||||
|
||||
foug_int32 foug_task_control_get_step_id(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->step_id : -1;
|
||||
}
|
||||
|
||||
void foug_task_control_set_step_id(foug_task_control_t* ctrl, foug_int32 step_id)
|
||||
{
|
||||
if (ctrl != NULL)
|
||||
ctrl->step_id = step_id;
|
||||
}
|
||||
|
||||
/* Progress */
|
||||
foug_real32 foug_task_control_get_progress_as_pc(const foug_task_control_t* ctrl)
|
||||
{
|
||||
if (ctrl == NULL)
|
||||
return 0.;
|
||||
const foug_real32 result = (ctrl->progress_value - ctrl->range_min) / ctrl->range_length;
|
||||
return fabs(result);
|
||||
}
|
||||
|
||||
foug_real32 foug_task_control_get_progress(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->progress_value : 0.;
|
||||
}
|
||||
|
||||
void foug_task_control_set_progress(foug_task_control_t* ctrl, foug_real32 v)
|
||||
{
|
||||
if (ctrl == NULL)
|
||||
return;
|
||||
|
||||
if (fabs(v - ctrl->progress_value) > fabs(ctrl->progress_threshold * ctrl->range_length)) {
|
||||
ctrl->progress_value = v;
|
||||
if (ctrl->manip.handle_progress_update_func != NULL)
|
||||
(*(ctrl->manip.handle_progress_update_func))(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
foug_real32 foug_task_control_get_progress_update_threshold(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->progress_threshold : 0.01;
|
||||
}
|
||||
|
||||
void foug_task_control_set_progress_update_threshold(foug_task_control_t* ctrl, foug_real32 v)
|
||||
{
|
||||
if (ctrl != NULL)
|
||||
ctrl->progress_threshold = v;
|
||||
}
|
||||
|
||||
/* Reset */
|
||||
|
||||
void foug_task_control_reset(foug_task_control_t* ctrl)
|
||||
{
|
||||
if (ctrl != NULL) {
|
||||
ctrl->step_id = -1;
|
||||
ctrl->progress_value = -1.;
|
||||
ctrl->range_min = -1.;
|
||||
ctrl->range_max = -2.;
|
||||
ctrl->is_stop_requested = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Task stop */
|
||||
|
||||
void foug_task_control_async_stop(foug_task_control_t* ctrl)
|
||||
{
|
||||
if (ctrl != NULL)
|
||||
ctrl->is_stop_requested = 1;
|
||||
}
|
||||
|
||||
void foug_task_control_handle_stop(foug_task_control_t* ctrl)
|
||||
{
|
||||
if (ctrl != NULL) {
|
||||
ctrl->is_stop_requested = 0;
|
||||
if (ctrl->manip.handle_stop_func != NULL)
|
||||
(*(ctrl->manip.handle_stop_func))(ctrl);
|
||||
}
|
||||
}
|
||||
|
||||
foug_bool foug_task_control_is_stop_requested(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->is_stop_requested : 0;
|
||||
}
|
||||
|
||||
/* Cookie */
|
||||
|
||||
void* foug_task_control_get_cookie(const foug_task_control_t* ctrl)
|
||||
{
|
||||
return ctrl != NULL ? ctrl->cookie : NULL;
|
||||
}
|
52
src/c/task_control.h
Normal file
52
src/c/task_control.h
Normal file
@ -0,0 +1,52 @@
|
||||
#ifndef FOUG_C_TASK_CONTROL_H
|
||||
#define FOUG_C_TASK_CONTROL_H
|
||||
|
||||
#include "foug_global.h"
|
||||
#include "memory.h"
|
||||
|
||||
/* foug_task_control : opaque structure */
|
||||
typedef struct _internal_foug_task_control foug_task_control_t;
|
||||
|
||||
/* foug_task_control_manip */
|
||||
typedef void (*foug_task_control_handle_stop_func)(foug_task_control_t*);
|
||||
typedef void (*foug_task_control_handle_progress_update_func)(foug_task_control_t*);
|
||||
typedef struct foug_task_control_manip
|
||||
{
|
||||
foug_task_control_handle_stop_func handle_stop_func;
|
||||
foug_task_control_handle_progress_update_func handle_progress_update_func;
|
||||
} foug_task_control_manip_t;
|
||||
|
||||
void foug_task_control_manip_init(foug_task_control_manip_t* manip);
|
||||
|
||||
foug_task_control_t* foug_task_control_create(foug_malloc_func_t func,
|
||||
void* data, foug_task_control_manip_t manip);
|
||||
|
||||
/* Range */
|
||||
foug_real32 foug_task_control_get_range_min(const foug_task_control_t* ctrl);
|
||||
foug_real32 foug_task_control_get_range_max(const foug_task_control_t* ctrl);
|
||||
void foug_task_control_set_range(foug_task_control_t* ctrl, foug_real32 min, foug_real32 max);
|
||||
|
||||
/* Step id */
|
||||
foug_int32 foug_task_control_get_step_id(const foug_task_control_t* ctrl);
|
||||
void foug_task_control_set_step_id(foug_task_control_t* ctrl, foug_int32 step_id);
|
||||
|
||||
/* Progress */
|
||||
foug_real32 foug_task_control_get_progress_as_pc(const foug_task_control_t* ctrl);
|
||||
foug_real32 foug_task_control_get_progress(const foug_task_control_t* ctrl);
|
||||
void foug_task_control_set_progress(foug_task_control_t* ctrl, foug_real32 v);
|
||||
|
||||
foug_real32 foug_task_control_get_progress_update_threshold(const foug_task_control_t* ctrl);
|
||||
void foug_task_control_set_progress_update_threshold(foug_task_control_t* ctrl, foug_real32 v);
|
||||
|
||||
/* Reset */
|
||||
void foug_task_control_reset(foug_task_control_t* ctrl);
|
||||
|
||||
/* Task stop */
|
||||
void foug_task_control_async_stop(foug_task_control_t* ctrl);
|
||||
void foug_task_control_handle_stop(foug_task_control_t* ctrl);
|
||||
foug_bool foug_task_control_is_stop_requested(const foug_task_control_t* ctrl);
|
||||
|
||||
/* Cookie */
|
||||
void* foug_task_control_get_cookie(const foug_task_control_t* ctrl);
|
||||
|
||||
#endif /* FOUG_C_TASK_CONTROL_H */
|
Loading…
Reference in New Issue
Block a user