mirror of
https://github.com/simon987/sist2.git
synced 2025-04-20 10:46:45 +00:00
commit
5f7a1acfe3
@ -4,6 +4,8 @@ set(CMAKE_C_STANDARD 11)
|
|||||||
project(sist2 C)
|
project(sist2 C)
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules")
|
||||||
|
|
||||||
|
option(SIST_DEBUG "Build a debug executable" on)
|
||||||
|
|
||||||
add_executable(
|
add_executable(
|
||||||
sist2
|
sist2
|
||||||
src/main.c
|
src/main.c
|
||||||
@ -81,14 +83,40 @@ target_link_directories(
|
|||||||
${UUID_LIBRARY_DIRS}
|
${UUID_LIBRARY_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_options(sist2
|
target_compile_options(
|
||||||
|
sist2
|
||||||
PRIVATE
|
PRIVATE
|
||||||
-Ofast
|
|
||||||
# -march=native
|
|
||||||
-fPIC
|
-fPIC
|
||||||
-fno-stack-protector
|
)
|
||||||
-fomit-frame-pointer
|
|
||||||
)
|
if (SIST_DEBUG)
|
||||||
|
target_compile_options(
|
||||||
|
sist2
|
||||||
|
PRIVATE
|
||||||
|
-g
|
||||||
|
-fstack-protector
|
||||||
|
-fno-omit-frame-pointer
|
||||||
|
-fsanitize=address
|
||||||
|
)
|
||||||
|
target_link_options(
|
||||||
|
sist2
|
||||||
|
PRIVATE
|
||||||
|
-fsanitize=address
|
||||||
|
)
|
||||||
|
set_target_properties(
|
||||||
|
sist2
|
||||||
|
PROPERTIES
|
||||||
|
OUTPUT_NAME sist2_debug
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
target_compile_options(
|
||||||
|
sist2
|
||||||
|
PRIVATE
|
||||||
|
-Ofast
|
||||||
|
-fno-stack-protector
|
||||||
|
-fomit-frame-pointer
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES(
|
TARGET_LINK_LIBRARIES(
|
||||||
sist2
|
sist2
|
||||||
@ -115,16 +143,14 @@ TARGET_LINK_LIBRARIES(
|
|||||||
|
|
||||||
m
|
m
|
||||||
bz2
|
bz2
|
||||||
${PROJECT_SOURCE_DIR}/lib/libmagic.a
|
# ${PROJECT_SOURCE_DIR}/lib/libmagic.a
|
||||||
|
magic
|
||||||
${PROJECT_SOURCE_DIR}/lib/libharfbuzz.a
|
${PROJECT_SOURCE_DIR}/lib/libharfbuzz.a
|
||||||
${PROJECT_SOURCE_DIR}/lib/libopenjp2.a
|
${PROJECT_SOURCE_DIR}/lib/libopenjp2.a
|
||||||
freetype
|
freetype
|
||||||
archive
|
archive
|
||||||
|
|
||||||
xml2
|
xml2
|
||||||
${PROJECT_SOURCE_DIR}/lib/libopc/libmce.a
|
|
||||||
${PROJECT_SOURCE_DIR}/lib/libopc/libopc.a
|
|
||||||
${PROJECT_SOURCE_DIR}/lib/libopc/libplib.a
|
|
||||||
|
|
||||||
${PROJECT_SOURCE_DIR}/lib/libtesseract.a
|
${PROJECT_SOURCE_DIR}/lib/libtesseract.a
|
||||||
${PROJECT_SOURCE_DIR}/lib/liblept.a
|
${PROJECT_SOURCE_DIR}/lib/liblept.a
|
||||||
|
@ -123,7 +123,7 @@ binaries.
|
|||||||
libssl-dev uuid-dev python3 libmagic-dev libfreetype6-dev \
|
libssl-dev uuid-dev python3 libmagic-dev libfreetype6-dev \
|
||||||
libcurl4-openssl-dev libbz2-dev yasm libharfbuzz-dev ragel \
|
libcurl4-openssl-dev libbz2-dev yasm libharfbuzz-dev ragel \
|
||||||
libarchive-dev libtiff5 libpng16-16 libpango1.0-dev \
|
libarchive-dev libtiff5 libpng16-16 libpango1.0-dev \
|
||||||
libxml2-dev
|
libxml2-dev libopenjp2-7-dev libleptonica-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Build
|
2. Build
|
||||||
|
2
argparse
2
argparse
@ -1 +1 @@
|
|||||||
Subproject commit fafc503d23d077bda40c29e8a20ea74707452721
|
Subproject commit 4ed6099cb33245b06343518b9f3c45ac56e8283c
|
2
cJSON
2
cJSON
@ -1 +1 @@
|
|||||||
Subproject commit 2d4ad841927590198ecfb8b27335a0cd97cf15c1
|
Subproject commit e8077d01500279a7b45b8cd7a0ae94ea7ad5748a
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
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/mce/config.h
|
|
||||||
*/
|
|
||||||
#ifndef MCE_CONFIG_H
|
|
||||||
#define MCE_CONFIG_H
|
|
||||||
|
|
||||||
#include <libxml/xmlstring.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <plib/plib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MCE_NAMESPACE_SUBSUMPTION_ENABLED 0
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MCE_CONFIG_H */
|
|
@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
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 mce/helper.h
|
|
||||||
Helper functions needed by mce/textreader.h and mce/textwriter.h to implement MCE:
|
|
||||||
- mceQNameLevelAdd(), mceQNameLevelLookup() and mceQNameLevelCleanup() maintain a set of mceQNameLevel_t tuples.
|
|
||||||
- mceQNameLevelPush() and mceQNameLevelPopIfMatch() maintain a stack of mceQNameLevel_t tuples.
|
|
||||||
- mceCtxInit(), mceCtxCleanup() and mceCtxUnderstandsNamespace() manage a context which holds all information needed to do MCE proprocessing.
|
|
||||||
*/
|
|
||||||
#include <mce/config.h>
|
|
||||||
|
|
||||||
#ifndef MCE_HELPER_H
|
|
||||||
#define MCE_HELPER_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Tiple (ns, ln, level).
|
|
||||||
*/
|
|
||||||
typedef struct MCE_QNAME_LEVEL {
|
|
||||||
xmlChar *ns;
|
|
||||||
xmlChar *ln;
|
|
||||||
puint32_t level;
|
|
||||||
puint32_t flag; // used by mceTextWriter
|
|
||||||
} mceQNameLevel_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
typedef enum MCE_SKIP_STATE_ENUM {
|
|
||||||
MCE_SKIP_STATE_IGNORE,
|
|
||||||
MCE_SKIP_STATE_ALTERNATE_CONTENT,
|
|
||||||
MCE_SKIP_STATE_CHOICE_MATCHED
|
|
||||||
} mceSkipState_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Represents an intervall of levels which are "skipped" i.e. ignored.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_SKIP_ITEM {
|
|
||||||
puint32_t level_start;
|
|
||||||
puint32_t level_end;
|
|
||||||
mceSkipState_t state;
|
|
||||||
} mceSkipItem_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Either represents a set of (ns, ln, level) triples.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_QNAME_LEVEL_SET {
|
|
||||||
mceQNameLevel_t *list_array;
|
|
||||||
puint32_t list_items;
|
|
||||||
puint32_t max_level;
|
|
||||||
} mceQNameLevelSet_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
The skip stack.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_SKIP_STACK {
|
|
||||||
mceSkipItem_t *stack_array;
|
|
||||||
puint32_t stack_items;
|
|
||||||
} mceSkipStack_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum MCE_ERROR_ENUM {
|
|
||||||
MCE_ERROR_NONE,
|
|
||||||
MCE_ERROR_XML,
|
|
||||||
MCE_ERROR_MUST_UNDERSTAND,
|
|
||||||
MCE_ERROR_VALIDATION,
|
|
||||||
MCE_ERROR_MEMORY
|
|
||||||
} mceError_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Holds all information to do MCE preprocessing.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_CONTEXT {
|
|
||||||
mceQNameLevelSet_t ignorable_set;
|
|
||||||
mceQNameLevelSet_t understands_set;
|
|
||||||
mceQNameLevelSet_t processcontent_set;
|
|
||||||
mceQNameLevelSet_t suspended_set;
|
|
||||||
#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
|
|
||||||
mceQNameLevelSet_t subsume_namespace_set;
|
|
||||||
mceQNameLevelSet_t subsume_exclude_set;
|
|
||||||
mceQNameLevelSet_t subsume_prefix_set;
|
|
||||||
#endif
|
|
||||||
mceSkipStack_t skip_stack;
|
|
||||||
mceError_t error;
|
|
||||||
pbool_t mce_disabled;
|
|
||||||
puint32_t suspended_level;
|
|
||||||
} mceCtx_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Add a new tiple (ns, ln, level) to the triple set \c qname_level_set.
|
|
||||||
The \c ns_sub string is optional and will not be touched.
|
|
||||||
*/
|
|
||||||
pbool_t mceQNameLevelAdd(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t level);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Lookup a tiple (ns, ln, level) via \c ns and \c ln. If \c ignore_ln is PTRUE then the first tiple matching \c ns will be returned.
|
|
||||||
*/
|
|
||||||
mceQNameLevel_t* mceQNameLevelLookup(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, pbool_t ignore_ln);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Remove all triples (ns, ln, level) where the level greater or equal to \c level.
|
|
||||||
*/
|
|
||||||
pbool_t mceQNameLevelCleanup(mceQNameLevelSet_t *qname_level_set, puint32_t level);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Push a new skip intervall (level_start, level_end, state) on the stack \c skip_stack.
|
|
||||||
*/
|
|
||||||
pbool_t mceSkipStackPush(mceSkipStack_t *skip_stack, puint32_t level_start, puint32_t level_end, mceSkipState_t state);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Pop the intervall (ns, ln, level) from the stack \c qname_level_array.
|
|
||||||
*/
|
|
||||||
void mceSkipStackPop(mceSkipStack_t *skip_stack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns top item or NULL.
|
|
||||||
*/
|
|
||||||
mceSkipItem_t *mceSkipStackTop(mceSkipStack_t *skip_stack);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns TRUE, if the \c level is in the top skip intervall.
|
|
||||||
*/
|
|
||||||
pbool_t mceSkipStackSkip(mceSkipStack_t *skip_stack, puint32_t level);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Initialize the mceCtx_t \c ctx.
|
|
||||||
*/
|
|
||||||
pbool_t mceCtxInit(mceCtx_t *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Cleanup, i.e. release all resourced from the mceCtx_t \c ctx.
|
|
||||||
*/
|
|
||||||
pbool_t mceCtxCleanup(mceCtx_t *ctx);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Register the namespace \ns in \c ctx.
|
|
||||||
*/
|
|
||||||
pbool_t mceCtxUnderstandsNamespace(mceCtx_t *ctx, const xmlChar *ns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Register the namespace \ns in \c ctx.
|
|
||||||
*/
|
|
||||||
pbool_t mceCtxSuspendProcessing(mceCtx_t *ctx, const xmlChar *ns, const xmlChar *ln);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
|
|
||||||
/**
|
|
||||||
Subsume namespace \c ns_new with \c ns_old.
|
|
||||||
*/
|
|
||||||
pbool_t mceCtxSubsumeNamespace(mceCtx_t *ctx, const xmlChar *prefix_new, const xmlChar *ns_new, const xmlChar *ns_old);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MCE_HELPER_H */
|
|
@ -1,464 +0,0 @@
|
|||||||
/*
|
|
||||||
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 mce/textreader.h
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef MCE_TEXTREADER_H
|
|
||||||
#define MCE_TEXTREADER_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
A handle to an MCE-aware libxml2 xmlTextReader.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_TEXTREADER mceTextReader_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <mce/config.h>
|
|
||||||
#include <opc/opc.h>
|
|
||||||
#include <mce/helper.h>
|
|
||||||
#include <libxml/xmlwriter.h>
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct MCE_TEXTREADER {
|
|
||||||
xmlTextReaderPtr reader;
|
|
||||||
mceCtx_t mceCtx;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Wrapper around an libxml2 xmlTextReaderRead function.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderRead
|
|
||||||
*/
|
|
||||||
int mceTextReaderRead(mceTextReader_t *mceTextReader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Wrapper around a libxml2 xmlTextReaderNext function.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderNext
|
|
||||||
*/
|
|
||||||
int mceTextReaderNext(mceTextReader_t *mceTextReader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Creates an mceTextReader from an XmlTextReader.
|
|
||||||
\code
|
|
||||||
mceTextReader reader;
|
|
||||||
mceTextReaderInit(&reader, xmlNewTextReaderFilename("sample.xml"));
|
|
||||||
// reader is ready to use.
|
|
||||||
mceTextReaderCleanup(&reader);
|
|
||||||
\endcode
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlreader.html#xmlNewTextReaderFilename
|
|
||||||
*/
|
|
||||||
int mceTextReaderInit(mceTextReader_t *mceTextReader, xmlTextReaderPtr reader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Cleanup MCE reader, i.e. free all resources. Also calls xmlTextReaderClose and xmlFreeTextReader.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlreader.html#xmlTextReaderClose
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlreader.html#xmlFreeTextReader
|
|
||||||
*/
|
|
||||||
int mceTextReaderCleanup(mceTextReader_t *mceTextReader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Reads all events \c mceTextReader and pipes them to \writer.
|
|
||||||
\code
|
|
||||||
mceTextReader reader;
|
|
||||||
mceTextReaderInit(&reader, xmlNewTextReaderFilename("sample.xml"));
|
|
||||||
mceTextReaderUnderstandsNamespace(&reader, _X("http://myextension"));
|
|
||||||
xmlTextWriterPtr writer=xmlNewTextWriterFilename("out.xml", 0);
|
|
||||||
mceTextReaderDump(&reader, writer, P_FALSE);
|
|
||||||
xmlFreeTextWriter(writer);
|
|
||||||
mceTextReaderCleanup(&reader);
|
|
||||||
\endcode
|
|
||||||
*/
|
|
||||||
int mceTextReaderDump(mceTextReader_t *mceTextReader, xmlTextWriter *writer, pbool_t fragment);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Registers an MCE namespace.
|
|
||||||
\see mceTextReaderDump()
|
|
||||||
*/
|
|
||||||
int mceTextReaderUnderstandsNamespace(mceTextReader_t *mceTextReader, const xmlChar *ns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Disable MCE processing.
|
|
||||||
\return Returns old value.
|
|
||||||
*/
|
|
||||||
pbool_t mceTextReaderDisableMCE(mceTextReader_t *mceTextReader, pbool_t flag);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Signal an error to the MCE processor.
|
|
||||||
*/
|
|
||||||
void mceRaiseError(xmlTextReader *reader, mceCtx_t *ctx, mceError_t error, const xmlChar *str, ...);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Internal function which does the MCE postprocessing. E.g. mceTextReaderRead() is implemented as
|
|
||||||
\code
|
|
||||||
mceTextReaderPostprocess(mceTextReader->reader, &mceTextReader->mceCtx, xmlTextReaderRead(mceTextReader->reader))
|
|
||||||
\endcode
|
|
||||||
This function is exposed to make existing libxm2 xmlTextReader MCE aware.
|
|
||||||
*/
|
|
||||||
int mceTextReaderPostprocess(xmlTextReader *reader, mceCtx_t *ctx, int ret);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Get the error code.
|
|
||||||
*/
|
|
||||||
mceError_t mceTextReaderGetError(mceTextReader_t *mceTextReader);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper macro to declare a start/end document block in a declarative way:
|
|
||||||
\code
|
|
||||||
mce_start_document(reader) {
|
|
||||||
} mce_end_document(reader);
|
|
||||||
\endcode
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_document(_reader_) \
|
|
||||||
if (NULL!=(_reader_)) { \
|
|
||||||
mceTextReaderRead(_reader_); \
|
|
||||||
if (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_document.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_document(_reader_) \
|
|
||||||
} /* if (NULL!=reader) */ \
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Container for mce_start_element and mce_start_attribute declarations.
|
|
||||||
\see mce_match_element
|
|
||||||
\see mce_match_attribute
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_choice(_reader_) \
|
|
||||||
if (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_choice
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_choice(_reader_)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Skips the attributes.
|
|
||||||
\see mce_match_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_skip_attributes(_reader_) \
|
|
||||||
mce_start_attributes(_reader_) { \
|
|
||||||
} mce_end_attributes(_reader_);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Skips the attributes.
|
|
||||||
\see mce_match_attribute.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_skip_children(_reader_) \
|
|
||||||
mce_start_children(_reader_) { \
|
|
||||||
} mce_end_children(_reader_);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_children(_reader_) \
|
|
||||||
if (!xmlTextReaderIsEmptyElement((_reader_)->reader)) { \
|
|
||||||
mceTextReaderRead(_reader_); do { \
|
|
||||||
if (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_children(_reader_) \
|
|
||||||
else { \
|
|
||||||
if (XML_READER_TYPE_END_ELEMENT!=xmlTextReaderNodeType((_reader_)->reader)) { \
|
|
||||||
mceTextReaderNext(_reader_); /*skip unhandled element */ \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while(XML_READER_TYPE_END_ELEMENT!=xmlTextReaderNodeType((_reader_)->reader) && \
|
|
||||||
XML_READER_TYPE_NONE!=xmlTextReaderNodeType((_reader_)->reader)); \
|
|
||||||
} /* if (!xmlTextReaderIsEmptyElement(reader->reader)) */
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper macro to match an element. Usefull for calling code in a seperate function:
|
|
||||||
|
|
||||||
\code
|
|
||||||
void handleElement(reader) {
|
|
||||||
mce_start_choice(reader) {
|
|
||||||
mce_start_element(reader, _X("ns"), _X("element")) {
|
|
||||||
|
|
||||||
} mce_end_element(reader)
|
|
||||||
} mce_end_choice(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse(reader) {
|
|
||||||
mce_start_document(reader) {
|
|
||||||
mce_start_element(reader, _X("ns"), _X("ln")) {
|
|
||||||
mce_skip_attributes(reader);
|
|
||||||
mce_start_children(reader) {
|
|
||||||
mce_match_element(reader, _X("ns"), _X("element")) {
|
|
||||||
handleElement(reader);
|
|
||||||
}
|
|
||||||
} mce_end_children(reader);
|
|
||||||
} mce_end_element();
|
|
||||||
} mce_end_document(reader);
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_match_element(_reader_, ns, ln) \
|
|
||||||
} else if (XML_READER_TYPE_ELEMENT==xmlTextReaderNodeType((_reader_)->reader) \
|
|
||||||
&& (NULL==ns || 0==xmlStrcmp(ns, xmlTextReaderConstNamespaceUri((_reader_)->reader))) \
|
|
||||||
&& (NULL==ln || 0==xmlStrcmp(ln, xmlTextReaderConstLocalName((_reader_)->reader)))) {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper macro to declare a element block in a declarative way:
|
|
||||||
\code
|
|
||||||
mce_start_element(reader) {
|
|
||||||
mce_start_attributes(reader) {
|
|
||||||
mce_start_attribute(reader, _X("ns"), _X("lnA")) {
|
|
||||||
// code for handling lnA.
|
|
||||||
} mce_end_attribute(reader);
|
|
||||||
mce_start_attribute(reader, _X("ns"), _X("lnB")) {
|
|
||||||
// code for handling lnB.
|
|
||||||
} mce_end_attribute(reader);
|
|
||||||
} mce_end_attributes(reader);
|
|
||||||
mce_start_children(reader) {
|
|
||||||
mce_start_element(reader, _X("ns"), _X("lnA")) {
|
|
||||||
// code for handling lnA.
|
|
||||||
} mce_end_element(reader);
|
|
||||||
mce_start_element(reader, _X("ns"), _X("lnB")) {
|
|
||||||
// code for handling lnB.
|
|
||||||
} mce_end_element(reader);
|
|
||||||
mce_start_text(reader) {
|
|
||||||
// code for handling text.
|
|
||||||
} mce_end_text(reader);
|
|
||||||
} mce_end_children(reader);
|
|
||||||
} mce_end_element(reader);
|
|
||||||
\endcode
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_element(_reader_, ns, ln) \
|
|
||||||
mce_match_element(_reader_, ns, ln)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_element(_reader_) \
|
|
||||||
mceTextReaderNext(_reader_)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Matches #TEXT without consuming it.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_match_text(_reader_) \
|
|
||||||
} else if (XML_READER_TYPE_TEXT==xmlTextReaderNodeType((_reader_)->reader) \
|
|
||||||
|| XML_READER_TYPE_SIGNIFICANT_WHITESPACE==xmlTextReaderNodeType((_reader_)->reader)) {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_text(_reader_) \
|
|
||||||
mce_match_text(_reader_)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_text(_reader_) \
|
|
||||||
mceTextReaderNext(_reader_)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_attributes(_reader_) \
|
|
||||||
if (1==xmlTextReaderMoveToFirstAttribute((_reader_)->reader)) { \
|
|
||||||
do { \
|
|
||||||
if (0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_attributes(_reader_) \
|
|
||||||
else { /* skipped attribute */ } \
|
|
||||||
} while(1==xmlTextReaderMoveToNextAttribute((_reader_)->reader)); \
|
|
||||||
xmlTextReaderMoveToElement((_reader_)->reader); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper macro to match an attribute. Usefull for calling code in a seperate function:
|
|
||||||
|
|
||||||
\code
|
|
||||||
void handleA(reader) {
|
|
||||||
mce_start_choice(reader) {
|
|
||||||
mce_start_attribute(reader, _X("ns"), _X("attr")) {
|
|
||||||
|
|
||||||
} mce_end_attribute(reader);
|
|
||||||
} mce_end_choice(reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse(reader) {
|
|
||||||
mce_start_document(reader) {
|
|
||||||
mce_start_element(reader, _X("ns"), _X("ln")) {
|
|
||||||
mce_start_attributes(reader) {
|
|
||||||
mce_match_attribute(reader, _X("ns"), _X("attr")) {
|
|
||||||
handleA(reader);
|
|
||||||
}
|
|
||||||
} mce_end_attributes(reader);
|
|
||||||
mce_skip_children(reader);
|
|
||||||
} mce_end_element();
|
|
||||||
} mce_end_document(reader);
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_match_attribute(_reader_, ns, ln) \
|
|
||||||
} else if ((NULL==ns || 0==xmlStrcmp(ns, xmlTextReaderConstNamespaceUri((_reader_)->reader))) \
|
|
||||||
&& (NULL==ln || 0==xmlStrcmp(ln, xmlTextReaderConstLocalName((_reader_)->reader)))) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_start_attribute(_reader_, ns, ln) \
|
|
||||||
mce_match_attribute(_reader_, ns, ln)
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_start_element.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_end_attribute(_reader_)
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Error handling for MCE parsers.
|
|
||||||
\code
|
|
||||||
mce_start_element(&reader, NULL, _X("Default")) {
|
|
||||||
const xmlChar *ext=NULL;
|
|
||||||
const xmlChar *type=NULL;
|
|
||||||
mce_start_attributes(&reader) {
|
|
||||||
mce_start_attribute(&reader, NULL, _X("Extension")) {
|
|
||||||
ext=xmlTextReaderConstValue(reader.reader);
|
|
||||||
} mce_end_attribute(&reader);
|
|
||||||
mce_start_attribute(&reader, NULL, _X("ContentType")) {
|
|
||||||
type=xmlTextReaderConstValue(reader.reader);
|
|
||||||
} mce_end_attribute(&reader);
|
|
||||||
} mce_end_attributes(&reader);
|
|
||||||
mce_error_guard_start(&reader) {
|
|
||||||
mce_error(&reader, NULL==ext || ext[0]==0, MCE_ERROR_VALIDATION, "Missing @Extension attribute!");
|
|
||||||
mce_error(&reader, NULL==type || type[0]==0, MCE_ERROR_VALIDATION, "Missing @ContentType attribute!");
|
|
||||||
opcContainerType *ct=insertType(c, type, OPC_TRUE);
|
|
||||||
mce_error(&reader, NULL==ct, MCE_ERROR_MEMORY, NULL);
|
|
||||||
opcContainerExtension *ce=opcContainerInsertExtension(c, ext, OPC_TRUE);
|
|
||||||
mce_error(&reader, NULL==ce, MCE_ERROR_MEMORY, NULL);
|
|
||||||
mce_errorf(&reader, NULL!=ce->type && 0!=xmlStrcmp(ce->type, type), MCE_ERROR_VALIDATION, "Extension \"%s\" is mapped to type \"%s\" as well as \"%s\"", ext, type, ce->type);
|
|
||||||
ce->type=ct->type;
|
|
||||||
} mce_error_guard_end(&reader);
|
|
||||||
mce_skip_children(&reader);
|
|
||||||
} mce_end_element(&reader);
|
|
||||||
\endcode
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_error_guard_start(_reader_) if (MCE_ERROR_NONE==(_reader_)->mceCtx.error) do {
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_error_guard_start
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_error_guard_end(_reader_) } while(0)
|
|
||||||
|
|
||||||
/**
|
|
||||||
Signal an error if guard if false.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_error(_reader_, guard, err, msg) if (guard) { (_reader_)->mceCtx.error=(err); fprintf(stderr, (NULL!=msg?msg:#err)); continue; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
Signal an error if guard if false.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
#define mce_errorf(_reader_, guard, err, msg, ...) if (guard) { mceRaiseError((_reader_)->reader, &(_reader_)->mceCtx, err, _X((NULL!=msg?msg:#err)), ##__VA_ARGS__ ); continue; }
|
|
||||||
#else
|
|
||||||
#define mce_errorf(_reader_, guard, err, msg, ...) if (guard) { mceRaiseError((_reader_)->reader, &(_reader_)->mceCtx, err, _X((NULL!=msg?msg:#err)), __VA_ARGS__ ); continue; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Only issues the error when in "strict mode".
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_error_strict mce_error
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see mce_error_strict
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_error_strictf mce_errorf
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Marker for a MCE defintion.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_def
|
|
||||||
|
|
||||||
/**
|
|
||||||
Marker for a MCE reference.
|
|
||||||
\hideinitializer
|
|
||||||
*/
|
|
||||||
#define mce_ref(r) (r)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MCE_TEXTREADER_H */
|
|
@ -1,176 +0,0 @@
|
|||||||
/*
|
|
||||||
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 mce/textwriter.h
|
|
||||||
|
|
||||||
*/
|
|
||||||
#include <mce/config.h>
|
|
||||||
#include <libxml/xmlwriter.h>
|
|
||||||
#include <mce/helper.h>
|
|
||||||
|
|
||||||
#ifndef MCE_TEXTWRITER_H
|
|
||||||
#define MCE_TEXTWRITER_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Default flags for an MCE namespace declaration.
|
|
||||||
*/
|
|
||||||
#define MCE_DEFAULT 0x0
|
|
||||||
|
|
||||||
/**
|
|
||||||
Flags MCE namespace declaration "ignorable".
|
|
||||||
*/
|
|
||||||
#define MCE_IGNORABLE 0x1
|
|
||||||
|
|
||||||
/**
|
|
||||||
Flags MCE namespace declaration "must understand".
|
|
||||||
*/
|
|
||||||
#define MCE_MUSTUNDERSTAND 0x2
|
|
||||||
|
|
||||||
/**
|
|
||||||
The MCE text writer context.
|
|
||||||
*/
|
|
||||||
typedef struct MCE_TEXTWRITER_STRUCT mceTextWriter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Create a new MCE text writer.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlIO.html#xmlOutputBufferCreateIO
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlNewTextWriter
|
|
||||||
*/
|
|
||||||
mceTextWriter *mceTextWriterCreateIO(xmlOutputWriteCallback iowrite, xmlOutputCloseCallback ioclose, void *ioctx, xmlCharEncodingHandlerPtr encoder);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper which create a new MCE text writer for a FILE handle.
|
|
||||||
*/
|
|
||||||
mceTextWriter *mceNewTextWriterFile(FILE *file);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Free all resources for \w.
|
|
||||||
*/
|
|
||||||
int mceTextWriterFree(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartDocument
|
|
||||||
*/
|
|
||||||
int mceTextWriterStartDocument(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterEndDocument
|
|
||||||
*/
|
|
||||||
int mceTextWriterEndDocument(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start a new XML element. If ns==NULL then there is no namespace and ""==ns means the default namespace.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartElement
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterStartElementNS
|
|
||||||
*/
|
|
||||||
int mceTextWriterStartElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterEndElement
|
|
||||||
*/
|
|
||||||
int mceTextWriterEndElement(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
|
|
||||||
|
|
||||||
/**
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterWriteString
|
|
||||||
*/
|
|
||||||
int mceTextWriterWriteString(mceTextWriter *w, const xmlChar *content);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Register a namespace. Must be called before mceTextWriterStartElement.
|
|
||||||
\see MCE_DEFAULT
|
|
||||||
\see MCE_IGNORABLE
|
|
||||||
\see MCE_MUSTUNDERSTAND
|
|
||||||
*/
|
|
||||||
const xmlChar *mceTextWriterRegisterNamespace(mceTextWriter *w, const xmlChar *ns, const xmlChar *prefix, int flags);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Register qname (ns, ln) as a "process content" element wrt. MCE. Must be called before mceTextWriterStartElement.
|
|
||||||
*/
|
|
||||||
int mceTextWriterProcessContent(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Writes a formatted attribute.
|
|
||||||
\see http://xmlsoft.org/html/libxml-xmlwriter.html#xmlTextWriterWriteFormatAttribute
|
|
||||||
*/
|
|
||||||
int mceTextWriterAttributeF(mceTextWriter *w, const xmlChar *ns, const xmlChar *ln, const char *value, ...);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Starts an MCE alternate content section.
|
|
||||||
*/
|
|
||||||
int mceTextWriterStartAlternateContent(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ends an MCE alternate content section.
|
|
||||||
*/
|
|
||||||
int mceTextWriterEndAlternateContent(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start an MCE choice.
|
|
||||||
*/
|
|
||||||
int mceTextWriterStartChoice(mceTextWriter *w, const xmlChar *ns);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ends an MCE choice.
|
|
||||||
*/
|
|
||||||
int mceTextWriterEndChoice(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Start an MCE fallback.
|
|
||||||
*/
|
|
||||||
int mceTextWriterStartFallback(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Ends an MCE fallback.
|
|
||||||
*/
|
|
||||||
int mceTextWriterEndFallback(mceTextWriter *w);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Returns the underlying xmlTextWriter.
|
|
||||||
*/
|
|
||||||
xmlTextWriterPtr mceTextWriterIntern(mceTextWriter *w);
|
|
||||||
|
|
||||||
/**
|
|
||||||
Helper which create a new xmlTextWriterPtr for a FILE handle.
|
|
||||||
*/
|
|
||||||
xmlTextWriterPtr xmlNewTextWriterFile(FILE *file);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* MCE_TEXTWRITER_H */
|
|
@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,300 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,200 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,73 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,255 +0,0 @@
|
|||||||
/*
|
|
||||||
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 */
|
|
@ -1,168 +0,0 @@
|
|||||||
/* include/plib/plib.h. Generated from plib.h by configure. */
|
|
||||||
/*
|
|
||||||
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.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef _PLIB_PLIB_H_
|
|
||||||
#define _PLIB_PLIB_H_
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HAVE_STDINT_H 1
|
|
||||||
#define HAVE_STDDEF_H 1
|
|
||||||
#define HAVE_STDIO_H 1
|
|
||||||
#define HAVE_STRING_H 1
|
|
||||||
#define HAVE_LIMITS_H 1
|
|
||||||
#define HAVE_STDLIB_H 1
|
|
||||||
/* #undef HAVE_IO_H */
|
|
||||||
#define HAVE_UNISTD_H 1
|
|
||||||
#define HAVE_SYS_TYPES_H 1
|
|
||||||
#define IS_CONFIGURED 1
|
|
||||||
|
|
||||||
#if !defined(IS_CONFIGURED)
|
|
||||||
#if defined(WIN32)
|
|
||||||
#define HAVE_STRING_H 1
|
|
||||||
#define HAVE_STDINT_H 1
|
|
||||||
#define HAVE_LIMITS_H 1
|
|
||||||
#define HAVE_STDDEF_H 1
|
|
||||||
#define HAVE_STDIO_H 1
|
|
||||||
#define HAVE_STDLIB_H 1
|
|
||||||
#define HAVE_IO_H
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#else
|
|
||||||
#error "configure not executed and we are not on a win32 machine? please run configure or define WIN32 is you are on a WIN32 platform."
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDDEF_H
|
|
||||||
#include <stddef.h>
|
|
||||||
typedef size_t pofs_t; // maximum file offset for eg. read write ops
|
|
||||||
#else
|
|
||||||
#error "system types can not be determined"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDIO_H
|
|
||||||
#include <stdio.h>
|
|
||||||
#else
|
|
||||||
#error "system io can not be determined"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDINT_H
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef int8_t pint8_t;
|
|
||||||
typedef uint8_t puint8_t;
|
|
||||||
|
|
||||||
typedef int16_t pint16_t;
|
|
||||||
typedef uint16_t puint16_t;
|
|
||||||
|
|
||||||
typedef int32_t pint32_t;
|
|
||||||
typedef uint32_t puint32_t;
|
|
||||||
|
|
||||||
typedef int64_t pint64_t;
|
|
||||||
typedef uint64_t puint64_t;
|
|
||||||
|
|
||||||
typedef int pbool_t;
|
|
||||||
|
|
||||||
typedef size_t psize_t;
|
|
||||||
|
|
||||||
// INTN_MAX, INTN_MIN, UINTN_MAX
|
|
||||||
#else
|
|
||||||
#error "system types can not be determined"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STRING_H
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_LIMITS_H
|
|
||||||
#include <limits.h>
|
|
||||||
#define PUINT8_MAX UCHAR_MAX
|
|
||||||
#define PINT32_MAX INT_MAX
|
|
||||||
#define PINT32_MIN INT_MIN
|
|
||||||
#define PUINT32_MAX UINT_MAX
|
|
||||||
#define PUINT32_MIN 0
|
|
||||||
#define PUINT16_MAX USHRT_MAX
|
|
||||||
#define PUINT16_MIN 0
|
|
||||||
#else
|
|
||||||
#error "limits can not be determined"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_IO_H
|
|
||||||
#include <io.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
#include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
Converts an ASCII string to a xmlChar string. This only works for ASCII strings.
|
|
||||||
*/
|
|
||||||
#ifndef _X
|
|
||||||
#define _X(s) BAD_CAST(s)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
Converts an xmlChar string to an ASCII string. This only works for ASCII charsets.
|
|
||||||
*/
|
|
||||||
#ifndef _X2C
|
|
||||||
#define _X2C(s) ((char*)(s))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define PASSERT(e) assert(e)
|
|
||||||
#ifdef NDEBUG
|
|
||||||
#define PENSURE(e) (void)(e)
|
|
||||||
#else
|
|
||||||
#define PENSURE(e) assert(e)
|
|
||||||
#endif
|
|
||||||
#define PTRUE (0==0)
|
|
||||||
#define PFALSE (0==1)
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* _PLIB_PLIB_H_ */
|
|
@ -1 +1 @@
|
|||||||
Subproject commit 8887991a3109f94b7d019a11a86e6cd900105258
|
Subproject commit e27a35e0458224ef6f47753f248ba84ec8284818
|
@ -1 +1 @@
|
|||||||
Subproject commit b28c282585afd3bff844e84eae7f29e1a1267aef
|
Subproject commit b7617f6b3cfa0abf10292ea79bcd53ef61a08e90
|
@ -1 +1 @@
|
|||||||
Subproject commit cc03be70fded1ad6a8cedad656456386a1bd08e8
|
Subproject commit 320b4bbb025db7f8c68d3c2b0b9d9fad459c7af3
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
|||||||
Subproject commit 3db0ff91bc6db20fc4cb035be366a9bbb4e701cf
|
Subproject commit a6d3c1d64b655f5f151a01fda2b7b0bf50cc61aa
|
@ -1 +1 @@
|
|||||||
Subproject commit c50ac19e412fe7830dfef5d1cbc71e9da3405c96
|
Subproject commit 1e1ac03fe4c8bfd9022d945b05e0cc1343827399
|
@ -1 +1 @@
|
|||||||
Subproject commit 73329b61eb82d65b827e92ab46b2db7da85163c7
|
Subproject commit 2b3b230b79ecae119b7eb847f2f9545a46bef13c
|
@ -1 +1 @@
|
|||||||
Subproject commit ac3737372a00b8778b528094dd5bd58a74f67d42
|
Subproject commit 563ecfb55ca77c0fc5ea19e4885e00f55ec82ca9
|
@ -1 +1 @@
|
|||||||
Subproject commit f268e6615e619a7140de78d9db3f8240fa8c68bd
|
Subproject commit 90405ad0e3bdb7b779d8edaf147bff496873f84b
|
@ -1,8 +1,6 @@
|
|||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "ctx.h"
|
#include "ctx.h"
|
||||||
|
|
||||||
#include <tesseract/capi.h>
|
|
||||||
|
|
||||||
#define DEFAULT_OUTPUT "index.sist2/"
|
#define DEFAULT_OUTPUT "index.sist2/"
|
||||||
#define DEFAULT_CONTENT_SIZE 32768
|
#define DEFAULT_CONTENT_SIZE 32768
|
||||||
#define DEFAULT_QUALITY 5
|
#define DEFAULT_QUALITY 5
|
||||||
@ -240,7 +238,7 @@ int index_args_validate(index_args_t *args, int argc, const char **argv) {
|
|||||||
|
|
||||||
args->script = malloc(info.st_size + 1);
|
args->script = malloc(info.st_size + 1);
|
||||||
res = read(fd, args->script, info.st_size);
|
res = read(fd, args->script, info.st_size);
|
||||||
if (res == -1) {
|
if (res < 0) {
|
||||||
fprintf(stderr, "Error reading script file '%s': %s\n", args->script_path, strerror(errno));
|
fprintf(stderr, "Error reading script file '%s': %s\n", args->script_path, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
#include "elastic.h"
|
#include "elastic.h"
|
||||||
#include "src/ctx.h"
|
#include "src/ctx.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "web.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <cJSON/cJSON.h>
|
|
||||||
|
|
||||||
#include "static_generated.c"
|
#include "static_generated.c"
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ void write_index_descriptor(char *path, index_descriptor_t *desc) {
|
|||||||
cJSON_AddNumberToObject(json, "timestamp", (double) desc->timestamp);
|
cJSON_AddNumberToObject(json, "timestamp", (double) desc->timestamp);
|
||||||
|
|
||||||
int fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
int fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||||
if (fd == -1) {
|
if (fd < 0) {
|
||||||
perror(path);
|
LOG_FATALF("serialize.c", "Could not write index descriptor: %s", strerror(errno));
|
||||||
}
|
}
|
||||||
char *str = cJSON_Print(json);
|
char *str = cJSON_Print(json);
|
||||||
write(fd, str, strlen(str));
|
write(fd, str, strlen(str));
|
||||||
@ -185,7 +185,7 @@ void write_document(document_t *doc) {
|
|||||||
|
|
||||||
int res = write(index_fd, buf.buf, buf.cur);
|
int res = write(index_fd, buf.buf, buf.cur);
|
||||||
if (res == -1) {
|
if (res == -1) {
|
||||||
perror("write");
|
LOG_FATALF("serialize.c", "Could not write document: %s", strerror(errno))
|
||||||
}
|
}
|
||||||
ScanCtx.stat_index_size += buf.cur;
|
ScanCtx.stat_index_size += buf.cur;
|
||||||
dyn_buffer_destroy(&buf);
|
dyn_buffer_destroy(&buf);
|
||||||
@ -334,7 +334,7 @@ void read_index_json(const char *path, UNUSED(const char *index_id), index_func
|
|||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
size_t len;
|
size_t len;
|
||||||
size_t read = getline(&line, &len, file);
|
size_t read = getline(&line, &len, file);
|
||||||
if (read == -1) {
|
if (read < 0) {
|
||||||
if (line) {
|
if (line) {
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,7 @@ store_t *store_create(char *path) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (open_ret != 0) {
|
if (open_ret != 0) {
|
||||||
fprintf(stderr, "Error while opening store: %s (%s)\n", mdb_strerror(open_ret), path);
|
LOG_FATALF("store.c", "Error while opening store: %s (%s)\n", mdb_strerror(open_ret), path)
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
store->size = (size_t) 1024 * 1024 * 5;
|
store->size = (size_t) 1024 * 1024 * 5;
|
||||||
@ -82,7 +81,7 @@ void store_write(store_t *store, char *key, size_t key_len, char *buf, size_t bu
|
|||||||
pthread_rwlock_unlock(&store->lock);
|
pthread_rwlock_unlock(&store->lock);
|
||||||
|
|
||||||
if (put_ret != 0) {
|
if (put_ret != 0) {
|
||||||
printf("%s\n", mdb_strerror(put_ret));
|
LOG_ERROR("store.c", mdb_strerror(put_ret))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
src/main.c
28
src/main.c
@ -6,7 +6,7 @@
|
|||||||
#define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0"
|
#define EPILOG "Made by simon987 <me@simon987.net>. Released under GPL-3.0"
|
||||||
|
|
||||||
|
|
||||||
static const char *const Version = "1.3.0";
|
static const char *const Version = "1.3.1";
|
||||||
static const char *const usage[] = {
|
static const char *const usage[] = {
|
||||||
"sist2 scan [OPTION]... PATH",
|
"sist2 scan [OPTION]... PATH",
|
||||||
"sist2 index [OPTION]... INDEX",
|
"sist2 index [OPTION]... INDEX",
|
||||||
@ -17,7 +17,6 @@ static const char *const usage[] = {
|
|||||||
void global_init() {
|
void global_init() {
|
||||||
curl_global_init(CURL_GLOBAL_NOTHING);
|
curl_global_init(CURL_GLOBAL_NOTHING);
|
||||||
av_log_set_level(AV_LOG_QUIET);
|
av_log_set_level(AV_LOG_QUIET);
|
||||||
opcInitLibrary();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_dir(const char *dirpath) {
|
void init_dir(const char *dirpath) {
|
||||||
@ -83,7 +82,8 @@ void sist2_scan(scan_args_t *args) {
|
|||||||
index_descriptor_t original_desc = read_index_descriptor(descriptor_path);
|
index_descriptor_t original_desc = read_index_descriptor(descriptor_path);
|
||||||
|
|
||||||
if (strcmp(original_desc.version, Version) != 0) {
|
if (strcmp(original_desc.version, Version) != 0) {
|
||||||
LOG_FATALF("main.c", "Version mismatch! Index is %s but executable is %s/%s", original_desc.version, Version, INDEX_VERSION_EXTERNAL)
|
LOG_FATALF("main.c", "Version mismatch! Index is %s but executable is %s/%s", original_desc.version,
|
||||||
|
Version, INDEX_VERSION_EXTERNAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@ -96,7 +96,7 @@ void sist2_scan(scan_args_t *args) {
|
|||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
|
|
||||||
printf("Loaded %d items in to mtime table.", g_hash_table_size(ScanCtx.original_table));
|
LOG_INFOF("main.c", "Loaded %d items in to mtime table.", g_hash_table_size(ScanCtx.original_table))
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanCtx.pool = tpool_create(args->threads, thread_cleanup);
|
ScanCtx.pool = tpool_create(args->threads, thread_cleanup);
|
||||||
@ -148,13 +148,13 @@ void sist2_index(index_args_t *args) {
|
|||||||
LOG_DEBUGF("main.c", "descriptor version %s (%s)", desc.version, desc.type)
|
LOG_DEBUGF("main.c", "descriptor version %s (%s)", desc.version, desc.type)
|
||||||
|
|
||||||
if (strcmp(desc.version, Version) != 0 && strcmp(desc.version, INDEX_VERSION_EXTERNAL) != 0) {
|
if (strcmp(desc.version, Version) != 0 && strcmp(desc.version, INDEX_VERSION_EXTERNAL) != 0) {
|
||||||
LOG_FATALF("main.c", "Version mismatch! Index is %s but executable is %s/%s", desc.version, Version, INDEX_VERSION_EXTERNAL)
|
LOG_FATALF("main.c", "Version mismatch! Index is %s but executable is %s/%s", desc.version, Version,
|
||||||
|
INDEX_VERSION_EXTERNAL)
|
||||||
}
|
}
|
||||||
|
|
||||||
DIR *dir = opendir(args->index_path);
|
DIR *dir = opendir(args->index_path);
|
||||||
if (dir == NULL) {
|
if (dir == NULL) {
|
||||||
perror("opendir");
|
LOG_FATALF("main.c", "Could not open index %s: %s", args->index_path, strerror(errno))
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
index_func f;
|
index_func f;
|
||||||
@ -274,7 +274,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
if (arg_version) {
|
if (arg_version) {
|
||||||
printf(Version);
|
printf(Version);
|
||||||
exit(0);
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (LogCtx.very_verbose != 0) {
|
if (LogCtx.very_verbose != 0) {
|
||||||
@ -286,12 +286,12 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
argparse_usage(&argparse);
|
argparse_usage(&argparse);
|
||||||
return 1;
|
goto end;
|
||||||
} else if (strcmp(argv[0], "scan") == 0) {
|
} else if (strcmp(argv[0], "scan") == 0) {
|
||||||
|
|
||||||
int err = scan_args_validate(scan_args, argc, argv);
|
int err = scan_args_validate(scan_args, argc, argv);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
goto end;
|
||||||
}
|
}
|
||||||
sist2_scan(scan_args);
|
sist2_scan(scan_args);
|
||||||
|
|
||||||
@ -299,7 +299,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
int err = index_args_validate(index_args, argc, argv);
|
int err = index_args_validate(index_args, argc, argv);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
goto end;
|
||||||
}
|
}
|
||||||
sist2_index(index_args);
|
sist2_index(index_args);
|
||||||
|
|
||||||
@ -307,19 +307,19 @@ int main(int argc, const char *argv[]) {
|
|||||||
|
|
||||||
int err = web_args_validate(web_args, argc, argv);
|
int err = web_args_validate(web_args, argc, argv);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
goto end;
|
||||||
}
|
}
|
||||||
sist2_web(web_args);
|
sist2_web(web_args);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Invalid command: '%s'\n", argv[0]);
|
fprintf(stderr, "Invalid command: '%s'\n", argv[0]);
|
||||||
argparse_usage(&argparse);
|
argparse_usage(&argparse);
|
||||||
return 1;
|
goto end;
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
end:
|
||||||
scan_args_destroy(scan_args);
|
scan_args_destroy(scan_args);
|
||||||
|
|
||||||
index_args_destroy(index_args);
|
index_args_destroy(index_args);
|
||||||
web_args_destroy(web_args);
|
web_args_destroy(web_args);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#import "cbr.h"
|
#include "cbr.h"
|
||||||
#import "src/ctx.h"
|
#include "src/ctx.h"
|
||||||
|
|
||||||
unsigned int cbr_mime;
|
unsigned int cbr_mime;
|
||||||
unsigned int cbz_mime;
|
unsigned int cbz_mime;
|
||||||
|
@ -1,10 +1,40 @@
|
|||||||
#include "doc.h"
|
#include "doc.h"
|
||||||
#include "src/ctx.h"
|
#include "src/ctx.h"
|
||||||
|
|
||||||
int dump_text(mceTextReader_t *reader, dyn_buffer_t *buf) {
|
|
||||||
|
|
||||||
mce_skip_attributes(reader);
|
#define STR_STARTS_WITH(x, y) (strncmp(y, x, sizeof(y) - 1) == 0)
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int should_read_part(const char *part) {
|
||||||
|
|
||||||
|
LOG_DEBUGF("doc.c", "Got part : %s", part)
|
||||||
|
|
||||||
|
if (part == NULL) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( // Word
|
||||||
|
STR_STARTS_WITH(part, "word/document.xml")
|
||||||
|
|| STR_STARTS_WITH(part, "word/footnotes.xml")
|
||||||
|
|| STR_STARTS_WITH(part, "word/endnotes.xml")
|
||||||
|
|| STR_STARTS_WITH(part, "word/footer")
|
||||||
|
|| STR_STARTS_WITH(part, "word/header")
|
||||||
|
// PowerPoint
|
||||||
|
|| STR_STARTS_WITH(part, "ppt/slides/slide")
|
||||||
|
|| STR_STARTS_WITH(part, "ppt/notesSlides/slide")
|
||||||
|
// Excel
|
||||||
|
|| STR_STARTS_WITH(part, "xl/worksheets/sheet")
|
||||||
|
|| STR_STARTS_WITH(part, "xl/sharedStrings.xml")
|
||||||
|
|| STR_STARTS_WITH(part, "xl/workbook.xml")
|
||||||
|
) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int extract_text(xmlDoc *xml, xmlNode *node, text_buffer_t *buf) {
|
||||||
|
//TODO: Check which nodes are likely to have a 't' child, and ignore nodes that aren't
|
||||||
xmlErrorPtr err = xmlGetLastError();
|
xmlErrorPtr err = xmlGetLastError();
|
||||||
if (err != NULL) {
|
if (err != NULL) {
|
||||||
if (err->level == XML_ERR_FATAL) {
|
if (err->level == XML_ERR_FATAL) {
|
||||||
@ -15,78 +45,51 @@ int dump_text(mceTextReader_t *reader, dyn_buffer_t *buf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mce_start_children(reader) {
|
for (xmlNode *child = node; child; child = child->next) {
|
||||||
mce_start_element(reader, NULL, _X("t")) {
|
if (*child->name == 't' && *(child->name + 1) == '\0') {
|
||||||
mce_skip_attributes(reader);
|
xmlChar *text = xmlNodeListGetString(xml, child->xmlChildrenNode, 1);
|
||||||
mce_start_children(reader) {
|
|
||||||
mce_start_text(reader) {
|
|
||||||
char *str = (char *) xmlTextReaderConstValue(reader->reader);
|
|
||||||
dyn_buffer_append_string(buf, str);
|
|
||||||
dyn_buffer_write_char(buf, ' ');
|
|
||||||
} mce_end_text(reader);
|
|
||||||
} mce_end_children(reader);
|
|
||||||
} mce_end_element(reader);
|
|
||||||
|
|
||||||
mce_start_element(reader, NULL, NULL) {
|
if (text) {
|
||||||
int ret = dump_text(reader, buf);
|
text_buffer_append_string0(buf, (char *) text);
|
||||||
if (ret != 0) {
|
text_buffer_append_char(buf, ' ');
|
||||||
return ret;
|
xmlFree(text);
|
||||||
}
|
}
|
||||||
} mce_end_element(reader);
|
}
|
||||||
|
|
||||||
} mce_end_children(reader)
|
extract_text(xml, child->children, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int xml_io_read(void *context, char *buffer, int len) {
|
||||||
|
struct archive *a = context;
|
||||||
|
return archive_read_data(a, buffer, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int xml_io_close(UNUSED(void *context)) {
|
||||||
|
//noop
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
int should_read_part(opcPart part) {
|
static int read_part(struct archive *a, text_buffer_t *buf, document_t *doc) {
|
||||||
|
|
||||||
char *part_name = (char *) part;
|
xmlDoc *xml = xmlReadIO(xml_io_read, xml_io_close, a, "/", NULL, XML_PARSE_RECOVER | XML_PARSE_NOWARNING | XML_PARSE_NOERROR | XML_PARSE_NONET);
|
||||||
|
|
||||||
if (part == NULL) {
|
if (xml == NULL) {
|
||||||
return FALSE;
|
LOG_ERROR(doc->filepath, "Could not parse XML")
|
||||||
}
|
|
||||||
|
|
||||||
if ( // Word
|
|
||||||
strcmp(part_name, "word/document.xml") == 0
|
|
||||||
|| strncmp(part_name, "word/footer", sizeof("word/footer") - 1) == 0
|
|
||||||
|| strncmp(part_name, "word/header", sizeof("word/header") - 1) == 0
|
|
||||||
// PowerPoint
|
|
||||||
|| strncmp(part_name, "ppt/slides/slide", sizeof("ppt/slides/slide") - 1) == 0
|
|
||||||
|| strncmp(part_name, "ppt/notesSlides/notesSlide", sizeof("ppt/notesSlides/notesSlide") - 1) == 0
|
|
||||||
// Excel
|
|
||||||
|| strncmp(part_name, "xl/worksheets/sheet", sizeof("xl/worksheets/sheet") - 1) == 0
|
|
||||||
|| strcmp(part_name, "xl/sharedStrings.xml") == 0
|
|
||||||
|| strcmp(part_name, "xl/workbook.xml") == 0
|
|
||||||
) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
__always_inline
|
|
||||||
int read_part(opcContainer *c, dyn_buffer_t *buf, opcPart part, document_t *doc) {
|
|
||||||
|
|
||||||
mceTextReader_t reader;
|
|
||||||
int ret = opcXmlReaderOpen(c, &reader, part, NULL, "UTF-8", XML_PARSE_NOWARNING | XML_PARSE_NOERROR | XML_PARSE_NONET);
|
|
||||||
|
|
||||||
if (ret != OPC_ERROR_NONE) {
|
|
||||||
LOG_ERRORF(doc->filepath, "(doc.c) opcXmlReaderOpen() returned error code %d", ret);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mce_start_document(&reader) {
|
xmlNode *root = xmlDocGetRootElement(xml);
|
||||||
mce_start_element(&reader, NULL, NULL) {
|
if (root == NULL) {
|
||||||
ret = dump_text(&reader, buf);
|
LOG_ERROR(doc->filepath, "Empty document")
|
||||||
if (ret != 0) {
|
xmlFreeDoc(xml);
|
||||||
mceTextReaderCleanup(&reader);
|
return -1;
|
||||||
return -1;
|
}
|
||||||
}
|
|
||||||
} mce_end_element(&reader);
|
extract_text(xml, root, buf);
|
||||||
} mce_end_document(&reader);
|
xmlFreeDoc(xml);
|
||||||
|
|
||||||
mceTextReaderCleanup(&reader);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,34 +99,42 @@ void parse_doc(void *mem, size_t mem_len, document_t *doc) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
opcContainer *c = opcContainerOpenMem(mem, mem_len, OPC_OPEN_READ_ONLY, NULL);
|
struct archive *a = archive_read_new();
|
||||||
if (c == NULL) {
|
archive_read_support_format_zip(a);
|
||||||
LOG_ERROR(doc->filepath, "(doc.c) Couldn't open document with opcContainerOpenMem()");
|
|
||||||
|
int ret = archive_read_open_memory(a, mem, mem_len);
|
||||||
|
if (ret != ARCHIVE_OK) {
|
||||||
|
LOG_ERRORF(doc->filepath, "Could not read archive: %s", archive_error_string(a))
|
||||||
|
archive_read_free(a);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dyn_buffer_t buf = dyn_buffer_create();
|
text_buffer_t buf = text_buffer_create(ScanCtx.content_size);
|
||||||
|
|
||||||
opcPart part = opcPartGetFirst(c);
|
struct archive_entry *entry;
|
||||||
do {
|
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
||||||
if (should_read_part(part)) {
|
if (S_ISREG(archive_entry_stat(entry)->st_mode)) {
|
||||||
int ret = read_part(c, &buf, part, doc);
|
const char *path = archive_entry_pathname(entry);
|
||||||
if (ret != 0) {
|
|
||||||
break;
|
if (should_read_part(path)) {
|
||||||
|
ret = read_part(a, &buf, doc);
|
||||||
|
if (ret != 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((part = opcPartGetNext(c, part)));
|
}
|
||||||
|
|
||||||
opcContainerClose(c, OPC_CLOSE_NOW);
|
if (buf.dyn_buffer.cur > 0) {
|
||||||
|
text_buffer_terminate_string(&buf);
|
||||||
|
|
||||||
if (buf.cur > 0) {
|
meta_line_t *meta = malloc(sizeof(meta_line_t) + buf.dyn_buffer.cur);
|
||||||
dyn_buffer_write_char(&buf, '\0');
|
|
||||||
|
|
||||||
meta_line_t *meta = malloc(sizeof(meta_line_t) + buf.cur);
|
|
||||||
meta->key = MetaContent;
|
meta->key = MetaContent;
|
||||||
strcpy(meta->strval, buf.buf);
|
strcpy(meta->strval, buf.dyn_buffer.buf);
|
||||||
APPEND_META(doc, meta)
|
APPEND_META(doc, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
dyn_buffer_destroy(&buf);
|
archive_read_close(a);
|
||||||
|
archive_read_free(a);
|
||||||
|
text_buffer_destroy(&buf);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#define AVIO_BUF_SIZE 8192
|
#define AVIO_BUF_SIZE 8192
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
AVCodecContext *alloc_jpeg_encoder(int dstW, int dstH, float qscale) {
|
static AVCodecContext *alloc_jpeg_encoder(int dstW, int dstH, float qscale) {
|
||||||
|
|
||||||
AVCodec *jpeg_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
|
AVCodec *jpeg_codec = avcodec_find_encoder(AV_CODEC_ID_MJPEG);
|
||||||
AVCodecContext *jpeg = avcodec_alloc_context3(jpeg_codec);
|
AVCodecContext *jpeg = avcodec_alloc_context3(jpeg_codec);
|
||||||
@ -78,7 +78,7 @@ AVFrame *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int si
|
|||||||
}
|
}
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int stream_idx, document_t *doc) {
|
static AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int stream_idx, document_t *doc) {
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
|
|
||||||
AVPacket avPacket;
|
AVPacket avPacket;
|
||||||
@ -135,7 +135,7 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st
|
|||||||
text_buffer_destroy(&tex);
|
text_buffer_destroy(&tex);
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) {
|
static void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) {
|
||||||
|
|
||||||
AVDictionaryEntry *tag = NULL;
|
AVDictionaryEntry *tag = NULL;
|
||||||
while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
|
while ((tag = av_dict_get(pFormatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
|
||||||
@ -160,8 +160,7 @@ void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
void
|
static void append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) {
|
||||||
append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) {
|
|
||||||
|
|
||||||
if (is_video) {
|
if (is_video) {
|
||||||
meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
|
meta_line_t *meta_duration = malloc(sizeof(meta_line_t));
|
||||||
|
@ -36,7 +36,7 @@ void *read_all(parse_job_t *job, const char *buf, int bytes_read) {
|
|||||||
memcpy(full_buf, buf, bytes_read);
|
memcpy(full_buf, buf, bytes_read);
|
||||||
|
|
||||||
int ret = job->vfile.read(&job->vfile, full_buf + bytes_read, job->info.st_size - bytes_read);
|
int ret = job->vfile.read(&job->vfile, full_buf + bytes_read, job->info.st_size - bytes_read);
|
||||||
if (ret == -1) {
|
if (ret < 0) {
|
||||||
LOG_ERRORF(job->filepath, "read(): [%d] %s", errno, strerror(errno))
|
LOG_ERRORF(job->filepath, "read(): [%d] %s", errno, strerror(errno))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -58,6 +58,7 @@ void parse(void *arg) {
|
|||||||
|
|
||||||
if (Magic == NULL) {
|
if (Magic == NULL) {
|
||||||
Magic = magic_open(MAGIC_MIME_TYPE);
|
Magic = magic_open(MAGIC_MIME_TYPE);
|
||||||
|
magic_load(Magic, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.filepath = job->filepath;
|
doc.filepath = job->filepath;
|
||||||
@ -87,10 +88,10 @@ void parse(void *arg) {
|
|||||||
|
|
||||||
int bytes_read = 0;
|
int bytes_read = 0;
|
||||||
|
|
||||||
if (doc.mime == 0) {
|
if (doc.mime == 0 && !ScanCtx.fast) {
|
||||||
// Get mime type with libmagic
|
// Get mime type with libmagic
|
||||||
bytes_read = job->vfile.read(&job->vfile, buf, PARSE_BUF_SIZE);
|
bytes_read = job->vfile.read(&job->vfile, buf, PARSE_BUF_SIZE);
|
||||||
if (bytes_read == -1) {
|
if (bytes_read < 0) {
|
||||||
LOG_WARNINGF(job->filepath, "read() Error: %s", strerror(errno))
|
LOG_WARNINGF(job->filepath, "read() Error: %s", strerror(errno))
|
||||||
CLOSE_FILE(job->vfile)
|
CLOSE_FILE(job->vfile)
|
||||||
return;
|
return;
|
||||||
@ -99,10 +100,16 @@ void parse(void *arg) {
|
|||||||
const char *magic_mime_str = magic_buffer(Magic, buf, bytes_read);
|
const char *magic_mime_str = magic_buffer(Magic, buf, bytes_read);
|
||||||
if (magic_mime_str != NULL) {
|
if (magic_mime_str != NULL) {
|
||||||
doc.mime = mime_get_mime_by_string(ScanCtx.mime_table, magic_mime_str);
|
doc.mime = mime_get_mime_by_string(ScanCtx.mime_table, magic_mime_str);
|
||||||
|
|
||||||
|
LOG_DEBUGF(job->filepath, "libmagic: %s", magic_mime_str);
|
||||||
|
|
||||||
if (doc.mime == 0) {
|
if (doc.mime == 0) {
|
||||||
LOG_WARNINGF(job->filepath, "Couldn't find mime %s", magic_mime_str);
|
LOG_WARNINGF(job->filepath, "Couldn't find mime %s", magic_mime_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
magic_close(Magic);
|
||||||
|
Magic = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mmime = MAJOR_MIME(doc.mime);
|
int mmime = MAJOR_MIME(doc.mime);
|
||||||
@ -112,11 +119,11 @@ void parse(void *arg) {
|
|||||||
} else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) ||
|
} else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) ||
|
||||||
(mmime == MimeImage && doc.size >= MIN_IMAGE_SIZE) || mmime == MimeAudio) {
|
(mmime == MimeImage && doc.size >= MIN_IMAGE_SIZE) || mmime == MimeAudio) {
|
||||||
|
|
||||||
if (job->vfile.is_fs_file) {
|
// if (job->vfile.is_fs_file) {
|
||||||
parse_media_filename(job->filepath, &doc);
|
// parse_media_filename(job->filepath, &doc);
|
||||||
} else {
|
// } else {
|
||||||
parse_media_vfile(&job->vfile, &doc);
|
// parse_media_vfile(&job->vfile, &doc);
|
||||||
}
|
// }
|
||||||
|
|
||||||
} else if (IS_PDF(doc.mime)) {
|
} else if (IS_PDF(doc.mime)) {
|
||||||
void *pdf_buf = read_all(job, (char *) buf, bytes_read);
|
void *pdf_buf = read_all(job, (char *) buf, bytes_read);
|
||||||
|
@ -6,12 +6,13 @@
|
|||||||
__thread text_buffer_t thread_buffer;
|
__thread text_buffer_t thread_buffer;
|
||||||
|
|
||||||
|
|
||||||
fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
int render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
fz_page *cover = NULL;
|
fz_page *cover = NULL;
|
||||||
|
|
||||||
fz_var(cover);
|
fz_var(cover);
|
||||||
|
fz_var(err);
|
||||||
fz_try(ctx)
|
fz_try(ctx)
|
||||||
cover = fz_load_page(ctx, fzdoc, 0);
|
cover = fz_load_page(ctx, fzdoc, 0);
|
||||||
fz_catch(ctx)
|
fz_catch(ctx)
|
||||||
@ -20,7 +21,7 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
|||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
fz_drop_page(ctx, cover);
|
fz_drop_page(ctx, cover);
|
||||||
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fz_rect bounds = fz_bound_page(ctx, cover);
|
fz_rect bounds = fz_bound_page(ctx, cover);
|
||||||
@ -61,7 +62,7 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
|||||||
LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
LOG_WARNINGF(doc->filepath, "fz_run_page() returned error code [%d] %s", err, ctx->error.message)
|
||||||
fz_drop_page(ctx, cover);
|
fz_drop_page(ctx, cover);
|
||||||
fz_drop_pixmap(ctx, pixmap);
|
fz_drop_pixmap(ctx, pixmap);
|
||||||
return NULL;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
fz_buffer *fzbuf = NULL;
|
fz_buffer *fzbuf = NULL;
|
||||||
@ -81,15 +82,15 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) {
|
|||||||
|
|
||||||
fz_drop_buffer(ctx, fzbuf);
|
fz_drop_buffer(ctx, fzbuf);
|
||||||
fz_drop_pixmap(ctx, pixmap);
|
fz_drop_pixmap(ctx, pixmap);
|
||||||
|
fz_drop_page(ctx, cover);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
LOG_WARNINGF(doc->filepath, "fz_new_buffer_from_pixmap_as_png() returned error code [%d] %s", err,
|
LOG_WARNINGF(doc->filepath, "fz_new_buffer_from_pixmap_as_png() returned error code [%d] %s", err,
|
||||||
ctx->error.message)
|
ctx->error.message)
|
||||||
fz_drop_page(ctx, cover);
|
return FALSE;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return cover;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fz_err_callback(void *user, UNUSED(const char *message)) {
|
void fz_err_callback(void *user, UNUSED(const char *message)) {
|
||||||
@ -100,7 +101,7 @@ void fz_err_callback(void *user, UNUSED(const char *message)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
__always_inline
|
__always_inline
|
||||||
void init_ctx(fz_context *ctx, document_t *doc) {
|
static void init_ctx(fz_context *ctx, document_t *doc) {
|
||||||
fz_disable_icc(ctx);
|
fz_disable_icc(ctx);
|
||||||
fz_register_document_handlers(ctx);
|
fz_register_document_handlers(ctx);
|
||||||
|
|
||||||
@ -110,7 +111,8 @@ void init_ctx(fz_context *ctx, document_t *doc) {
|
|||||||
ctx->error.print = fz_err_callback;
|
ctx->error.print = fz_err_callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_stext_block(fz_stext_block *block, text_buffer_t *tex) {
|
__always_inline
|
||||||
|
static int read_stext_block(fz_stext_block *block, text_buffer_t *tex) {
|
||||||
if (block->type != FZ_STEXT_BLOCK_TEXT) {
|
if (block->type != FZ_STEXT_BLOCK_TEXT) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -197,7 +199,7 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) {
|
|||||||
fz_catch(ctx)
|
fz_catch(ctx)
|
||||||
err = ctx->error.errcode;
|
err = ctx->error.errcode;
|
||||||
|
|
||||||
if (err) {
|
if (err != 0) {
|
||||||
fz_drop_stream(ctx, stream);
|
fz_drop_stream(ctx, stream);
|
||||||
fz_drop_document(ctx, fzdoc);
|
fz_drop_document(ctx, fzdoc);
|
||||||
fz_drop_context(ctx);
|
fz_drop_context(ctx);
|
||||||
@ -232,18 +234,11 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fz_page *cover = NULL;
|
|
||||||
if (ScanCtx.tn_size > 0) {
|
if (ScanCtx.tn_size > 0) {
|
||||||
cover = render_cover(ctx, doc, fzdoc);
|
err = render_cover(ctx, doc, fzdoc);
|
||||||
} else {
|
|
||||||
fz_var(cover);
|
|
||||||
fz_try(ctx)
|
|
||||||
cover = fz_load_page(ctx, fzdoc, 0);
|
|
||||||
fz_catch(ctx)
|
|
||||||
cover = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cover == NULL) {
|
if (err == TRUE) {
|
||||||
fz_drop_stream(ctx, stream);
|
fz_drop_stream(ctx, stream);
|
||||||
fz_drop_document(ctx, fzdoc);
|
fz_drop_document(ctx, fzdoc);
|
||||||
fz_drop_context(ctx);
|
fz_drop_context(ctx);
|
||||||
@ -256,23 +251,19 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) {
|
|||||||
|
|
||||||
for (int current_page = 0; current_page < page_count; current_page++) {
|
for (int current_page = 0; current_page < page_count; current_page++) {
|
||||||
fz_page *page = NULL;
|
fz_page *page = NULL;
|
||||||
if (current_page == 0) {
|
fz_var(err);
|
||||||
page = cover;
|
fz_try(ctx)
|
||||||
} else {
|
page = fz_load_page(ctx, fzdoc, current_page);
|
||||||
fz_var(err);
|
fz_catch(ctx)
|
||||||
fz_try(ctx)
|
err = ctx->error.errcode;
|
||||||
page = fz_load_page(ctx, fzdoc, current_page);
|
if (err != 0) {
|
||||||
fz_catch(ctx)
|
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
||||||
err = ctx->error.errcode;
|
text_buffer_destroy(&thread_buffer);
|
||||||
if (err != 0) {
|
fz_drop_page(ctx, page);
|
||||||
LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message)
|
fz_drop_stream(ctx, stream);
|
||||||
text_buffer_destroy(&thread_buffer);
|
fz_drop_document(ctx, fzdoc);
|
||||||
fz_drop_page(ctx, page);
|
fz_drop_context(ctx);
|
||||||
fz_drop_stream(ctx, stream);
|
return;
|
||||||
fz_drop_document(ctx, fzdoc);
|
|
||||||
fz_drop_context(ctx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fz_stext_page *stext = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
|
fz_stext_page *stext = fz_new_stext_page(ctx, fz_bound_page(ctx, page));
|
||||||
@ -289,12 +280,12 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) {
|
|||||||
|
|
||||||
fz_var(err);
|
fz_var(err);
|
||||||
fz_try(ctx)
|
fz_try(ctx)
|
||||||
fz_run_page(ctx, page, dev, fz_identity, NULL);
|
fz_run_page(ctx, page, dev, fz_identity, NULL);
|
||||||
fz_always(ctx)
|
fz_always(ctx)
|
||||||
{
|
{
|
||||||
fz_close_device(ctx, dev);
|
fz_close_device(ctx, dev);
|
||||||
fz_drop_device(ctx, dev);
|
fz_drop_device(ctx, dev);
|
||||||
}
|
}
|
||||||
fz_catch(ctx)
|
fz_catch(ctx)
|
||||||
err = ctx->error.errcode;
|
err = ctx->error.errcode;
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@
|
|||||||
#include "freetype/freetype.h"
|
#include "freetype/freetype.h"
|
||||||
#include <archive.h>
|
#include <archive.h>
|
||||||
#include <archive_entry.h>
|
#include <archive_entry.h>
|
||||||
#include <opc/opc.h>
|
|
||||||
#include <libxml/xmlstring.h>
|
#include <libxml/xmlstring.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
#define BOOL int
|
#define BOOL int
|
||||||
#include <tesseract/capi.h>
|
#include <tesseract/capi.h>
|
||||||
#include <pcre.h>
|
#include <pcre.h>
|
||||||
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "tpool.h"
|
#include "tpool.h"
|
||||||
|
#include "utf8.h/utf8.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "io/store.h"
|
#include "io/store.h"
|
||||||
#include "io/serialize.h"
|
#include "io/serialize.h"
|
||||||
@ -63,7 +64,6 @@
|
|||||||
#include "parsing/cbr.h"
|
#include "parsing/cbr.h"
|
||||||
#include "cli.h"
|
#include "cli.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "utf8.h/utf8.h"
|
|
||||||
|
|
||||||
#include "src/index/elastic.h"
|
#include "src/index/elastic.h"
|
||||||
#include "index/web.h"
|
#include "index/web.h"
|
||||||
|
229
src/util.c
229
src/util.c
@ -1,235 +1,6 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "src/ctx.h"
|
#include "src/ctx.h"
|
||||||
|
|
||||||
dyn_buffer_t dyn_buffer_create() {
|
|
||||||
dyn_buffer_t buf;
|
|
||||||
|
|
||||||
buf.size = INITIAL_BUF_SIZE;
|
|
||||||
buf.cur = 0;
|
|
||||||
buf.buf = malloc(INITIAL_BUF_SIZE);
|
|
||||||
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void grow_buffer(dyn_buffer_t *buf, size_t size) {
|
|
||||||
if (buf->cur + size > buf->size) {
|
|
||||||
do {
|
|
||||||
buf->size *= 2;
|
|
||||||
} while (buf->cur + size > buf->size);
|
|
||||||
|
|
||||||
buf->buf = realloc(buf->buf, buf->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void grow_buffer_small(dyn_buffer_t *buf) {
|
|
||||||
if (buf->cur + sizeof(long) > buf->size) {
|
|
||||||
buf->size *= 2;
|
|
||||||
buf->buf = realloc(buf->buf, buf->size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write(dyn_buffer_t *buf, void *data, size_t size) {
|
|
||||||
grow_buffer(buf, size);
|
|
||||||
|
|
||||||
memcpy(buf->buf + buf->cur, data, size);
|
|
||||||
buf->cur += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write_char(dyn_buffer_t *buf, char c) {
|
|
||||||
grow_buffer_small(buf);
|
|
||||||
|
|
||||||
*(buf->buf + buf->cur) = c;
|
|
||||||
buf->cur += sizeof(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write_str(dyn_buffer_t *buf, char *str) {
|
|
||||||
dyn_buffer_write(buf, str, strlen(str));
|
|
||||||
dyn_buffer_write_char(buf, '\0');
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_append_string(dyn_buffer_t *buf, char *str) {
|
|
||||||
dyn_buffer_write(buf, str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write_int(dyn_buffer_t *buf, int d) {
|
|
||||||
grow_buffer_small(buf);
|
|
||||||
|
|
||||||
*(int *) (buf->buf + buf->cur) = d;
|
|
||||||
buf->cur += sizeof(int);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write_short(dyn_buffer_t *buf, short s) {
|
|
||||||
grow_buffer_small(buf);
|
|
||||||
|
|
||||||
*(short *) (buf->buf + buf->cur) = s;
|
|
||||||
buf->cur += sizeof(short);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_write_long(dyn_buffer_t *buf, unsigned long l) {
|
|
||||||
grow_buffer_small(buf);
|
|
||||||
|
|
||||||
*(unsigned long *) (buf->buf + buf->cur) = l;
|
|
||||||
buf->cur += sizeof(unsigned long);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dyn_buffer_destroy(dyn_buffer_t *buf) {
|
|
||||||
free(buf->buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void text_buffer_destroy(text_buffer_t *buf) {
|
|
||||||
dyn_buffer_destroy(&buf->dyn_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
text_buffer_t text_buffer_create(int max_size) {
|
|
||||||
text_buffer_t text_buf;
|
|
||||||
|
|
||||||
text_buf.dyn_buffer = dyn_buffer_create();
|
|
||||||
text_buf.max_size = max_size;
|
|
||||||
text_buf.last_char_was_whitespace = FALSE;
|
|
||||||
|
|
||||||
return text_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void text_buffer_terminate_string(text_buffer_t *buf) {
|
|
||||||
if (buf->dyn_buffer.cur > 0 && *(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) == ' ') {
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) = '\0';
|
|
||||||
} else {
|
|
||||||
dyn_buffer_write_char(&buf->dyn_buffer, '\0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__always_inline
|
|
||||||
int utf8_validchr(const char *s) {
|
|
||||||
if (0x00 == (0x80 & *s)) {
|
|
||||||
return TRUE;
|
|
||||||
} else if (0xf0 == (0xf8 & *s)) {
|
|
||||||
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
|
|
||||||
(0x80 != (0xc0 & s[3]))) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0x80 == (0xc0 & s[4])) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
} else if (0xe0 == (0xf0 & *s)) {
|
|
||||||
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0x80 == (0xc0 & s[3])) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
} else if (0xc0 == (0xe0 & *s)) {
|
|
||||||
if (0x80 != (0xc0 & s[1])) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0x80 == (0xc0 & s[2])) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0 == (0x1e & s[0])) {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len) {
|
|
||||||
|
|
||||||
utf8_int32_t c;
|
|
||||||
if (str == NULL || len < 1 ||
|
|
||||||
(0xf0 == (0xf8 & str[0]) && len < 4) ||
|
|
||||||
(0xe0 == (0xf0 & str[0]) && len < 3) ||
|
|
||||||
(0xc0 == (0xe0 & str[0]) && len == 1) ||
|
|
||||||
*(str) == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (void *v = utf8codepoint(str, &c); c != '\0' && ((char *) v - str + 4) < len; v = utf8codepoint(v, &c)) {
|
|
||||||
if (utf8_validchr(v)) {
|
|
||||||
text_buffer_append_char(buf, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int text_buffer_append_string0(text_buffer_t *buf, char *str) {
|
|
||||||
utf8_int32_t c;
|
|
||||||
for (void *v = utf8codepoint(str, &c); c != '\0'; v = utf8codepoint(v, &c)) {
|
|
||||||
if (utf8_validchr(v)) {
|
|
||||||
text_buffer_append_char(buf, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int text_buffer_append_char(text_buffer_t *buf, int c) {
|
|
||||||
|
|
||||||
if (SHOULD_IGNORE_CHAR(c) || c == ' ') {
|
|
||||||
if (!buf->last_char_was_whitespace && buf->dyn_buffer.cur != 0) {
|
|
||||||
dyn_buffer_write_char(&buf->dyn_buffer, ' ');
|
|
||||||
buf->last_char_was_whitespace = TRUE;
|
|
||||||
|
|
||||||
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
|
||||||
return TEXT_BUF_FULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
buf->last_char_was_whitespace = FALSE;
|
|
||||||
grow_buffer_small(&buf->dyn_buffer);
|
|
||||||
|
|
||||||
if (0 == ((utf8_int32_t) 0xffffff80 & c)) {
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = (char) c;
|
|
||||||
} else if (0 == ((utf8_int32_t) 0xfffff800 & c)) {
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xc0 | (char) (c >> 6);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
|
||||||
} else if (0 == ((utf8_int32_t) 0xffff0000 & c)) {
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xe0 | (char) (c >> 12);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
|
||||||
} else {
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xf0 | (char) (c >> 18);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 12) & 0x3f);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
|
||||||
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
|
||||||
return TEXT_BUF_FULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void incremental_put(GHashTable *table, unsigned long inode_no, int mtime) {
|
|
||||||
g_hash_table_insert(table, (gpointer) inode_no, GINT_TO_POINTER(mtime));
|
|
||||||
}
|
|
||||||
|
|
||||||
int incremental_get(GHashTable *table, unsigned long inode_no) {
|
|
||||||
if (table != NULL) {
|
|
||||||
return GPOINTER_TO_INT(g_hash_table_lookup(table, (gpointer) inode_no));
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int incremental_mark_file_for_copy(GHashTable *table, unsigned long inode_no) {
|
|
||||||
g_hash_table_insert(table, GINT_TO_POINTER(inode_no), GINT_TO_POINTER(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define PBSTR "========================================"
|
#define PBSTR "========================================"
|
||||||
#define PBWIDTH 40
|
#define PBWIDTH 40
|
||||||
|
|
||||||
|
253
src/util.h
253
src/util.h
@ -32,47 +32,258 @@ dyn_buffer_t url_escape(char *str);
|
|||||||
|
|
||||||
void progress_bar_print(double percentage, size_t tn_size, size_t index_size);
|
void progress_bar_print(double percentage, size_t tn_size, size_t index_size);
|
||||||
|
|
||||||
|
|
||||||
GHashTable *incremental_get_table();
|
GHashTable *incremental_get_table();
|
||||||
|
|
||||||
dyn_buffer_t dyn_buffer_create();
|
__always_inline
|
||||||
|
static int utf8_validchr2(const char *s) {
|
||||||
|
if (0x00 == (0x80 & *s)) {
|
||||||
|
return TRUE;
|
||||||
|
} else if (0xf0 == (0xf8 & *s)) {
|
||||||
|
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2])) ||
|
||||||
|
(0x80 != (0xc0 & s[3]))) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void grow_buffer(dyn_buffer_t *buf, size_t size);
|
if (0x80 == (0xc0 & s[4])) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void grow_buffer_small(dyn_buffer_t *buf);
|
if ((0 == (0x07 & s[0])) && (0 == (0x30 & s[1]))) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else if (0xe0 == (0xf0 & *s)) {
|
||||||
|
if ((0x80 != (0xc0 & s[1])) || (0x80 != (0xc0 & s[2]))) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_write(dyn_buffer_t *buf, void *data, size_t size);
|
if (0x80 == (0xc0 & s[3])) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_write_char(dyn_buffer_t *buf, char c);
|
if ((0 == (0x0f & s[0])) && (0 == (0x20 & s[1]))) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else if (0xc0 == (0xe0 & *s)) {
|
||||||
|
if (0x80 != (0xc0 & s[1])) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_write_str(dyn_buffer_t *buf, char *str);
|
if (0x80 == (0xc0 & s[2])) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_append_string(dyn_buffer_t *buf, char *str);
|
if (0 == (0x1e & s[0])) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_write_int(dyn_buffer_t *buf, int d);
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void dyn_buffer_write_short(dyn_buffer_t *buf, short s);
|
|
||||||
|
|
||||||
void dyn_buffer_write_long(dyn_buffer_t *buf, unsigned long l);
|
__always_inline
|
||||||
|
static dyn_buffer_t dyn_buffer_create() {
|
||||||
|
dyn_buffer_t buf;
|
||||||
|
|
||||||
void dyn_buffer_destroy(dyn_buffer_t *buf);
|
buf.size = INITIAL_BUF_SIZE;
|
||||||
|
buf.cur = 0;
|
||||||
|
buf.buf = malloc(INITIAL_BUF_SIZE);
|
||||||
|
|
||||||
void text_buffer_destroy(text_buffer_t *buf);
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
text_buffer_t text_buffer_create(int max_size);
|
__always_inline
|
||||||
|
static void grow_buffer(dyn_buffer_t *buf, size_t size) {
|
||||||
|
if (buf->cur + size > buf->size) {
|
||||||
|
do {
|
||||||
|
buf->size *= 2;
|
||||||
|
} while (buf->cur + size > buf->size);
|
||||||
|
|
||||||
void text_buffer_terminate_string(text_buffer_t *buf);
|
buf->buf = realloc(buf->buf, buf->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len);
|
__always_inline
|
||||||
int text_buffer_append_string0(text_buffer_t *buf, char *str);
|
static void grow_buffer_small(dyn_buffer_t *buf) {
|
||||||
|
if (buf->cur + sizeof(long) > buf->size) {
|
||||||
|
buf->size *= 2;
|
||||||
|
buf->buf = realloc(buf->buf, buf->size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int text_buffer_append_char(text_buffer_t *buf, int c);
|
__always_inline
|
||||||
|
static void dyn_buffer_write(dyn_buffer_t *buf, void *data, size_t size) {
|
||||||
|
grow_buffer(buf, size);
|
||||||
|
|
||||||
void incremental_put(GHashTable *table, unsigned long inode_no, int mtime);
|
memcpy(buf->buf + buf->cur, data, size);
|
||||||
|
buf->cur += size;
|
||||||
|
}
|
||||||
|
|
||||||
int incremental_get(GHashTable *table, unsigned long inode_no);
|
__always_inline
|
||||||
|
static void dyn_buffer_write_char(dyn_buffer_t *buf, char c) {
|
||||||
|
grow_buffer_small(buf);
|
||||||
|
|
||||||
|
*(buf->buf + buf->cur) = c;
|
||||||
|
buf->cur += sizeof(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_write_str(dyn_buffer_t *buf, char *str) {
|
||||||
|
dyn_buffer_write(buf, str, strlen(str));
|
||||||
|
dyn_buffer_write_char(buf, '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_append_string(dyn_buffer_t *buf, char *str) {
|
||||||
|
dyn_buffer_write(buf, str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_write_int(dyn_buffer_t *buf, int d) {
|
||||||
|
grow_buffer_small(buf);
|
||||||
|
|
||||||
|
*(int *) (buf->buf + buf->cur) = d;
|
||||||
|
buf->cur += sizeof(int);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_write_short(dyn_buffer_t *buf, short s) {
|
||||||
|
grow_buffer_small(buf);
|
||||||
|
|
||||||
|
*(short *) (buf->buf + buf->cur) = s;
|
||||||
|
buf->cur += sizeof(short);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_write_long(dyn_buffer_t *buf, unsigned long l) {
|
||||||
|
grow_buffer_small(buf);
|
||||||
|
|
||||||
|
*(unsigned long *) (buf->buf + buf->cur) = l;
|
||||||
|
buf->cur += sizeof(unsigned long);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void dyn_buffer_destroy(dyn_buffer_t *buf) {
|
||||||
|
free(buf->buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void text_buffer_destroy(text_buffer_t *buf) {
|
||||||
|
dyn_buffer_destroy(&buf->dyn_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static text_buffer_t text_buffer_create(int max_size) {
|
||||||
|
text_buffer_t text_buf;
|
||||||
|
|
||||||
|
text_buf.dyn_buffer = dyn_buffer_create();
|
||||||
|
text_buf.max_size = max_size;
|
||||||
|
text_buf.last_char_was_whitespace = FALSE;
|
||||||
|
|
||||||
|
return text_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int text_buffer_append_char(text_buffer_t *buf, int c) {
|
||||||
|
|
||||||
|
if (SHOULD_IGNORE_CHAR(c) || c == ' ') {
|
||||||
|
if (!buf->last_char_was_whitespace && buf->dyn_buffer.cur != 0) {
|
||||||
|
dyn_buffer_write_char(&buf->dyn_buffer, ' ');
|
||||||
|
buf->last_char_was_whitespace = TRUE;
|
||||||
|
|
||||||
|
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
||||||
|
return TEXT_BUF_FULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf->last_char_was_whitespace = FALSE;
|
||||||
|
grow_buffer_small(&buf->dyn_buffer);
|
||||||
|
|
||||||
|
if (0 == ((utf8_int32_t) 0xffffff80 & c)) {
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = (char) c;
|
||||||
|
} else if (0 == ((utf8_int32_t) 0xfffff800 & c)) {
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xc0 | (char) (c >> 6);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||||
|
} else if (0 == ((utf8_int32_t) 0xffff0000 & c)) {
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xe0 | (char) (c >> 12);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||||
|
} else {
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0xf0 | (char) (c >> 18);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 12) & 0x3f);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) ((c >> 6) & 0x3f);
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur++) = 0x80 | (char) (c & 0x3f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf->max_size > 0 && buf->dyn_buffer.cur >= buf->max_size) {
|
||||||
|
return TEXT_BUF_FULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void text_buffer_terminate_string(text_buffer_t *buf) {
|
||||||
|
if (buf->dyn_buffer.cur > 0 && *(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) == ' ') {
|
||||||
|
*(buf->dyn_buffer.buf + buf->dyn_buffer.cur - 1) = '\0';
|
||||||
|
} else {
|
||||||
|
dyn_buffer_write_char(&buf->dyn_buffer, '\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int text_buffer_append_string(text_buffer_t *buf, char *str, size_t len) {
|
||||||
|
|
||||||
|
utf8_int32_t c;
|
||||||
|
if (str == NULL || len < 1 ||
|
||||||
|
(0xf0 == (0xf8 & str[0]) && len < 4) ||
|
||||||
|
(0xe0 == (0xf0 & str[0]) && len < 3) ||
|
||||||
|
(0xc0 == (0xe0 & str[0]) && len == 1) ||
|
||||||
|
*(str) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (void *v = utf8codepoint(str, &c); c != '\0' && ((char *) v - str + 4) < len; v = utf8codepoint(v, &c)) {
|
||||||
|
if (utf8_validchr2(v)) {
|
||||||
|
text_buffer_append_char(buf, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int text_buffer_append_string0(text_buffer_t *buf, char *str) {
|
||||||
|
utf8_int32_t c;
|
||||||
|
for (void *v = utf8codepoint(str, &c); c != '\0'; v = utf8codepoint(v, &c)) {
|
||||||
|
if (utf8_validchr2(v)) {
|
||||||
|
text_buffer_append_char(buf, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static void incremental_put(GHashTable *table, unsigned long inode_no, int mtime) {
|
||||||
|
g_hash_table_insert(table, (gpointer) inode_no, GINT_TO_POINTER(mtime));
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int incremental_get(GHashTable *table, unsigned long inode_no) {
|
||||||
|
if (table != NULL) {
|
||||||
|
return GPOINTER_TO_INT(g_hash_table_lookup(table, (gpointer) inode_no));
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__always_inline
|
||||||
|
static int incremental_mark_file_for_copy(GHashTable *table, unsigned long inode_no) {
|
||||||
|
g_hash_table_insert(table, GINT_TO_POINTER(inode_no), GINT_TO_POINTER(1));
|
||||||
|
}
|
||||||
|
|
||||||
int incremental_mark_file_for_copy(GHashTable *table, unsigned long inode_no);
|
|
||||||
|
|
||||||
const char *find_file_in_paths(const char **paths, const char *filename);
|
const char *find_file_in_paths(const char **paths, const char *filename);
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user