2174 lines
75 KiB
C++
2174 lines
75 KiB
C++
/*
|
|
* gta.hpp
|
|
*
|
|
* This file is part of libgta, a library that implements the Generic Tagged
|
|
* Array (GTA) file format.
|
|
*
|
|
* Copyright (C) 2010, 2011, 2012
|
|
* Martin Lambers <marlam@marlam.de>
|
|
*
|
|
* Libgta is free software: you can redistribute it and/or modify it under the
|
|
* terms of the GNU Lesser General Public License as published by the Free
|
|
* Software Foundation, either version 2.1 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* Libgta is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with Libgta. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
|
|
/**
|
|
* \file gta.hpp
|
|
* \brief The libgta C++ interface.
|
|
*
|
|
* This document describes the C++ language interface of libgta.
|
|
*/
|
|
|
|
|
|
#ifndef GTA_HPP
|
|
#define GTA_HPP
|
|
|
|
#include <exception>
|
|
#include <istream>
|
|
#include <ostream>
|
|
#include <vector>
|
|
#include <limits>
|
|
#include <cerrno>
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
#include <gta/gta.h>
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning (push)
|
|
# pragma warning (disable: 4996) // strerror and _snprintf
|
|
# pragma warning (disable: 4244) // conversion from uintmax_t to unsigned int
|
|
#endif
|
|
|
|
|
|
/**
|
|
* \brief The gta namespace.
|
|
*/
|
|
namespace gta
|
|
{
|
|
/**
|
|
* \brief GTA result
|
|
*
|
|
* This is equivalent to \a gta_result_t from the C interface.
|
|
*/
|
|
enum result
|
|
{
|
|
ok = GTA_OK,
|
|
/**<
|
|
* \brief Success / no error
|
|
*/
|
|
overflow = GTA_OVERFLOW,
|
|
/**<
|
|
* \brief Size overflow
|
|
*/
|
|
unsupported_data = GTA_UNSUPPORTED_DATA,
|
|
/**<
|
|
* \brief Unsupported data
|
|
*
|
|
* The input seems to require features that are not available in this version
|
|
* of the library.
|
|
*/
|
|
unexpected_eof = GTA_UNEXPECTED_EOF,
|
|
/**<
|
|
* \brief Unexpected end of file
|
|
*
|
|
* The GTA library intended to read more data, but the input did not provide it.
|
|
*/
|
|
invalid_data = GTA_INVALID_DATA,
|
|
/**<
|
|
* \brief Invalid data
|
|
*
|
|
* Some data was invalid. For example, an input file is not in GTA format,
|
|
* or decompression of the data failed.
|
|
*/
|
|
system_error = GTA_SYSTEM_ERROR
|
|
/**<
|
|
* \brief System error
|
|
*
|
|
* A system error occured. More information is available in errno.
|
|
* Examples: memory allocation failure (errno == ENOMEM), input/output
|
|
* errors (errno == EIO), no space left on device (errno == ENOSPC).
|
|
*/
|
|
};
|
|
|
|
/**
|
|
* \brief GTA data types
|
|
*
|
|
* This is equivalent to \a gta_type_t from the C interface.
|
|
*
|
|
* All integer types contain the exact number of bits indicated by their name
|
|
* and use the common two's complement representation.\n
|
|
* All floating point types contain the exact number of bits indicated by their
|
|
* name and conform to the binary representation defined by IEEE 754.\n
|
|
* The complex types (gta::cfloat*) consist of two floating point values with the
|
|
* number of bits indicated by the name, as defined above. The first value is
|
|
* the real part, the second value is the imaginary part. For example,
|
|
* \a gta::cfloat32 consists of two \a gta::float32 values.\n
|
|
* The name \a gta::blob can be used for data types that are not defined in this
|
|
* list. In this case, the size of the data type must be given, and the data type
|
|
* must be independent of endianness.
|
|
*/
|
|
enum type
|
|
{
|
|
int8 = GTA_INT8, /**< \brief int8_t */
|
|
uint8 = GTA_UINT8, /**< \brief uint8_t */
|
|
int16 = GTA_INT16, /**< \brief int16_t */
|
|
uint16 = GTA_UINT16, /**< \brief uint16_t */
|
|
int32 = GTA_INT32, /**< \brief int32_t */
|
|
uint32 = GTA_UINT32, /**< \brief uint32_t */
|
|
int64 = GTA_INT64, /**< \brief int64_t */
|
|
uint64 = GTA_UINT64, /**< \brief uint64_t */
|
|
int128 = GTA_INT128, /**< \brief int128_t (unavailable on many platforms) */
|
|
uint128 = GTA_UINT128, /**< \brief uint128_t (unavailable on many platforms) */
|
|
float32 = GTA_FLOAT32, /**< \brief IEEE 754 single precision floating point (on many platforms: float) */
|
|
float64 = GTA_FLOAT64, /**< \brief IEEE 754 double precision floating point (on many platforms: double) */
|
|
float128 = GTA_FLOAT128, /**< \brief IEEE 754 quadrupel precision floating point (unavailable on many platforms, even if long double exists) */
|
|
cfloat32 = GTA_CFLOAT32, /**< \brief complex (re,im) based on two \a gta::float32 */
|
|
cfloat64 = GTA_CFLOAT64, /**< \brief complex (re,im) based on two \a gta::float64 */
|
|
cfloat128 = GTA_CFLOAT128, /**< \brief complex (re,im) based on two \a gta::float128 */
|
|
blob = GTA_BLOB /**< \brief Data blob; must be endianness-independent; user must specify the size */
|
|
};
|
|
|
|
/**
|
|
* \brief GTA compression methods
|
|
*
|
|
* This is equivalent to \a gta_compression_t from the C interface.
|
|
*
|
|
* Compression algorithms used to compress the array.\n
|
|
* Only uncompressed files are suitable for out-of-core data access; compressed
|
|
* files must be decompressed first.\n
|
|
* \a gta::zlib compression is fast and achieves a moderate compression ratio.
|
|
* \a gta::bzip2 compression is moderately fast and achieves a good compression ratio.
|
|
* \a gta::xz compression is slow for compression, moderately fast for decompression,
|
|
* and achieves good or very good compression rates.
|
|
*/
|
|
enum compression
|
|
{
|
|
none = GTA_NONE, /**< \brief No compression */
|
|
zlib = GTA_ZLIB, /**< \brief ZLIB compression (fast, moderate compression rate) */
|
|
zlib1 = GTA_ZLIB1, /**< \brief ZLIB compression with level 1 */
|
|
zlib2 = GTA_ZLIB2, /**< \brief ZLIB compression with level 2 */
|
|
zlib3 = GTA_ZLIB3, /**< \brief ZLIB compression with level 3 */
|
|
zlib4 = GTA_ZLIB4, /**< \brief ZLIB compression with level 4 */
|
|
zlib5 = GTA_ZLIB5, /**< \brief ZLIB compression with level 5 */
|
|
zlib6 = GTA_ZLIB6, /**< \brief ZLIB compression with level 6 */
|
|
zlib7 = GTA_ZLIB7, /**< \brief ZLIB compression with level 7 */
|
|
zlib8 = GTA_ZLIB8, /**< \brief ZLIB compression with level 8 */
|
|
zlib9 = GTA_ZLIB9, /**< \brief ZLIB compression with level 9 */
|
|
bzip2 = GTA_BZIP2, /**< \brief BZIP2 compression (moderate speed, good compression rates) */
|
|
xz = GTA_XZ /**< \brief XZ compression (low/moderate speed, good/very good compression rates) */
|
|
};
|
|
|
|
/**
|
|
* \brief The exception class.
|
|
*
|
|
* The GTA C++ interface reports errors by throwing exceptions. You can use
|
|
* them just like std::exceptions, but you can also query the original
|
|
* \a gta::result that caused the exception.
|
|
*/
|
|
class exception : public std::exception
|
|
{
|
|
private:
|
|
|
|
static const int _whatsize = 96;
|
|
gta::result _r;
|
|
int _sys_errno;
|
|
char _what[_whatsize];
|
|
|
|
public:
|
|
|
|
/**
|
|
* \brief Constructor.
|
|
* \param s The action that failed.
|
|
* \param r The GTA result.
|
|
*/
|
|
exception(const char *s, gta::result r)
|
|
: _r(r), _sys_errno(r == system_error ? errno : 0)
|
|
{
|
|
const char *w = "";
|
|
switch (r)
|
|
{
|
|
case ok:
|
|
w = "success";
|
|
break;
|
|
case overflow:
|
|
w = "value too large for data type";
|
|
break;
|
|
case unsupported_data:
|
|
w = "unsupported data";
|
|
break;
|
|
case unexpected_eof:
|
|
w = "unexpected end of input";
|
|
break;
|
|
case invalid_data:
|
|
w = "invalid data";
|
|
break;
|
|
case system_error:
|
|
w = strerror(_sys_errno);
|
|
break;
|
|
}
|
|
#if defined _MSC_VER
|
|
_snprintf(_what, _whatsize, "%s: %s", s, w);
|
|
#else
|
|
snprintf(_what, _whatsize, "%s: %s", s, w);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* \brief Get the original GTA result.
|
|
* \return The original GTA result.
|
|
*/
|
|
gta::result result() const
|
|
{
|
|
return _r;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the original errno.
|
|
* \return The original errno.
|
|
*
|
|
* The original errno value is relevant if the original GTA result was
|
|
* \a gta::system_error.
|
|
*/
|
|
int sys_errno() const
|
|
{
|
|
return _sys_errno;
|
|
}
|
|
|
|
/**
|
|
* \brief Get a description.
|
|
* \return A description of the exception.
|
|
*/
|
|
virtual const char* what() const throw ()
|
|
{
|
|
return _what;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* \brief Tag Lists.
|
|
*
|
|
* GTA stores meta information in tags.
|
|
* Tag names are non-empty UTF-8 strings that must not contain '='.\n
|
|
* Tag values are UTF-8 strings.\n
|
|
* If you do not want to deal with conversions between the local character set and UTF-8,
|
|
* you must restrict names and values to ASCII.
|
|
*/
|
|
class taglist
|
|
{
|
|
private:
|
|
|
|
gta_taglist_t *_taglist;
|
|
|
|
/** \cond INTERNAL */
|
|
void set(gta_taglist_t *taglist)
|
|
{
|
|
_taglist = taglist;
|
|
}
|
|
|
|
taglist()
|
|
{
|
|
}
|
|
/** \endcond */
|
|
|
|
public:
|
|
|
|
/**
|
|
* \brief Get the number of tags.
|
|
* \return The number of tags.
|
|
*/
|
|
uintmax_t tags() const
|
|
{
|
|
return gta_get_tags(_taglist);
|
|
}
|
|
|
|
/**
|
|
* \brief Get a tag name.
|
|
* \param i The tag index.
|
|
* \return The name of the tag.
|
|
*/
|
|
const char *name(uintmax_t i) const
|
|
{
|
|
return gta_get_tag_name(_taglist, i);
|
|
}
|
|
|
|
/**
|
|
* \brief Get a tag value.
|
|
* \param i The tag index.
|
|
* \return The value of the tag.
|
|
*/
|
|
const char *value(uintmax_t i) const
|
|
{
|
|
return gta_get_tag_value(_taglist, i);
|
|
}
|
|
|
|
/**
|
|
* \brief Get a tag value by its name.
|
|
* \param name The tag name.
|
|
* \return The tag value, or NULL if the tag name is not found.
|
|
*/
|
|
const char *get(const char *name) const
|
|
{
|
|
return gta_get_tag(_taglist, name);
|
|
}
|
|
|
|
/**
|
|
* \brief Set a tag.
|
|
* \param name The tag name.
|
|
* \param value The tag value.
|
|
*
|
|
* Sets the given tag, possibly overwriting an existing tag with the same name.
|
|
* The name and value must be valid UTF-8 strings without control characters.
|
|
* Additionally, the name must not contain the equal sign and must not be empty.
|
|
*/
|
|
void set(const char *name, const char *value)
|
|
{
|
|
gta_result_t r = gta_set_tag(_taglist, name, value);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA tag", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Unset a tag.
|
|
* \param name The tag name.
|
|
*
|
|
* Removes the tag with the given name, if it exists.
|
|
*/
|
|
void unset(const char *name)
|
|
{
|
|
gta_result_t r = gta_unset_tag(_taglist, name);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot unset GTA tag", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Unset all tags.
|
|
*
|
|
* Removes all tags.
|
|
*/
|
|
void unset_all()
|
|
{
|
|
gta_unset_all_tags(_taglist);
|
|
}
|
|
|
|
/**
|
|
* \brief Assignment operator.
|
|
* \param tl The tag list to copy.
|
|
*/
|
|
const taglist &operator=(const taglist &tl)
|
|
{
|
|
gta_result_t r = gta_clone_taglist(_taglist, tl._taglist);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot clone GTA taglist", static_cast<gta::result>(r));
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
friend class header;
|
|
};
|
|
|
|
/**
|
|
* \brief Class for custom input/output.
|
|
*
|
|
* You can define your own custom input/output media by implementing this interface.
|
|
* The seek function is only required if you want to use the out-of-core data access
|
|
* funtions \a header::read_block() or \a header::write_block().
|
|
*/
|
|
class custom_io
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* \brief Custom read function.
|
|
* \param buffer The destionation buffer.
|
|
* \param size The number of bytes to read.
|
|
* \param error The error flag.
|
|
*
|
|
* This function must read the given number of bytes into the given buffer.\n
|
|
* Its return value must be the number of bytes successfully read.\n
|
|
* If an error occured, the error flag must be set to true.
|
|
* The function must set errno to indicate the type of error. If the
|
|
* error type is unknown, errno should be set to EIO.
|
|
*/
|
|
virtual size_t read(void *buffer GTA_ATTR_UNUSED, size_t size GTA_ATTR_UNUSED, bool *error)
|
|
{
|
|
errno = ENOSYS;
|
|
*error = true;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Custom write function.
|
|
* \param buffer The source buffer.
|
|
* \param size The number of bytes to write.
|
|
* \param error The error flag.
|
|
*
|
|
* This function must write the given number of bytes from the given buffer.\n
|
|
* Its return value must be the number of bytes successfully written.\n
|
|
* If an error occured, the error flag must be set to true.
|
|
* The function must set errno to indicate the type of error. If the
|
|
* error type is unknown, errno should be set to EIO.
|
|
*/
|
|
virtual size_t write(const void *buffer GTA_ATTR_UNUSED, size_t size GTA_ATTR_UNUSED, bool *error)
|
|
{
|
|
errno = ENOSYS;
|
|
*error = true;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* \brief Tell if this object is seekable.
|
|
* \return Whether this object is seekable.
|
|
*
|
|
* This function must return true if the object is seekable, i.e. if the
|
|
* \a seek function can be used. Otherwise, it must return false.
|
|
*/
|
|
virtual bool seekable()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* \brief Custom seek function.
|
|
* \param offset The position offset.
|
|
* \param whence SEEK_SET or SEEK_CUR.
|
|
* \param error The error flag.
|
|
*
|
|
* This function must change the position indicator as indicated by the parameters \a
|
|
* offset and \a whence, just like fseeko() and lseek() do. The parameter \a whence
|
|
* can be SEEK_SET or SEEK_CUR (SEEK_END is never used).\n
|
|
* If an error occured, the error flag must be set to true.
|
|
* The function must set errno to indicate the type of error. If the
|
|
* error type is unknown, errno should be set to EIO.
|
|
*/
|
|
virtual void seek(intmax_t offset GTA_ATTR_UNUSED, int whence GTA_ATTR_UNUSED, bool *error)
|
|
{
|
|
errno = ENOSYS;
|
|
*error = true;
|
|
}
|
|
};
|
|
|
|
/** \cond INTERNAL */
|
|
class istream_io : public custom_io
|
|
{
|
|
private:
|
|
|
|
std::istream &_is;
|
|
|
|
public:
|
|
|
|
istream_io(std::istream &is)
|
|
: _is(is)
|
|
{
|
|
}
|
|
|
|
virtual size_t read(void *buffer, size_t size, bool *error)
|
|
{
|
|
try
|
|
{
|
|
_is.read(static_cast<char *>(buffer), size);
|
|
}
|
|
catch (...)
|
|
{
|
|
_is.setstate(std::ios::failbit);
|
|
}
|
|
if (!_is.good())
|
|
{
|
|
errno = EIO;
|
|
*error = true;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
virtual bool seekable()
|
|
{
|
|
return (_is.tellg() != static_cast<std::streampos>(-1));
|
|
}
|
|
|
|
virtual void seek(intmax_t offset, int whence, bool *error)
|
|
{
|
|
if (offset > std::numeric_limits<std::streamoff>::max())
|
|
{
|
|
#ifdef EOVERFLOW
|
|
errno = EOVERFLOW;
|
|
#else
|
|
errno = EFBIG;
|
|
#endif
|
|
*error = true;
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
_is.seekg(offset, whence == SEEK_SET ? std::ios_base::beg : std::ios_base::cur);
|
|
}
|
|
catch (...)
|
|
{
|
|
_is.setstate(std::ios::failbit);
|
|
}
|
|
if (!_is.good())
|
|
{
|
|
errno = EIO;
|
|
*error = true;
|
|
}
|
|
}
|
|
};
|
|
/** \endcond */
|
|
|
|
/** \cond INTERNAL */
|
|
class ostream_io : public custom_io
|
|
{
|
|
private:
|
|
|
|
std::ostream &_os;
|
|
|
|
public:
|
|
|
|
ostream_io(std::ostream &os)
|
|
: _os(os)
|
|
{
|
|
}
|
|
|
|
virtual size_t write(const void *buffer, size_t size, bool *error)
|
|
{
|
|
try
|
|
{
|
|
_os.write(static_cast<const char *>(buffer), size);
|
|
}
|
|
catch (...)
|
|
{
|
|
_os.setstate(std::ios::failbit);
|
|
}
|
|
if (!_os.good())
|
|
{
|
|
errno = EIO;
|
|
*error = true;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
virtual bool seekable()
|
|
{
|
|
return (_os.tellp() != static_cast<std::streampos>(-1));
|
|
}
|
|
|
|
virtual void seek(intmax_t offset, int whence, bool *error)
|
|
{
|
|
if (offset > std::numeric_limits<std::streamoff>::max())
|
|
{
|
|
#ifdef EOVERFLOW
|
|
errno = EOVERFLOW;
|
|
#else
|
|
errno = EFBIG;
|
|
#endif
|
|
*error = true;
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
_os.seekp(offset, whence == SEEK_SET ? std::ios_base::beg : std::ios_base::cur);
|
|
}
|
|
catch (...)
|
|
{
|
|
_os.setstate(std::ios::failbit);
|
|
}
|
|
if (!_os.good())
|
|
{
|
|
errno = EIO;
|
|
*error = true;
|
|
}
|
|
}
|
|
};
|
|
/** \endcond */
|
|
|
|
/** \cond INTERNAL */
|
|
inline size_t read_custom_io(intptr_t userdata, void *buffer, size_t size, int *error)
|
|
{
|
|
custom_io *io = reinterpret_cast<custom_io *>(userdata);
|
|
bool tmp_error = false;
|
|
size_t r = io->read(buffer, size, &tmp_error);
|
|
if (tmp_error)
|
|
{
|
|
*error = 1;
|
|
}
|
|
return r;
|
|
}
|
|
/** \endcond */
|
|
|
|
/** \cond INTERNAL */
|
|
inline size_t write_custom_io(intptr_t userdata, const void *buffer, size_t size, int *error)
|
|
{
|
|
custom_io *io = reinterpret_cast<custom_io *>(userdata);
|
|
bool tmp_error = false;
|
|
size_t r = io->write(buffer, size, &tmp_error);
|
|
if (tmp_error)
|
|
{
|
|
*error = 1;
|
|
}
|
|
return r;
|
|
}
|
|
/** \endcond */
|
|
|
|
/** \cond INTERNAL */
|
|
inline void seek_custom_io(intptr_t userdata, intmax_t offset, int whence, int *error)
|
|
{
|
|
custom_io *io = reinterpret_cast<custom_io *>(userdata);
|
|
bool tmp_error = false;
|
|
io->seek(offset, whence, &tmp_error);
|
|
if (tmp_error)
|
|
{
|
|
*error = 1;
|
|
}
|
|
}
|
|
/** \endcond */
|
|
|
|
/**
|
|
* \brief State for element-based input and output.
|
|
*
|
|
* See gta::header::read_elements() and gta::header::write_elements().
|
|
*/
|
|
class io_state
|
|
{
|
|
private:
|
|
|
|
gta_io_state_t *_state;
|
|
|
|
public:
|
|
|
|
io_state()
|
|
{
|
|
gta_result_t r = gta_create_io_state(&_state);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot initialize GTA i/o state", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/** \cond INTERNAL */
|
|
io_state(const io_state &s)
|
|
{
|
|
gta_result_t r = gta_create_io_state(&_state);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot initialize GTA i/o state", static_cast<gta::result>(r));
|
|
}
|
|
r = gta_clone_io_state(_state, s._state);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot clone GTA i/o state", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
/** \endcond */
|
|
|
|
~io_state()
|
|
{
|
|
if (_state)
|
|
{
|
|
gta_destroy_io_state(_state);
|
|
}
|
|
}
|
|
|
|
/** \cond INTERNAL */
|
|
io_state &operator=(const io_state &s)
|
|
{
|
|
gta_result_t r = gta_clone_io_state(_state, s._state);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot clone GTA i/o state", static_cast<gta::result>(r));
|
|
}
|
|
return *this;
|
|
}
|
|
/** \endcond */
|
|
|
|
friend class header;
|
|
};
|
|
|
|
/**
|
|
* \brief The GTA header.
|
|
*
|
|
* Each GTA file is described by its header. It stores information about the
|
|
* array elements and the dimensions, and the various tag lists.
|
|
* Using the header, one can access the data in a GTA file, either by
|
|
* managaing the complete data in memory (if it fits), or by using
|
|
* out-of-core data read/write functions. There are also functions that help
|
|
* the application to implement its own data access scheme, if that is necessary.
|
|
*/
|
|
class header
|
|
{
|
|
private:
|
|
|
|
gta_header_t *_header;
|
|
taglist _global_taglist;
|
|
std::vector<taglist> _dimension_taglists;
|
|
std::vector<taglist> _component_taglists;
|
|
|
|
void reset_global_taglist()
|
|
{
|
|
_global_taglist.set(gta_get_global_taglist(_header));
|
|
}
|
|
|
|
void reset_component_taglists()
|
|
{
|
|
_component_taglists.resize(gta_get_components(_header), taglist());
|
|
for (uintmax_t i = 0; i < _component_taglists.size(); i++)
|
|
{
|
|
_component_taglists[i].set(gta_get_component_taglist(_header, i));
|
|
}
|
|
}
|
|
|
|
void reset_dimension_taglists()
|
|
{
|
|
_dimension_taglists.resize(gta_get_dimensions(_header), taglist());
|
|
for (size_t i = 0; i < _dimension_taglists.size(); i++)
|
|
{
|
|
_dimension_taglists[i].set(gta_get_dimension_taglist(_header, i));
|
|
}
|
|
}
|
|
|
|
void reset_taglists()
|
|
{
|
|
reset_global_taglist();
|
|
reset_component_taglists();
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
public:
|
|
|
|
/**
|
|
* \name Constructor / Destructor & Co.
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Constructor.
|
|
*/
|
|
header()
|
|
{
|
|
gta_result_t r = gta_create_header(&_header);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot initialize GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Copy constructor.
|
|
* \param hdr The header to copy.
|
|
*/
|
|
header(const header &hdr)
|
|
{
|
|
gta_result_t r;
|
|
r = gta_create_header(&_header);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot initialize GTA header", static_cast<gta::result>(r));
|
|
}
|
|
r = gta_clone_header(_header, hdr._header);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot clone GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Destructor.
|
|
*/
|
|
~header()
|
|
{
|
|
if (_header)
|
|
{
|
|
gta_destroy_header(_header);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Assignment operator.
|
|
* \param hdr The header to copy.
|
|
*/
|
|
const header &operator=(const header &hdr)
|
|
{
|
|
gta_result_t r = gta_clone_header(_header, hdr._header);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot clone GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
return *this;
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Read and Write a Header
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Read a header.
|
|
* \param io Custom input object.
|
|
*/
|
|
void read_from(custom_io &io)
|
|
{
|
|
gta_result_t r = gta_read_header(_header, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Read a header.
|
|
* \param is Input stream.
|
|
*/
|
|
void read_from(std::istream &is)
|
|
{
|
|
istream_io io(is);
|
|
gta_result_t r = gta_read_header(_header, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Read a header.
|
|
* \param f Input C stream.
|
|
*/
|
|
void read_from(FILE *f)
|
|
{
|
|
gta_result_t r = gta_read_header_from_stream(_header, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Read a header.
|
|
* \param fd Input file descriptor.
|
|
*/
|
|
void read_from(int fd)
|
|
{
|
|
gta_result_t r = gta_read_header_from_fd(_header, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA header", static_cast<gta::result>(r));
|
|
}
|
|
reset_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Write a header.
|
|
* \param io Custom output object.
|
|
*/
|
|
void write_to(custom_io &io) const
|
|
{
|
|
gta_result_t r = gta_write_header(_header, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA header", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write a header.
|
|
* \param os Output stream.
|
|
*/
|
|
void write_to(std::ostream &os) const
|
|
{
|
|
ostream_io io(os);
|
|
gta_result_t r = gta_write_header(_header, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA header", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write a header.
|
|
* \param f Output C stream.
|
|
*/
|
|
void write_to(FILE *f) const
|
|
{
|
|
gta_result_t r = gta_write_header_to_stream(_header, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA header", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write a header.
|
|
* \param fd Output file descriptor.
|
|
*/
|
|
void write_to(int fd) const
|
|
{
|
|
gta_result_t r = gta_write_header_to_fd(_header, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA header", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Access Header Information
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Get the global tag list.
|
|
* \return The global tag list.
|
|
*/
|
|
const taglist &global_taglist() const
|
|
{
|
|
return _global_taglist;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the global tag list.
|
|
* \return The global tag list.
|
|
*/
|
|
taglist &global_taglist()
|
|
{
|
|
return _global_taglist;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the element size.
|
|
* \return The size of an array element.
|
|
*/
|
|
uintmax_t element_size() const
|
|
{
|
|
return gta_get_element_size(_header);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the number of components.
|
|
* \return The number of components.
|
|
*/
|
|
uintmax_t components() const
|
|
{
|
|
return gta_get_components(_header);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the component type.
|
|
* \param i The component index.
|
|
* \return The type of the component.
|
|
*/
|
|
type component_type(uintmax_t i) const
|
|
{
|
|
return static_cast<type>(gta_get_component_type(_header, i));
|
|
}
|
|
|
|
/**
|
|
* \brief Get the component size.
|
|
* \param i The component index.
|
|
* \return The size of the component.
|
|
*/
|
|
uintmax_t component_size(uintmax_t i) const
|
|
{
|
|
return gta_get_component_size(_header, i);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the component tag list.
|
|
* \param i The component index.
|
|
* \return The tag list of the component.
|
|
*/
|
|
const taglist &component_taglist(uintmax_t i) const
|
|
{
|
|
return _component_taglists[i];
|
|
}
|
|
|
|
/**
|
|
* \brief Get the component tag list.
|
|
* \param i The component index.
|
|
* \return The tag list of the component.
|
|
*/
|
|
taglist &component_taglist(uintmax_t i)
|
|
{
|
|
return _component_taglists[i];
|
|
}
|
|
|
|
/**
|
|
* \brief Get the number of dimensions.
|
|
* \return The number of dimensions.
|
|
*/
|
|
uintmax_t dimensions() const
|
|
{
|
|
return gta_get_dimensions(_header);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the size in a dimension.
|
|
* \param i The dimension index.
|
|
* \return The size in the dimension.
|
|
*/
|
|
uintmax_t dimension_size(uintmax_t i) const
|
|
{
|
|
return gta_get_dimension_size(_header, i);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the dimension tag list.
|
|
* \param i The dimension index.
|
|
* \return The tag list of the dimension.
|
|
*/
|
|
const taglist &dimension_taglist(uintmax_t i) const
|
|
{
|
|
return _dimension_taglists[i];
|
|
}
|
|
|
|
/**
|
|
* \brief Get the dimension tag list.
|
|
* \param i The dimension index.
|
|
* \return The tag list of the dimension.
|
|
*/
|
|
taglist &dimension_taglist(uintmax_t i)
|
|
{
|
|
return _dimension_taglists[i];
|
|
}
|
|
|
|
/**
|
|
* \brief Get the total number of elements in the array.
|
|
* \return The total number of elements in the array.
|
|
*/
|
|
uintmax_t elements() const
|
|
{
|
|
return gta_get_elements(_header);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the total size of the array.
|
|
* \return The size (in bytes) of the complete array.
|
|
*/
|
|
uintmax_t data_size() const
|
|
{
|
|
return gta_get_data_size(_header);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the compression.
|
|
* \return The compression type.
|
|
*
|
|
* Gets the compression type for the header and data.\n
|
|
* See \a gta_compression_t for more information on compression types.\n
|
|
* Compressed data is always stored in chunks, while uncompressed
|
|
* data is never stored in chunks.
|
|
*/
|
|
gta::compression compression() const
|
|
{
|
|
return static_cast<gta::compression>(gta_get_compression(_header));
|
|
}
|
|
|
|
/**
|
|
* \brief Set the compression.
|
|
* \param compression The compression type.
|
|
*
|
|
* Sets the compression type for writing the header and data.\n
|
|
* See \a gta_compression_t for more information on compression types.
|
|
*/
|
|
void set_compression(gta::compression compression)
|
|
{
|
|
gta_set_compression(_header, static_cast<gta_compression_t>(compression));
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Define an Array
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Set the components of an array element.
|
|
* \param n The number of components.
|
|
* \param types The types of the \a n components.
|
|
* \param sizes NULL, or the sizes of the components that have type \a gta::blob.
|
|
*
|
|
* Set the components of the array elements.\n
|
|
* The \a sizes parameter can be NULL if no components have the type \a gta::blob.
|
|
* Otherwise, it must point to a list that contains the sizes of these components (and only
|
|
* these components). For example, if there are five components, but only two have the type
|
|
* \a gta::blob, then the \a sizes list must contain two size values.\n
|
|
* All components will initially have an empty tag list.\n
|
|
*/
|
|
void set_components(uintmax_t n, const type *types, const uintmax_t *sizes = NULL)
|
|
{
|
|
gta_result_t r = gta_set_components(_header, n, reinterpret_cast<const gta_type_t *>(types), sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA components", static_cast<gta::result>(r));
|
|
}
|
|
reset_component_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the components of an array element (variant for elements with a single component).
|
|
* \param type The type of the component.
|
|
* \param size The size of the component, in case the type is \a gta::blob.
|
|
*/
|
|
void set_components(type type, uintmax_t size = 0)
|
|
{
|
|
gta::type types[] = { type };
|
|
uintmax_t sizes[] = { size };
|
|
gta_result_t r = gta_set_components(_header, 1, reinterpret_cast<gta_type_t *>(types), sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA components", static_cast<gta::result>(r));
|
|
}
|
|
reset_component_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the components of an array element (variant for elements with two components).
|
|
* \param type0 The type of the first component.
|
|
* \param type1 The type of the second component.
|
|
* \param size0 The size of the first component, in case its type is \a gta::blob.
|
|
* \param size1 The size of the second component, in case its type is \a gta::blob.
|
|
*/
|
|
void set_components(type type0, type type1,
|
|
uintmax_t size0 = 0, uintmax_t size1 = 0)
|
|
{
|
|
type types[] = { type0, type1 };
|
|
uintmax_t sizes[] = { size0, size1 };
|
|
gta_result_t r = gta_set_components(_header, 2, reinterpret_cast<gta_type_t *>(types), sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA components", static_cast<gta::result>(r));
|
|
}
|
|
reset_component_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the components of an array element (variant for elements with three components).
|
|
* \param type0 The type of the first component.
|
|
* \param type1 The type of the second component.
|
|
* \param type2 The type of the third component.
|
|
* \param size0 The size of the first component, in case its type is \a gta::blob.
|
|
* \param size1 The size of the second component, in case its type is \a gta::blob.
|
|
* \param size2 The size of the third component, in case its type is \a gta::blob.
|
|
*/
|
|
void set_components(type type0, type type1, type type2,
|
|
uintmax_t size0 = 0, uintmax_t size1 = 0, uintmax_t size2 = 0)
|
|
{
|
|
type types[] = { type0, type1, type2 };
|
|
uintmax_t sizes[] = { size0, size1, size2 };
|
|
gta_result_t r = gta_set_components(_header, 3, reinterpret_cast<gta_type_t *>(types), sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA components", static_cast<gta::result>(r));
|
|
}
|
|
reset_component_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the components of an array element (variant for elements with four components).
|
|
* \param type0 The type of the first component.
|
|
* \param type1 The type of the second component.
|
|
* \param type2 The type of the third component.
|
|
* \param type3 The type of the fourth component.
|
|
* \param size0 The size of the first component, in case its type is \a gta::blob.
|
|
* \param size1 The size of the second component, in case its type is \a gta::blob.
|
|
* \param size2 The size of the third component, in case its type is \a gta::blob.
|
|
* \param size3 The size of the fourth component, in case its type is \a gta::blob.
|
|
*/
|
|
void set_components(type type0, type type1, type type2, type type3,
|
|
uintmax_t size0 = 0, uintmax_t size1 = 0, uintmax_t size2 = 0, uintmax_t size3 = 0)
|
|
{
|
|
type types[] = { type0, type1, type2, type3 };
|
|
uintmax_t sizes[] = { size0, size1, size2, size3 };
|
|
gta_result_t r = gta_set_components(_header, 4, reinterpret_cast<gta_type_t *>(types), sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA components", static_cast<gta::result>(r));
|
|
}
|
|
reset_component_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the dimensions.
|
|
* \param n The number of dimensions.
|
|
* \param sizes The array sizes in each of the \n dimensions.
|
|
*
|
|
* Sets the array dimensions.\n
|
|
* All dimensions will initially have an empty tag list.
|
|
*/
|
|
void set_dimensions(uintmax_t n, const uintmax_t *sizes)
|
|
{
|
|
gta_result_t r = gta_set_dimensions(_header, n, sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA dimensions", static_cast<gta::result>(r));
|
|
}
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the dimensions (variant for one-dimensional arrays).
|
|
* \param size The size in the single dimension.
|
|
*/
|
|
void set_dimensions(uintmax_t size)
|
|
{
|
|
uintmax_t sizes[] = { size };
|
|
gta_result_t r = gta_set_dimensions(_header, 1, sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA dimensions", static_cast<gta::result>(r));
|
|
}
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the dimensions (variant for two-dimensional arrays).
|
|
* \param size0 The size in the first dimension.
|
|
* \param size1 The size in the second dimension.
|
|
*/
|
|
void set_dimensions(uintmax_t size0, uintmax_t size1)
|
|
{
|
|
uintmax_t sizes[] = { size0, size1 };
|
|
gta_result_t r = gta_set_dimensions(_header, 2, sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA dimensions", static_cast<gta::result>(r));
|
|
}
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the dimensions (variant for three-dimensional arrays).
|
|
* \param size0 The size in the first dimension.
|
|
* \param size1 The size in the second dimension.
|
|
* \param size2 The size in the third dimension.
|
|
*/
|
|
void set_dimensions(uintmax_t size0, uintmax_t size1, uintmax_t size2)
|
|
{
|
|
uintmax_t sizes[] = { size0, size1, size2 };
|
|
gta_result_t r = gta_set_dimensions(_header, 3, sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA dimensions", static_cast<gta::result>(r));
|
|
}
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
/**
|
|
* \brief Set the dimensions (variant for four-dimensional arrays).
|
|
* \param size0 The size in the first dimension.
|
|
* \param size1 The size in the second dimension.
|
|
* \param size2 The size in the third dimension.
|
|
* \param size3 The size in the fourth dimension.
|
|
*/
|
|
void set_dimensions(uintmax_t size0, uintmax_t size1, uintmax_t size2, uintmax_t size3)
|
|
{
|
|
uintmax_t sizes[] = { size0, size1, size2, size3 };
|
|
gta_result_t r = gta_set_dimensions(_header, 4, sizes);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot set GTA dimensions", static_cast<gta::result>(r));
|
|
}
|
|
reset_dimension_taglists();
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Read and Write Complete Arrays
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Read the complete data.
|
|
* \param io Custom input object.
|
|
* \param data Data buffer.
|
|
*
|
|
* Reads the complete data into the given buffer. The buffer must be large enough.
|
|
*/
|
|
void read_data(custom_io &io, void *data) const
|
|
{
|
|
gta_result_t r = gta_read_data(_header, data, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read the complete data.
|
|
* \param is Input stream.
|
|
* \param data Data buffer.
|
|
*
|
|
* Reads the complete data into the given buffer. The buffer must be large enough.
|
|
*/
|
|
void read_data(std::istream &is, void *data) const
|
|
{
|
|
istream_io io(is);
|
|
gta_result_t r = gta_read_data(_header, data, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read the complete data.
|
|
* \param f Input C stream.
|
|
* \param data Data buffer.
|
|
*
|
|
* Reads the complete data into the given buffer. The buffer must be large enough.
|
|
*/
|
|
void read_data(FILE *f, void *data) const
|
|
{
|
|
gta_result_t r = gta_read_data_from_stream(_header, data, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read the complete data.
|
|
* \param fd Input file descriptor.
|
|
* \param data Data buffer.
|
|
*
|
|
* Reads the complete data into the given buffer. The buffer must be large enough.
|
|
*/
|
|
void read_data(int fd, void *data) const
|
|
{
|
|
gta_result_t r = gta_read_data_from_fd(_header, data, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Skip the complete data.
|
|
* \param io Custom input object.
|
|
*
|
|
* Skips the complete data, so that the next GTA header can be read.
|
|
*/
|
|
void skip_data(custom_io &io) const
|
|
{
|
|
gta_result_t r = gta_skip_data(_header, read_custom_io,
|
|
(io.seekable() ? seek_custom_io : NULL),
|
|
reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot skip GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Skip the complete data.
|
|
* \param is Input stream.
|
|
*
|
|
* Skips the complete data, so that the next GTA header can be read.
|
|
*/
|
|
void skip_data(std::istream &is) const
|
|
{
|
|
istream_io io(is);
|
|
gta_result_t r = gta_skip_data(_header, read_custom_io,
|
|
(io.seekable() ? seek_custom_io : NULL),
|
|
reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot skip GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Skip the complete data.
|
|
* \param f Input C stream.
|
|
*
|
|
* Skips the complete data, so that the next GTA header can be read.
|
|
*/
|
|
void skip_data(FILE *f) const
|
|
{
|
|
gta_result_t r = gta_skip_data_from_stream(_header, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot skip GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Skip the complete data.
|
|
* \param fd Input file descriptor.
|
|
*
|
|
* Skips the complete data, so that the next GTA header can be read.
|
|
*/
|
|
void skip_data(int fd) const
|
|
{
|
|
gta_result_t r = gta_skip_data_from_fd(_header, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot skip GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write the complete data.
|
|
* \param io Custom output object.
|
|
* \param data Data buffer.
|
|
*/
|
|
void write_data(custom_io &io, const void *data) const
|
|
{
|
|
gta_result_t r = gta_write_data(_header, data, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write the complete data.
|
|
* \param os Output stream.
|
|
* \param data Data buffer.
|
|
*/
|
|
void write_data(std::ostream &os, const void *data) const
|
|
{
|
|
ostream_io io(os);
|
|
gta_result_t r = gta_write_data(_header, data, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write the complete data.
|
|
* \param f Output C stream.
|
|
* \param data Data buffer.
|
|
*/
|
|
void write_data(FILE *f, const void *data) const
|
|
{
|
|
gta_result_t r = gta_write_data_to_stream(_header, data, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write the complete data.
|
|
* \param fd Output file descriptor.
|
|
* \param data Data buffer.
|
|
*/
|
|
void write_data(int fd, const void *data) const
|
|
{
|
|
gta_result_t r = gta_write_data_to_fd(_header, data, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Copy the complete data.
|
|
* \param read_io Custom input object.
|
|
* \param write_header Output header.
|
|
* \param write_io Custom output object.
|
|
*/
|
|
void copy_data(custom_io &read_io, const header &write_header, custom_io &write_io) const
|
|
{
|
|
gta_result_t r = gta_copy_data(_header,
|
|
read_custom_io, reinterpret_cast<intptr_t>(&read_io),
|
|
write_header._header,
|
|
write_custom_io, reinterpret_cast<intptr_t>(&write_io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot copy GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Copy the complete data.
|
|
* \param is Input stream.
|
|
* \param write_header Output header.
|
|
* \param os Output stream.
|
|
*/
|
|
void copy_data(std::istream &is, const header &write_header, std::ostream &os) const
|
|
{
|
|
istream_io read_io(is);
|
|
ostream_io write_io(os);
|
|
gta_result_t r = gta_copy_data(_header,
|
|
read_custom_io, reinterpret_cast<intptr_t>(&read_io),
|
|
write_header._header,
|
|
write_custom_io, reinterpret_cast<intptr_t>(&write_io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot copy GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Copy the complete data.
|
|
* \param fi Input C stream.
|
|
* \param write_header Output header.
|
|
* \param fo Output C stream.
|
|
*/
|
|
void copy_data(FILE *fi, const header &write_header, FILE *fo) const
|
|
{
|
|
gta_result_t r = gta_copy_data_stream(_header, fi, write_header._header, fo);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot copy GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Copy the complete data.
|
|
* \param fdi Input file descriptor.
|
|
* \param write_header Output header.
|
|
* \param fdo Output file descriptor.
|
|
*/
|
|
void copy_data(int fdi, const header &write_header, int fdo) const
|
|
{
|
|
gta_result_t r = gta_copy_data_fd(_header, fdi, write_header._header, fdo);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot copy GTA data", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name In-Memory Data Access
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Transform a linear index to array indices.
|
|
* \param index The linear index.
|
|
* \param indices The array indices.
|
|
*/
|
|
void linear_index_to_indices(uintmax_t index, uintmax_t *indices) const
|
|
{
|
|
gta_linear_index_to_indices(_header, index, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Transform array indices to a linear index.
|
|
* \param indices The array indices.
|
|
* \return The linear index.
|
|
*/
|
|
uintmax_t indices_to_linear_index(const uintmax_t *indices) const
|
|
{
|
|
return gta_indices_to_linear_index(_header, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element.
|
|
* \param data Data Buffer.
|
|
* \param indices Indices for each dimension of the array.
|
|
* \return A pointer to the element.
|
|
*/
|
|
const void *element(const void *data, const uintmax_t *indices) const
|
|
{
|
|
return gta_get_element_const(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element.
|
|
* \param data Data Buffer.
|
|
* \param indices Indices for each dimension of the array.
|
|
* \return A pointer to the element.
|
|
*/
|
|
void *element(void *data, const uintmax_t *indices) const
|
|
{
|
|
return gta_get_element(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element via a linear index.
|
|
* \param data Data Buffer.
|
|
* \param index Index of the element.
|
|
* \return A pointer to the element.
|
|
*
|
|
* This function not only works for one-dimensional arrays in the obvious way,
|
|
* but also for multidimensional arrays by using \a index as a linear index to
|
|
* the array data.
|
|
*/
|
|
const void *element(const void *data, uintmax_t index) const
|
|
{
|
|
return gta_get_element_linear_const(_header, data, index);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element via a linear index.
|
|
* \param data Data Buffer.
|
|
* \param index Index of the element.
|
|
* \return A pointer to the element.
|
|
*
|
|
* This function not only works for one-dimensional arrays in the obvious way,
|
|
* but also for multidimensional arrays by using \a index as a linear index to
|
|
* the array data.
|
|
*/
|
|
void *element(void *data, uintmax_t index) const
|
|
{
|
|
return gta_get_element_linear(_header, data, index);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for two-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
const void *element(const void *data, uintmax_t index0, uintmax_t index1) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1 };
|
|
return gta_get_element_const(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for two-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
void *element(void *data, uintmax_t index0, uintmax_t index1) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1 };
|
|
return gta_get_element(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for three-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \param index2 Index of the element in the third dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
const void *element(const void *data, uintmax_t index0, uintmax_t index1, uintmax_t index2) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1, index2 };
|
|
return gta_get_element_const(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for three-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \param index2 Index of the element in the third dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
void *element(void *data, uintmax_t index0, uintmax_t index1, uintmax_t index2) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1, index2 };
|
|
return gta_get_element(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for four-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \param index2 Index of the element in the third dimension.
|
|
* \param index3 Index of the element in the fourth dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
const void *element(const void *data, uintmax_t index0, uintmax_t index1, uintmax_t index2, uintmax_t index3) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1, index2, index3 };
|
|
return gta_get_element_const(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get an array element (variant for four-dimensional arrays).
|
|
* \param data Data Buffer.
|
|
* \param index0 Index of the element in the first dimension.
|
|
* \param index1 Index of the element in the second dimension.
|
|
* \param index2 Index of the element in the third dimension.
|
|
* \param index3 Index of the element in the fourth dimension.
|
|
* \return A pointer to the element.
|
|
*/
|
|
void *element(void *data, uintmax_t index0, uintmax_t index1, uintmax_t index2, uintmax_t index3) const
|
|
{
|
|
uintmax_t indices[] = { index0, index1, index2, index3 };
|
|
return gta_get_element(_header, data, indices);
|
|
}
|
|
|
|
/**
|
|
* \brief Get a component of an array element.
|
|
* \param element Element.
|
|
* \param i Component index.
|
|
* \return A pointer to the component.
|
|
*/
|
|
const void *component(const void *element, uintmax_t i) const
|
|
{
|
|
return gta_get_component_const(_header, element, i);
|
|
}
|
|
|
|
/**
|
|
* \brief Get a component of an array element.
|
|
* \param element Element.
|
|
* \param i Component index.
|
|
* \return A pointer to the component.
|
|
*/
|
|
void *component(void *element, uintmax_t i) const
|
|
{
|
|
return gta_get_component(_header, element, i);
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Read and Write Array Elements
|
|
*
|
|
* These functions are intended to be used for filtering a complete array on a per-element basis.
|
|
* They read or write a given number of elements, and it is expected that they are used
|
|
* repeatedly until all elements of an array have been read or written.
|
|
* Theses function work for all GTAs, with or without compression, an the input and output streams
|
|
* do not need to be seekable.
|
|
*
|
|
* Element-based input/output needs a state object gta::io_state. The same state object must be
|
|
* used until all elements are read or written, or until an error occurs.
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Read array elements.
|
|
* \param state The input/output state.
|
|
* \param io Custom input object.
|
|
* \param n The number of elements to read.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Reads the given number of elements into the given buffer, which must be large enough.
|
|
*/
|
|
void read_elements(io_state &state, custom_io &io, uintmax_t n, void *buf) const
|
|
{
|
|
gta_result_t r = gta_read_elements(_header, state._state, n, buf, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read array elements.
|
|
* \param state The input/output state.
|
|
* \param is Input stream.
|
|
* \param n The number of elements to read.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Reads the given number of elements into the given buffer, which must be large enough.
|
|
*/
|
|
void read_elements(io_state &state, std::istream &is, uintmax_t n, void *buf) const
|
|
{
|
|
istream_io io(is);
|
|
gta_result_t r = gta_read_elements(_header, state._state, n, buf, read_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read array elements.
|
|
* \param state The input/output state.
|
|
* \param f Input stream.
|
|
* \param n The number of elements to read.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Reads the given number of elements into the given buffer, which must be large enough.
|
|
*/
|
|
void read_elements(io_state &state, FILE *f, uintmax_t n, void *buf) const
|
|
{
|
|
gta_result_t r = gta_read_elements_from_stream(_header, state._state, n, buf, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read array elements.
|
|
* \param state The input/output state.
|
|
* \param fd Input file descriptor.
|
|
* \param n The number of elements to read.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Reads the given number of elements into the given buffer, which must be large enough.
|
|
*/
|
|
void read_elements(io_state &state, int fd, uintmax_t n, void *buf) const
|
|
{
|
|
gta_result_t r = gta_read_elements_from_fd(_header, state._state, n, buf, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write array elements.
|
|
* \param state The input/output state.
|
|
* \param io Custom output object.
|
|
* \param n The number of elements to write.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Writes the given number of elements from the given buffer.
|
|
*/
|
|
void write_elements(io_state &state, custom_io &io, uintmax_t n, const void *buf) const
|
|
{
|
|
gta_result_t r = gta_write_elements(_header, state._state, n, buf, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write array elements.
|
|
* \param state The input/output state.
|
|
* \param os Output stream.
|
|
* \param n The number of elements to write.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Writes the given number of elements from the given buffer.
|
|
*/
|
|
void write_elements(io_state &state, std::ostream &os, uintmax_t n, const void *buf) const
|
|
{
|
|
ostream_io io(os);
|
|
gta_result_t r = gta_write_elements(_header, state._state, n, buf, write_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write array elements.
|
|
* \param state The input/output state.
|
|
* \param f Output stream.
|
|
* \param n The number of elements to write.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Writes the given number of elements from the given buffer.
|
|
*/
|
|
void write_elements(io_state &state, FILE *f, uintmax_t n, const void *buf) const
|
|
{
|
|
gta_result_t r = gta_write_elements_to_stream(_header, state._state, n, buf, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write array elements.
|
|
* \param state The input/output state.
|
|
* \param fd Output file descriptor.
|
|
* \param n The number of elements to write.
|
|
* \param buf The buffer for the elements.
|
|
*
|
|
* Writes the given number of elements from the given buffer.
|
|
*/
|
|
void write_elements(io_state &state, int fd, uintmax_t n, const void *buf) const
|
|
{
|
|
gta_result_t r = gta_write_elements_to_fd(_header, state._state, n, buf, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data elements", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/*@}*/
|
|
|
|
/**
|
|
* \name Read and Write Array Blocks
|
|
*
|
|
* These functions can only be used if the data is not compressed (see \a header::compression())
|
|
* and the input/output is seekable.\n
|
|
* They are suitable for applications that do not want to store the complete array data in
|
|
* memory.\n
|
|
* A block is given by the lowest and highest element coordinates in each dimension.
|
|
* For example, for a 2D array from which we want a rectangle of 20x10 elements starting at
|
|
* element (5,3), we would store the values (5,3) in \a lower_coordinates and (24, 12) in
|
|
* \a higher_coordinates.
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Read an array block.
|
|
* \param io Custom input object.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* Reads the given array block and copies it to the given block buffer, which must be large enough.\n
|
|
* This function modifies the file position indicator of the input.
|
|
*/
|
|
void read_block(custom_io &io, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
void *block) const
|
|
{
|
|
gta_result_t r = gta_read_block(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block,
|
|
read_custom_io, seek_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read an array block.
|
|
* \param is Input stream.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* Reads the given array block and copies it to the given block buffer, which must be large enough.\n
|
|
* This function modifies the file position indicator of the input.
|
|
*/
|
|
void read_block(std::istream &is, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
void *block) const
|
|
{
|
|
istream_io io(is);
|
|
gta_result_t r = gta_read_block(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block,
|
|
read_custom_io, seek_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read an array block.
|
|
* \param f Input C stream.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* Reads the given array block and copies it to the given block buffer, which must be large enough.\n
|
|
* This function modifies the file position indicator of the input.
|
|
*/
|
|
void read_block(FILE *f, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
void *block) const
|
|
{
|
|
gta_result_t r = gta_read_block_from_stream(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Read an array block.
|
|
* \param fd Input file descriptor.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* Reads the given array block and copies it to the given block buffer, which must be large enough.\n
|
|
* This function modifies the file position indicator of the input.
|
|
*/
|
|
void read_block(int fd, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
void *block) const
|
|
{
|
|
gta_result_t r = gta_read_block_from_fd(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot read GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write an array block.
|
|
* \param io Custom output object.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* This function modifies the file position indicator of the output.
|
|
*/
|
|
void write_block(custom_io &io, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
const void *block) const
|
|
{
|
|
gta_result_t r = gta_write_block(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block,
|
|
write_custom_io, seek_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write an array block.
|
|
* \param os Output stream.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* This function modifies the file position indicator of the output.
|
|
*/
|
|
void write_block(std::ostream &os, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
const void *block) const
|
|
{
|
|
ostream_io io(os);
|
|
gta_result_t r = gta_write_block(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block,
|
|
write_custom_io, seek_custom_io, reinterpret_cast<intptr_t>(&io));
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write an array block.
|
|
* \param f Output C stream.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* This function modifies the file position indicator of the output.
|
|
*/
|
|
void write_block(FILE *f, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
const void *block) const
|
|
{
|
|
gta_result_t r = gta_write_block_to_stream(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block, f);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Write an array block.
|
|
* \param fd Output file descriptor.
|
|
* \param data_offset Offset of the first data byte.
|
|
* \param lower_coordinates Coordinates of the lower corner element of the block.
|
|
* \param higher_coordinates Coordinates of the higher corner element of the block.
|
|
* \param block Block buffer.
|
|
*
|
|
* This function modifies the file position indicator of the output.
|
|
*/
|
|
void write_block(int fd, uintmax_t data_offset,
|
|
const uintmax_t *lower_coordinates, const uintmax_t *higher_coordinates,
|
|
const void *block) const
|
|
{
|
|
gta_result_t r = gta_write_block_to_fd(_header, data_offset,
|
|
lower_coordinates, higher_coordinates, block, fd);
|
|
if (r != GTA_OK)
|
|
{
|
|
throw exception("Cannot write GTA data block", static_cast<gta::result>(r));
|
|
}
|
|
}
|
|
|
|
/*@}*/
|
|
};
|
|
|
|
|
|
/**
|
|
* \name Version information
|
|
*/
|
|
|
|
/*@{*/
|
|
|
|
/**
|
|
* \brief Get the version string.
|
|
* \return The version string "MAJOR.MINOR.PATCH"
|
|
*/
|
|
inline const char *version()
|
|
{
|
|
return gta_version(NULL, NULL, NULL);
|
|
}
|
|
|
|
/**
|
|
* \brief Get the major version number.
|
|
* \return The major version number.
|
|
*/
|
|
inline int version_major()
|
|
{
|
|
int major;
|
|
gta_version(&major, NULL, NULL);
|
|
return major;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the minor version number.
|
|
* \return The minor version number.
|
|
*/
|
|
inline int version_minor()
|
|
{
|
|
int minor;
|
|
gta_version(NULL, &minor, NULL);
|
|
return minor;
|
|
}
|
|
|
|
/**
|
|
* \brief Get the patch version number.
|
|
* \return The patch version number.
|
|
*/
|
|
inline int version_patch()
|
|
{
|
|
int patch;
|
|
gta_version(NULL, NULL, &patch);
|
|
return patch;
|
|
}
|
|
|
|
/*@}*/
|
|
}
|
|
|
|
#ifdef _MSC_VER
|
|
# pragma warning (pop)
|
|
#endif
|
|
|
|
#endif
|