OOXML files support

This commit is contained in:
2019-12-19 16:53:18 -05:00
parent d6fe61cfdc
commit 8451109ecd
38 changed files with 2938 additions and 11 deletions

189
include/opc/config.h Normal file
View File

@@ -0,0 +1,189 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**@file config/opc/config.h
*/
#ifndef OPC_CONFIG_H
#define OPC_CONFIG_H
#include <libxml/xmlstring.h>
#include <plib/plib.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
Assert expression e is true. Will be removed entirely in release mode.
\hideinitializer
*/
#define OPC_ASSERT(e) assert(e)
/**
Assert expression e is true. Expression will be executed in release mode too.
\hideinitializer
*/
#ifdef NDEBUG
#define OPC_ENSURE(e) (void)(e)
#else
#define OPC_ENSURE(e) assert(e)
#endif
/**
Constant for boolean true.
\hideinitializer
*/
#define OPC_TRUE (0==0)
/**
Constant for boolean false.
\hideinitializer
*/
#define OPC_FALSE (0==1)
/**
Boolean type.
\hideinitializer
*/
typedef pbool_t opc_bool_t;
/**
Type which represents an offset in e.g. a file.
\hideinitializer
*/
typedef pofs_t opc_ofs_t;
/**
8-bit unsigned integer.
\hideinitializer
*/
typedef puint8_t opc_uint8_t;
/**
16-bit unsigned integer.
\hideinitializer
*/
typedef puint16_t opc_uint16_t;
/**
32-bit unsigned integer.
\hideinitializer
*/
typedef puint32_t opc_uint32_t;
/**
64-bit unsigned integer.
\hideinitializer
*/
typedef puint64_t opc_uint64_t;
/**
8-bit signed integer.
\hideinitializer
*/
typedef pint8_t opc_int8_t;
/**
16-bit signed integer.
\hideinitializer
*/
typedef pint16_t opc_int16_t;
/**
32-bit signed integer.
\hideinitializer
*/
typedef pint32_t opc_int32_t;
/**
64-bit signed integer.
\hideinitializer
*/
typedef pint64_t opc_int64_t;
/**
Default size fo the deflate buffer used by zlib.
*/
#define OPC_DEFLATE_BUFFER_SIZE 4096
/**
Max system path len.
*/
#define OPC_MAX_PATH 512
/**
Error codes for the OPC module.
*/
typedef enum OPC_ERROR_ENUM {
OPC_ERROR_NONE,
OPC_ERROR_STREAM,
OPC_ERROR_SEEK, // can't seek
OPC_ERROR_UNSUPPORTED_DATA_DESCRIPTOR,
OPC_ERROR_UNSUPPORTED_COMPRESSION,
OPC_ERROR_DEFLATE,
OPC_ERROR_HEADER,
OPC_ERROR_MEMORY,
OPC_ERROR_XML,
OPC_ERROR_USER // user triggered an abort
} opc_error_t;
/**
Compression options for OPC streams.
*/
typedef enum OPC_COMPRESSIONOPTION_ENUM {
OPC_COMPRESSIONOPTION_NONE,
OPC_COMPRESSIONOPTION_NORMAL,
OPC_COMPRESSIONOPTION_MAXIMUM,
OPC_COMPRESSIONOPTION_FAST,
OPC_COMPRESSIONOPTION_SUPERFAST
} opcCompressionOption_t;
/**
Helper for debug logs.
\hideinitializer
*/
#define opc_logf printf
/**
Abstraction for memset(m, 0, s).
\hideinitializer
*/
#define opc_bzero_mem(m,s) memset(m, 0, s)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_CONFIG_H */

300
include/opc/container.h Normal file
View File

@@ -0,0 +1,300 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/container.h
The container.h module has the fundamental methods for dealing with ZIP-based OPC container.
OPC container can be opened in READ-ONLY mode, WRITE-ONLY mode, READ/WRITE mode, TEMPLATE mode and TRANSITION mode.
The most notable mode is the READ/WRITE mode, which gives you concurrent stream-based READ and WRITE access to a
single ZIP-based OPC container. This is achieved without the use of temporary files by taking advantage of the
OPC specific “interleave” mode. \see http://standards.iso.org/ittf/PubliclyAvailableStandards/c051459_ISOIEC_29500-2_2008(E).zip
The TEMPLATE mode allows very fast customized "cloning" of ZIP-based OPC container by using "RAW access" to the ZIP streams.
The TRANSITION mode is a special version of the TEMPLATE mode, which allows transition-based READ/WRITE access to the
ZIP-based OPC container using a temporary file.
*/
#include <opc/config.h>
#include <opc/file.h>
#ifndef OPC_CONTAINER_H
#define OPC_CONTAINER_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Handle to an OPC container created by \ref opcContainerOpen.
\see opcContainerOpen.
*/
typedef struct OPC_CONTAINER_STRUCT opcContainer;
/**
Modes for opcContainerOpen();
\see opcContainerOpen
*/
typedef enum {
/**
Opens the OPC container denoted by \a fileName in READ-ONLY mode. The \a destName parameter must be \a NULL.
\hideinitializer
*/
OPC_OPEN_READ_ONLY=0,
/**
Opens the OPC container denoted by \a fileName in WRITE-ONLY mode. The \a destName parameter must be \a NULL.
\hideinitializer
*/
OPC_OPEN_WRITE_ONLY=1,
/**
Opens the OPC container denoted by \a fileName in READ/WRITE mode. The \a destName parameter must be \a NULL.
\hideinitializer
*/
OPC_OPEN_READ_WRITE=2,
/**
This mode will open the container denoted by \a fileName in READ-ONLY mode and the container denoted by
\a destName in write-only mode. Any modifications will be written to the container denoted by \a destName
and the unmodified streams from \a fileName will be written to \a destName on closing.
\warning Currently not implemented.
\hideinitializer
*/
OPC_OPEN_TEMPLATE=3,
/**
Like the OPC_OPEN_TEMPLATE mode, but the \a destName will be renamed to the \a fileName on closing. If \a destName
is \a NULL, then the name of the temporary file will be generated automatically.
\warning Currently not implemented.
\hideinitializer
*/
OPC_OPEN_TRANSITION=4
} opcContainerOpenMode;
/** Modes for opcContainerClose.
\see opcContainerClose.
*/
typedef enum {
/**
Close the OPC container without any further postprocessing.
\hideinitializer
*/
OPC_CLOSE_NOW = 0,
/**
Close the OPC container and trim the file by removing unused fragments like e.g.
deleted parts.
\hideinitializer
*/
OPC_CLOSE_TRIM = 1,
/**
Close the OPC container like in \a OPC_CLOSE_TRIM mode, but additionally remove any
"interleaved" parts by reordering them.
\warning Currently not implemented. Same semantic as OPC_CLOSE_TRIM.
\hideinitializer
*/
OPC_CLOSE_DEFRAG = 2
} opcContainerCloseMode;
/**
Opens a ZIP-based OPC container.
@param[in] fileName. For more details see \ref opcContainerOpenMode.
@param[in] mode. For more details see \ref opcContainerOpenMode.
@param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
@param[in] destName. For more details see \ref opcContainerOpenMode.
@return \a NULL if failed.
\see opcContainerOpenMode
\see opcContainerDump
*/
opcContainer* opcContainerOpen(const xmlChar *fileName,
opcContainerOpenMode mode,
void *userContext,
const xmlChar *destName);
/**
Opens a ZIP-based OPC container from memory.
@param[in] data.
@param[in] data_len.
@param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
@param[in] mode. For more details see \ref opcContainerOpenMode.
@return \a NULL if failed.
*/
opcContainer* opcContainerOpenMem(const opc_uint8_t *data, opc_uint32_t data_len,
opcContainerOpenMode mode,
void *userContext);
/**
Opens a ZIP-based OPC container from memory.
@param[in] ioread.
@param[in] iowrite.
@param[in] ioclose.
@param[in] ioseek.
@param[in] iotrim.
@param[in] ioflush.
@param[in] iocontext.
@param[in] file_size.
@param[in] userContext. Will not be modified by libopc. Can be used to e.g. store the "this" pointer for C++ bindings.
@param[in] mode. For more details see \ref opcContainerOpenMode.
@return \a NULL if failed.
*/
opcContainer* opcContainerOpenIO(opcFileReadCallback *ioread,
opcFileWriteCallback *iowrite,
opcFileCloseCallback *ioclose,
opcFileSeekCallback *ioseek,
opcFileTrimCallback *iotrim,
opcFileFlushCallback *ioflush,
void *iocontext,
pofs_t file_size,
opcContainerOpenMode mode,
void *userContext);
/**
Close an OPC container.
@param[in] c. \ref opcContainer openered by \ref opcContainerOpen.
@param[in] mode. For more information see \ref opcContainerCloseMode.
@return Non-zero if successful.
\see opcContainerOpen
\see opcContainerCloseMode
*/
opc_error_t opcContainerClose(opcContainer *c, opcContainerCloseMode mode);
/**
Returns the unmodified user context passed to \ref opcContainerOpen.
\see opcContainerOpen
*/
void *opcContainerGetUserContext(opcContainer *c);
/**
List all types, relations and parts of the container \a c to \a out.
\par Sample:
\include opc_dump.c
*/
opc_error_t opcContainerDump(opcContainer *c, FILE *out);
/**
Exports the OPC container to "Flat OPC" (http://blogs.msdn.com/b/ericwhite/archive/2008/09/29/the-flat-opc-format.aspx).
The flat versions of an OPC file are very important when dealing with e.g XSL(T)-based or Javascript-based transformations.
\see opcContainerFlatImport.
\todo Implementation needed.
*/
int opcContainerFlatExport(opcContainer *c, const xmlChar *fileName);
/**
Imports the flat version of an OPC container.
\see opcContainerFlatExport.
\todo Implementation needed.
*/
int opcContainerFlatImport(opcContainer *c, const xmlChar *fileName);
/**
Iterate all types.
\code
for(xmlChar *type=opcContentTypeFirst(c);
NULL!=type;
type=opcContentTypeNext(c, type)) {
printf("%s\n", type);
}
\endcode
*/
const xmlChar *opcContentTypeFirst(opcContainer *container);
/**
\see opcContentTypeNext()
*/
const xmlChar *opcContentTypeNext(opcContainer *container, const xmlChar *type);
/**
Iterate extensions.
\code
for(const xmlChar *ext=opcExtensionFirst(c);
NULL!=ext;
ext=opcExtensionNext(ext)) {
printf("%s\n", ext);
}
\endcode
*/
const xmlChar *opcExtensionFirst(opcContainer *container);
/**
\see opcExtensionFirst()
*/
const xmlChar *opcExtensionNext(opcContainer *container, const xmlChar *ext);
/**
Get registered type for extension.
\see opcExtensionRegister()
*/
const xmlChar *opcExtensionGetType(opcContainer *container, const xmlChar *ext);
/**
Register a mime-type and and extension.
\see opcExtensionGetType()
*/
const xmlChar *opcExtensionRegister(opcContainer *container, const xmlChar *ext, const xmlChar *type);
/**
Iterator through all relation types of the container:
\code
for(xmlChar *type=opcRelationTypeFirst(c);
NULL!=type;
type=opcRelationTypeNext(c, type)) {
printf("%s\n", type);
}
\endcode
*/
const xmlChar *opcRelationTypeFirst(opcContainer *container);
/**
\see opcRelationTypeFirst()
*/
const xmlChar *opcRelationTypeNext(opcContainer *container, const xmlChar *type);
/**
Iterator through all relation types of the container:
\code
for(xmlChar *target=opcExternalTargetFirst(c);
NULL!=target;
type=opcExternalTargetNext(c, target)) {
printf("%s\n", target);
}
\endcode
*/
const xmlChar *opcExternalTargetFirst(opcContainer *container);
/**
\see opcExternalTargetFirst()
*/
const xmlChar *opcExternalTargetNext(opcContainer *container, const xmlChar *target);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_CONTAINER_H */

200
include/opc/file.h Normal file
View File

@@ -0,0 +1,200 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/file.h
The opc module contains the file library functions.
*/
#include <opc/config.h>
#ifndef OPC_FILE_H
#define OPC_FILE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Flag for READ access.
\hideinitializer
*/
#define OPC_FILE_READ (1<<0)
/**
Flag for WRITE access.
\hideinitializer
*/
#define OPC_FILE_WRITE (1<<1)
/**
Flag indicates that file will be truncated when opened.
\hideinitializer
*/
#define OPC_FILE_TRUNC (1<<2)
/**
Abstraction for see modes.
*/
typedef enum OPC_FILESEEKMODE_ENUM {
opcFileSeekSet = SEEK_SET,
opcFileSeekCur = SEEK_CUR,
opcFileSeekEnd = SEEK_END
} opcFileSeekMode;
/**
Callback to read a file. E.g. for a FILE * context this can be implemented as
\code
static int opcFileRead(void *iocontext, char *buffer, int len) {
return fread(buffer, sizeof(char), len, (FILE*)iocontext);
}
\endcode
*/
typedef int opcFileReadCallback(void *iocontext, char *buffer, int len);
/**
Callback to write a file. E.g. for a FILE * context this can be implemented as
\code
static int opcFileWrite(void *iocontext, const char *buffer, int len) {
return fwrite(buffer, sizeof(char), len, (FILE*)iocontext);
}
\endcode
*/
typedef int opcFileWriteCallback(void *iocontext, const char *buffer, int len);
/**
Callback to close a file. E.g. for a FILE * context this can be implemented as
\code
static int opcFileClose(void *iocontext) {
return fclose((FILE*)iocontext);
}
\endcode
*/
typedef int opcFileCloseCallback(void *iocontext);
/**
Callback to seek a file. E.g. for a FILE * context this can be implemented as
\code
static opc_ofs_t opcFileSeek(void *iocontext, opc_ofs_t ofs) {
int ret=fseek((FILE*)iocontext, ofs, SEEK_SET);
if (ret>=0) {
return ftell((FILE*)iocontext);
} else {
return ret;
}
}
\endcode
*/
typedef opc_ofs_t opcFileSeekCallback(void *iocontext, opc_ofs_t ofs);
/**
Callback to trim a file. E.g. for a FILE * context this can be implemented as
\code
static int opcFileTrim(void *iocontext, opc_ofs_t new_size) {
#ifdef WIN32
return _chsize(fileno((FILE*)iocontext), new_size);
#else
return ftruncate(fileno((FILE*)iocontext), new_size);
#endif
}
\endcode
*/
typedef int opcFileTrimCallback(void *iocontext, opc_ofs_t new_size);
/**
Callback to flush a file. E.g. for a FILE * context this can be implemented as
\code
static int opcFileFlush(void *iocontext) {
return fflush((FILE*)iocontext);
}
\endcode
*/
typedef int opcFileFlushCallback(void *iocontext);
/**
Represents a state of a file, i.e. file position (buf_pos) and error status (err).
*/
typedef struct OPC_FILERAWSTATE_STRUCT {
opc_error_t err;
opc_ofs_t buf_pos; // current pos in file
} opcFileRawState;
/**
File IO context.
*/
typedef struct OPC_IO_STRUCT {
opcFileReadCallback *_ioread;
opcFileWriteCallback *_iowrite;
opcFileCloseCallback *_ioclose;
opcFileSeekCallback *_ioseek;
opcFileTrimCallback *_iotrim;
opcFileFlushCallback *_ioflush;
void *iocontext;
int flags;
opcFileRawState state;
opc_ofs_t file_size;
} opcIO_t;
/**
Initialize an IO context.
*/
opc_error_t opcFileInitIO(opcIO_t *io,
opcFileReadCallback *ioread,
opcFileWriteCallback *iowrite,
opcFileCloseCallback *ioclose,
opcFileSeekCallback *ioseek,
opcFileTrimCallback *iotrim,
opcFileFlushCallback *ioflush,
void *iocontext,
pofs_t file_size,
int flags);
/**
Initialize an IO context for a file.
*/
opc_error_t opcFileInitIOFile(opcIO_t *io, const xmlChar *filename, int flags);
/**
Initialize an IO for memory.
\warning Currently supports READ-ONLY file access.
*/
opc_error_t opcFileInitIOMemory(opcIO_t *io, const opc_uint8_t *data, opc_uint32_t data_len, int flags);
/**
Cleanup an IO context, i.e. release all system resources.
*/
opc_error_t opcFileCleanupIO(opcIO_t *io);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_FILE_H */

60
include/opc/helper.h Normal file
View File

@@ -0,0 +1,60 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/helper.h
Contains helper functions for the opc module.
*/
#include <opc/config.h>
#ifndef OPC_HELPER_H
#define OPC_HELPER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
/**
Constructs a segment name.
*/
opc_uint16_t opcHelperAssembleSegmentName(char *out, opc_uint16_t out_size, const xmlChar *name, opc_uint32_t segment_number, opc_uint32_t next_segment_id, opc_bool_t rels_segment, opc_uint16_t *out_max);
/**
Splits a filename into the segment informations.
*/
opc_error_t opcHelperSplitFilename(opc_uint8_t *filename, opc_uint32_t filename_length, opc_uint32_t *segment_number, opc_bool_t *last_segment, opc_bool_t *rel_segment);
#endif /* OPC_HELPER_H */

74
include/opc/inputstream.h Normal file
View File

@@ -0,0 +1,74 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/inputstream.h
*/
#include <opc/config.h>
#ifndef OPC_INPUTSTREAM_H
#define OPC_INPUTSTREAM_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Internal type which represents a binary input stream.
*/
typedef struct OPC_CONTAINER_INPUTSTREAM_STRUCT opcContainerInputStream;
/**
Opens the part \c name of the \c container for reading.
*/
opcContainerInputStream* opcContainerOpenInputStream(opcContainer *container, const xmlChar *name);
/**
Reads maximal \c buffer_len bytes from the input \c stream to \c buffer.
\return The number of byes read or "0" in case of an error or end-of-stream.
*/
opc_uint32_t opcContainerReadInputStream(opcContainerInputStream* stream, opc_uint8_t *buffer, opc_uint32_t buffer_len);
/**
Closes the input stream and releases all system resources.
*/
opc_error_t opcContainerCloseInputStream(opcContainerInputStream* stream);
/**
Returns the type of compression used for the stream.
*/
opcCompressionOption_t opcContainerGetInputStreamCompressionOption(opcContainerInputStream* stream);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_INPUTSTREAM_H */

73
include/opc/opc.h Normal file
View File

@@ -0,0 +1,73 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/opc.h
The opc module contains the basic library functions.
*/
#include <opc/config.h>
#include <opc/container.h>
#include <opc/part.h>
#include <opc/relation.h>
#include <opc/inputstream.h>
#include <opc/outputstream.h>
#include <opc/zip.h>
#include <opc/xmlreader.h>
#include <opc/xmlwriter.h>
#include <opc/properties.h>
#ifndef OPC_OPC_H
#define OPC_OPC_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize libopc.
* Sample:
* \include opc_helloworld.c
* @return Non-zero if successful.
*/
opc_error_t opcInitLibrary();
/**
* Free libopc. Clean up all resources.
* @return Non-zero if successful.
* \see opcInitLibrary.
*/
opc_error_t opcFreeLibrary();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_OPC_H */

View File

@@ -0,0 +1,71 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/outputstream.h
*/
#include <opc/config.h>
#ifndef OPC_OUTPUTSTREAM_H
#define OPC_OUTPUTSTREAM_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Internal type which represents a binary output stream.
*/
typedef struct OPC_CONTAINER_OUTPUTSTREAM_STRUCT opcContainerOutputStream;
/**
Open the part \c name or writing in \c container with compression \c compression_option.
\note Make sure the part exists!
\see opcPartCreate.
*/
opcContainerOutputStream* opcContainerCreateOutputStream(opcContainer *container, const xmlChar *name, opcCompressionOption_t compression_option);
/**
Write \c buffer_len bytes from \c buffer to \c stream.
\return Returns the number of bytes written.
*/
opc_uint32_t opcContainerWriteOutputStream(opcContainerOutputStream* stream, const opc_uint8_t *buffer, opc_uint32_t buffer_len);
/**
Close the \c stream and free all associated resources.
*/
opc_error_t opcContainerCloseOutputStream(opcContainerOutputStream* stream);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_OUTPUTSTREAM_H */

118
include/opc/part.h Normal file
View File

@@ -0,0 +1,118 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/part.h
*/
#include <opc/config.h>
#ifndef OPC_PART_H
#define OPC_PART_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Handle to an OPC part created by \ref opcPartOpen.
\see opcPartOpen.
*/
typedef xmlChar* opcPart;
/**
Represents an invalid (resp. NULL) part.
In releations OPC_PART_INVALID also represents the root part.
\hideinitializer
*/
#define OPC_PART_INVALID NULL
/**
Find a part in a \ container by \c absolutePath and/or \c type.
Currently no flags are supported.
*/
opcPart opcPartFind(opcContainer *container,
const xmlChar *absolutePath,
const xmlChar *type,
int flags);
/**
Creates a part in a \ container with \c absolutePath and \c type.
Currently no flags are supported.
*/
opcPart opcPartCreate(opcContainer *container,
const xmlChar *absolutePath,
const xmlChar *type,
int flags);
/**
Returns the type of the container.
The string is interned and must not be freed.
*/
const xmlChar *opcPartGetType(opcContainer *c, opcPart part);
/**
Returns the type of the container.
If \c override_only then the return value will be NULL for parts not having an override type.
The string is interned and must not be freed.
*/
const xmlChar *opcPartGetTypeEx(opcContainer *c, opcPart part, opc_bool_t override_only);
/**
Deleted that part \c absolutePath in the \c container.
*/
opc_error_t opcPartDelete(opcContainer *container, const xmlChar *absolutePath);
/**
Get the first part.
\code
for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
printf("%s; \n", part, opcPartGetType(c, part));
}
\endcode
*/
opcPart opcPartGetFirst(opcContainer *container);
/**
Get the next part.
\see opcPartGetFirst
*/
opcPart opcPartGetNext(opcContainer *container, opcPart part);
/**
Returns the size in bytes of the \c part.
*/
opc_ofs_t opcPartGetSize(opcContainer *c, opcPart part);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_PART_H */

121
include/opc/properties.h Executable file
View File

@@ -0,0 +1,121 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/properties.h
*/
#include <opc/config.h>
#include <opc/container.h>
#ifndef OPC_PROPERTIES_H
#define OPC_PROPERTIES_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Represents a simple Dublin Core type.
*/
typedef struct OPC_DC_SIMPLE_TYPE {
xmlChar *str;
xmlChar *lang;
} opcDCSimpleType_t;
/**
Represents the core properties of an OPC container.
*/
typedef struct OPC_PROPERTIES_STRUCT {
xmlChar *category; /* xsd:string */
xmlChar *contentStatus; /* xsd:string */
xmlChar *created; /* dc:date */
opcDCSimpleType_t creator; /* dc:any */
opcDCSimpleType_t description; /* dc:any */
opcDCSimpleType_t identifier; /* dc:any */
opcDCSimpleType_t *keyword_array; /* cp:CT_Keywords */
opc_uint32_t keyword_items;
opcDCSimpleType_t language; /* dc:any */
xmlChar *lastModifiedBy; /* xsd:string */
xmlChar *lastPrinted; /* xsd:dateTime */
xmlChar *modified; /* dc:date */
xmlChar *revision; /* xsd:string */
opcDCSimpleType_t subject; /* dc:any */
opcDCSimpleType_t title; /* dc:any */
xmlChar *version; /* xsd:string */
} opcProperties_t;
/**
Initialize the core properties \c cp.
\see opcCorePropertiesSetString
*/
opc_error_t opcCorePropertiesInit(opcProperties_t *cp);
/**
Cleanup the core properties \c cp, i.e. release all resources.
\see opcCorePropertiesSetString
*/
opc_error_t opcCorePropertiesCleanup(opcProperties_t *cp);
/**
Rease the core properties \c cp from the container \c.
*/
opc_error_t opcCorePropertiesRead(opcProperties_t *cp, opcContainer *c);
/**
Write/Update the core properties \c cp in the container \c.
*/
opc_error_t opcCorePropertiesWrite(opcProperties_t *cp, opcContainer *c);
/**
Update a string in the core properties the right way.
\code
opcProperties_t cp;
opcCorePropertiesInit(&cp);
opcCorePropertiesSetString(&cp.revision, "1");
opcCorePropertiesSetStringLang(&cp.creator, "Florian Reuter", NULL);
opcCorePropertiesCleanup(&cp);
\endcode
*/
opc_error_t opcCorePropertiesSetString(xmlChar **prop, const xmlChar *str);
/**
Update a core properties the right way.
\see opcCorePropertiesSetString
*/
opc_error_t opcCorePropertiesSetStringLang(opcDCSimpleType_t *prop, const xmlChar *str, const xmlChar *lang);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_PROPERTIES_H */

140
include/opc/relation.h Normal file
View File

@@ -0,0 +1,140 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/relation.h
*/
#include <opc/config.h>
#ifndef OPC_RELATION_H
#define OPC_RELATION_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Indentifier for an OPC relation.
*/
typedef opc_uint32_t opcRelation;
/**
Constant which represents an invalid relation.
*/
#define OPC_RELATION_INVALID (-1)
/**
Find a relation originating from \c part in \c container with \c relationId and/or \c mimeType.
If \c part is OPC_PART_INVALID then part represents the root part.
@param[in] relationId The relationId (e.g. "rId1") or NULL.
@param[in] mimeType The mimeType or NULL.
*/
opcRelation opcRelationFind(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType);
/**
Deleted the relation from the container.
\see opcRelationFind.
*/
opc_error_t opcRelationDelete(opcContainer *container, opcPart part, const xmlChar *relationId, const xmlChar *mimeType);
/**
Returns the first relation.
The following code will dump all relations:
\code
for(opcPart part=opcPartGetFirst(c);OPC_PART_INVALID!=part;part=opcPartGetNext(c, part)) {
for(opcRelation rel=opcRelationFirst(part, c);
OPC_PART_INVALID!=rel;
rel=opcRelationNext(c, rel)) {
opcPart internal_target=opcRelationGetInternalTarget(c, part, rel);
const xmlChar *external_target=opcRelationGetExternalTarget(c, part, rel);
const xmlChar *target=(NULL!=internal_target?internal_target:external_target);
const xmlChar *prefix=NULL;
opc_uint32_t counter=-1;
const xmlChar *type=NULL;
opcRelationGetInformation(c, part, rel, &prefix, &counter, &type);
if (-1==counter) { // no counter after prefix
printf("%s;%s;%s;%s\n", part, prefix, target, type);
} else {
printf("%s;%s%i;%s;%s\n", part, prefix, counter, target, type);
}
}
}
\endcode
*/
opcRelation opcRelationFirst(opcContainer *container, opcPart part);
/**
\see opcRelationFirst
*/
opcRelation opcRelationNext(opcContainer *container, opcPart part, opcRelation relation);
/**
Returns the internal target.
\note To test for an external target use opcRelationGetExternalTarget.
\see opcRelationGetExternalTarget
*/
opcPart opcRelationGetInternalTarget(opcContainer *container, opcPart part, opcRelation relation);
/**
Returns the external target or NULL if it is an internal target.
The string is interned. Must not be freed.
\see opcRelationGetExternalTarget
*/
const xmlChar *opcRelationGetExternalTarget(opcContainer *container, opcPart part, opcRelation relation);
/**
Returns the relations type.
The string is interned. Must not be freed.
*/
const xmlChar *opcRelationGetType(opcContainer *container, opcPart part, opcRelation relation);
/**
Get information about a relation.
\see opcRelationFirst
*/
void opcRelationGetInformation(opcContainer *container, opcPart part, opcRelation relation, const xmlChar **prefix, opc_uint32_t *counter, const xmlChar **type);
/**
Add a relation to \c container from \c src part to \c dest part with id \c rid and type \c type.
*/
opc_uint32_t opcRelationAdd(opcContainer *container, opcPart src, const xmlChar *rid, opcPart dest, const xmlChar *type);
/**
Add an external relation to \c container from \c src part to \c target URL with id \c rid and type \c type.
*/
opc_uint32_t opcRelationAddExternal(opcContainer *container, opcPart src, const xmlChar *rid, const xmlChar *target, const xmlChar *type);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_RELATION_H */

69
include/opc/xmlreader.h Normal file
View File

@@ -0,0 +1,69 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/xmlreader.h
*/
#ifndef OPC_XMLREADER_H
#define OPC_XMLREADER_H
#include <opc/config.h>
#include <libxml/xmlreader.h>
#include <mce/textreader.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
Open an MCE reader for \c partName. Parameters \c URL, \c encoding and \c options will be passed unmodified to
http://xmlsoft.org/html/libxml-xmlreader.html#xmlReaderForIO and they can we NULL, NULL, 0.
\note Make sure the part exists.
\see opcPartFind
*/
opc_error_t opcXmlReaderOpen(opcContainer *container, mceTextReader_t *mceTextReader, const xmlChar *partName, const char * URL, const char * encoding, int options);
/**
Returns an libxml DOM document. Parameters \c URL, \c encoding and \c options will be passed unmodified to
http://xmlsoft.org/html/libxml-parser.html#xmlReadIO and they can we NULL, NULL, 0.
\note Make sure the part exists.
\see opcPartFind
*/
xmlDocPtr opcXmlReaderReadDoc(opcContainer *container, const xmlChar *partName, const char * URL, const char * encoding, int options);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_XMLREADER_H */

57
include/opc/xmlwriter.h Normal file
View File

@@ -0,0 +1,57 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/xmlwriter.h
*/
#include <opc/config.h>
#include <mce/textwriter.h>
#ifndef OPC_XMLWRITER_H
#define OPC_XMLWRITER_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Create an MCE text writer for \c part in \c container with compression \c compression_option.
\note Make sure the part exists.
\see opcPartFind
*/
mceTextWriter *mceTextWriterOpen(opcContainer *c, opcPart part, opcCompressionOption_t compression_option);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_XMLWRITER_H */

255
include/opc/zip.h Normal file
View File

@@ -0,0 +1,255 @@
/*
Copyright (c) 2010, Florian Reuter
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of Florian Reuter nor the names of its contributors
may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file opc/zip.h
The ZIP file backend of an OPC container.
*/
#include <opc/config.h>
#include <opc/file.h>
#include <opc/container.h>
#ifndef OPC_ZIP_H
#define OPC_ZIP_H
#ifdef __cplusplus
extern "C" {
#endif
/**
Default growth hint of an OPC stream.
*/
#define OPC_DEFAULT_GROWTH_HINT 512
/**
Handle to a ZIP archive.
\see internal.h
*/
typedef struct OPC_ZIP_STRUCT opcZip;
/**
Handle to a raw ZIP input stream.
\see internal.h
*/
typedef struct OPC_ZIPINPUTSTREAM_STRUCT opcZipInputStream;
/**
Handle to a raw ZIP output stream.
\see internal.h
*/
typedef struct OPC_ZIPOUTPUTSTREAM_STRUCT opcZipOutputStream;
/**
Holds all information of a ZIP segment.
*/
typedef struct OPC_ZIP_SEGMENT_INFO_STRUCT {
xmlChar name[OPC_MAX_PATH];
opc_uint32_t name_len;
opc_uint32_t segment_number;
opc_bool_t last_segment;
opc_bool_t rels_segment;
opc_uint32_t header_size;
opc_uint32_t min_header_size;
opc_uint32_t trailing_bytes;
opc_uint32_t compressed_size;
opc_uint32_t uncompressed_size;
opc_uint16_t bit_flag;
opc_uint32_t data_crc;
opc_uint16_t compression_method;
opc_ofs_t stream_ofs;
opc_uint16_t growth_hint;
} opcZipSegmentInfo_t;
/**
\see opcZipLoader
*/
typedef int opcZipLoaderOpenCallback(void *iocontext);
/**
\see opcZipLoader
*/
typedef int opcZipLoaderSkipCallback(void *iocontext);
/**
\see opcZipLoader
*/
typedef int opcZipLoaderReadCallback(void *iocontext, char *buffer, int len);
/**
\see opcZipLoader
*/
typedef int opcZipLoaderCloseCallback(void *iocontext);
/**
\see opcZipLoader
*/
typedef opc_error_t (opcZipLoaderSegmentCallback_t)(void *iocontext, void *userctx, opcZipSegmentInfo_t *info, opcZipLoaderOpenCallback *open, opcZipLoaderReadCallback *read, opcZipLoaderCloseCallback *close, opcZipLoaderSkipCallback *skip);
/**
Walks every segment in a ZIP archive and calls the \c segmentCallback callback method.
The implementer \c segmentCallback method must then eiher use the passed \c open, \c read and \c close methods
to read the stream or the passed \c skip methods to skip the stream.
This method can be used to e.g. read ZIP file in stream mode.
*/
opc_error_t opcZipLoader(opcIO_t *io, void *userctx, opcZipLoaderSegmentCallback_t *segmentCallback);
/**
\see opcZipClose
*/
typedef opc_error_t (opcZipSegmentReleaseCallback)(opcZip *zip, opc_uint32_t segment_id);
/**
Closes the ZIP archive \c zip and will call \c releaseCallback for every segment to give the implementer a chance
to free user resources.
*/
void opcZipClose(opcZip *zip, opcZipSegmentReleaseCallback* releaseCallback);
/**
Creates an empty ZIP archive with the given \c io.
*/
opcZip *opcZipCreate(opcIO_t *io);
/**
Commits all buffers and writes the ZIP archives local header directories.
if \c trim is true then padding bytes will be removed, i.e. the ZIP file size fill be minimalized.
*/
opc_error_t opcZipCommit(opcZip *zip, opc_bool_t trim);
/**
Garbage collection on the passed \c zip archive. This will e.g. make deleted files available as free space.
*/
opc_error_t opcZipGC(opcZip *zip);
/**
Load segment information into \c info.
If \c rels_segment is -1 then load the info for part with name \c partName.
Otherwise load the segment information for the ".rels." segment of \c partName.
\return Returns the segment_id.
*/
opc_uint32_t opcZipLoadSegment(opcZip *zip, const xmlChar *partName, opc_bool_t rels_segment, opcZipSegmentInfo_t *info);
/**
Create a segment with the given parameters.
\return Returns the segment_id.
*/
opc_uint32_t opcZipCreateSegment(opcZip *zip,
const xmlChar *partName,
opc_bool_t relsSegment,
opc_uint32_t segment_size,
opc_uint32_t growth_hint,
opc_uint16_t compression_method,
opc_uint16_t bit_flag);
/**
Creates an input stream for the segment with \c segment_id.
\see opcZipLoadSegment
\see opcZipCreateSegment
*/
opcZipInputStream *opcZipOpenInputStream(opcZip *zip, opc_uint32_t segment_id);
/**
Free all resources of the input stream.
*/
opc_error_t opcZipCloseInputStream(opcZip *zip, opcZipInputStream *stream);
/**
Read maximal \c buf_len bytes from the input stream into \buf.
\return Returns the number of bytes read.
*/
opc_uint32_t opcZipReadInputStream(opcZip *zip, opcZipInputStream *stream, opc_uint8_t *buf, opc_uint32_t buf_len);
/**
Creates an output stream for the segment with \c segment_id.
If \c *segment_id is -1 then a new segment will be created.
Otherwise the segment with \c *segment_id will be overwritten.
*/
opcZipOutputStream *opcZipCreateOutputStream(opcZip *zip,
opc_uint32_t *segment_id,
const xmlChar *partName,
opc_bool_t relsSegment,
opc_uint32_t segment_size,
opc_uint32_t growth_hint,
opc_uint16_t compression_method,
opc_uint16_t bit_flag);
/**
Opens an existing ouput stream for reading.
The \c *segment_id will be set to -1 and reset on opcZipCloseOutputStream.
\see opcZipCloseOutputStream
*/
opcZipOutputStream *opcZipOpenOutputStream(opcZip *zip, opc_uint32_t *segment_id);
/**
Will close the stream and free all resources. Additionally the new segment id will be stored in \c *segment_id.
\see opcZipOpenOutputStream
*/
opc_error_t opcZipCloseOutputStream(opcZip *zip, opcZipOutputStream *stream, opc_uint32_t *segment_id);
/**
Write \c buf_len bytes to \c buf.
\return Returns the number of bytes written.
*/
opc_uint32_t opcZipWriteOutputStream(opcZip *zip, opcZipOutputStream *stream, const opc_uint8_t *buf, opc_uint32_t buf_len);
/**
Returns the first segment id or -1.
Use the following code to iterarte through all segments.
\code
for(opc_uint32_t segment_id=opcZipGetFirstSegmentId(zip);
-1!=segment_id;
segment_id=opcZipGetNextSegmentId(zip, segment_id) {
...
}
\endcode
\see opcZipGetNextSegmentId
*/
opc_uint32_t opcZipGetFirstSegmentId(opcZip *zip);
/**
Returns the next segment id or -1.
\see opcZipGetFirstSegmentId
*/
opc_uint32_t opcZipGetNextSegmentId(opcZip *zip, opc_uint32_t segment_id);
/**
Returns info about the given segment id.
*/
opc_error_t opcZipGetSegmentInfo(opcZip *zip, opc_uint32_t segment_id, const xmlChar **name, opc_bool_t *rels_segment, opc_uint32_t *crc);
/**
Marks a given segments as deleted.
\see opcZipGC
*/
opc_bool_t opcZipSegmentDelete(opcZip *zip, opc_uint32_t *first_segment, opc_uint32_t *last_segment, opcZipSegmentReleaseCallback* releaseCallback);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* OPC_ZIP_H */