mirror of
				https://github.com/simon987/sist2.git
				synced 2025-10-31 16:06:53 +00:00 
			
		
		
		
	
						commit
						5f7a1acfe3
					
				| @ -4,6 +4,8 @@ set(CMAKE_C_STANDARD 11) | ||||
| project(sist2 C) | ||||
| list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMakeModules") | ||||
| 
 | ||||
| option(SIST_DEBUG "Build a debug executable" on) | ||||
| 
 | ||||
| add_executable( | ||||
|         sist2 | ||||
|         src/main.c | ||||
| @ -81,14 +83,40 @@ target_link_directories( | ||||
|         ${UUID_LIBRARY_DIRS} | ||||
| ) | ||||
| 
 | ||||
| target_compile_options(sist2 | ||||
| target_compile_options( | ||||
|         sist2 | ||||
|         PRIVATE | ||||
|         -Ofast | ||||
| #        -march=native | ||||
|         -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( | ||||
|         sist2 | ||||
| @ -115,16 +143,14 @@ TARGET_LINK_LIBRARIES( | ||||
| 
 | ||||
|         m | ||||
|         bz2 | ||||
|         ${PROJECT_SOURCE_DIR}/lib/libmagic.a | ||||
| #        ${PROJECT_SOURCE_DIR}/lib/libmagic.a | ||||
|         magic | ||||
|         ${PROJECT_SOURCE_DIR}/lib/libharfbuzz.a | ||||
|         ${PROJECT_SOURCE_DIR}/lib/libopenjp2.a | ||||
|         freetype | ||||
|         archive | ||||
| 
 | ||||
|         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/liblept.a | ||||
|  | ||||
| @ -123,7 +123,7 @@ binaries. | ||||
|         libssl-dev uuid-dev python3 libmagic-dev libfreetype6-dev \ | ||||
|         libcurl4-openssl-dev libbz2-dev yasm libharfbuzz-dev ragel \ | ||||
|         libarchive-dev libtiff5 libpng16-16 libpango1.0-dev \ | ||||
|         libxml2-dev | ||||
|         libxml2-dev libopenjp2-7-dev libleptonica-dev | ||||
|    ``` | ||||
| 
 | ||||
| 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 "ctx.h" | ||||
| 
 | ||||
| #include <tesseract/capi.h> | ||||
| 
 | ||||
| #define DEFAULT_OUTPUT "index.sist2/" | ||||
| #define DEFAULT_CONTENT_SIZE 32768 | ||||
| #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); | ||||
|         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)); | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
| @ -1,12 +1,6 @@ | ||||
| #include "elastic.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" | ||||
| 
 | ||||
| 
 | ||||
|  | ||||
| @ -39,8 +39,8 @@ void write_index_descriptor(char *path, index_descriptor_t *desc) { | ||||
|     cJSON_AddNumberToObject(json, "timestamp", (double) desc->timestamp); | ||||
| 
 | ||||
|     int fd = open(path, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); | ||||
|     if (fd == -1) { | ||||
|         perror(path); | ||||
|     if (fd < 0) { | ||||
|         LOG_FATALF("serialize.c", "Could not write index descriptor: %s", strerror(errno)); | ||||
|     } | ||||
|     char *str = cJSON_Print(json); | ||||
|     write(fd, str, strlen(str)); | ||||
| @ -185,7 +185,7 @@ void write_document(document_t *doc) { | ||||
| 
 | ||||
|     int res = write(index_fd, buf.buf, buf.cur); | ||||
|     if (res == -1) { | ||||
|         perror("write"); | ||||
|         LOG_FATALF("serialize.c", "Could not write document: %s", strerror(errno)) | ||||
|     } | ||||
|     ScanCtx.stat_index_size += buf.cur; | ||||
|     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; | ||||
|         size_t len; | ||||
|         size_t read = getline(&line, &len, file); | ||||
|         if (read == -1) { | ||||
|         if (read < 0) { | ||||
|             if (line) { | ||||
|                 free(line); | ||||
|             } | ||||
|  | ||||
| @ -15,8 +15,7 @@ store_t *store_create(char *path) { | ||||
|     ); | ||||
| 
 | ||||
|     if (open_ret != 0) { | ||||
|         fprintf(stderr, "Error while opening store: %s (%s)\n", mdb_strerror(open_ret), path); | ||||
|         exit(1); | ||||
|         LOG_FATALF("store.c", "Error while opening store: %s (%s)\n", mdb_strerror(open_ret), path) | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     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" | ||||
| 
 | ||||
| 
 | ||||
| static const char *const Version = "1.3.0"; | ||||
| static const char *const Version = "1.3.1"; | ||||
| static const char *const usage[] = { | ||||
|         "sist2 scan [OPTION]... PATH", | ||||
|         "sist2 index [OPTION]... INDEX", | ||||
| @ -17,7 +17,6 @@ static const char *const usage[] = { | ||||
| void global_init() { | ||||
|     curl_global_init(CURL_GLOBAL_NOTHING); | ||||
|     av_log_set_level(AV_LOG_QUIET); | ||||
|     opcInitLibrary(); | ||||
| } | ||||
| 
 | ||||
| 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); | ||||
| 
 | ||||
|         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; | ||||
| @ -96,7 +96,7 @@ void sist2_scan(scan_args_t *args) { | ||||
|         } | ||||
|         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); | ||||
| @ -148,13 +148,13 @@ void sist2_index(index_args_t *args) { | ||||
|     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) { | ||||
|         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); | ||||
|     if (dir == NULL) { | ||||
|         perror("opendir"); | ||||
|         return; | ||||
|         LOG_FATALF("main.c", "Could not open index %s: %s", args->index_path, strerror(errno)) | ||||
|     } | ||||
| 
 | ||||
|     index_func f; | ||||
| @ -274,7 +274,7 @@ int main(int argc, const char *argv[]) { | ||||
| 
 | ||||
|     if (arg_version) { | ||||
|         printf(Version); | ||||
|         exit(0); | ||||
|         goto end; | ||||
|     } | ||||
| 
 | ||||
|     if (LogCtx.very_verbose != 0) { | ||||
| @ -286,12 +286,12 @@ int main(int argc, const char *argv[]) { | ||||
| 
 | ||||
|     if (argc == 0) { | ||||
|         argparse_usage(&argparse); | ||||
|         return 1; | ||||
|         goto end; | ||||
|     } else if (strcmp(argv[0], "scan") == 0) { | ||||
| 
 | ||||
|         int err = scan_args_validate(scan_args, argc, argv); | ||||
|         if (err != 0) { | ||||
|             return err; | ||||
|             goto end; | ||||
|         } | ||||
|         sist2_scan(scan_args); | ||||
| 
 | ||||
| @ -299,7 +299,7 @@ int main(int argc, const char *argv[]) { | ||||
| 
 | ||||
|         int err = index_args_validate(index_args, argc, argv); | ||||
|         if (err != 0) { | ||||
|             return err; | ||||
|             goto end; | ||||
|         } | ||||
|         sist2_index(index_args); | ||||
| 
 | ||||
| @ -307,19 +307,19 @@ int main(int argc, const char *argv[]) { | ||||
| 
 | ||||
|         int err = web_args_validate(web_args, argc, argv); | ||||
|         if (err != 0) { | ||||
|             return err; | ||||
|             goto end; | ||||
|         } | ||||
|         sist2_web(web_args); | ||||
| 
 | ||||
|     } else { | ||||
|         fprintf(stderr, "Invalid command: '%s'\n", argv[0]); | ||||
|         argparse_usage(&argparse); | ||||
|         return 1; | ||||
|         goto end; | ||||
|     } | ||||
|     printf("\n"); | ||||
| 
 | ||||
|     end: | ||||
|     scan_args_destroy(scan_args); | ||||
| 
 | ||||
|     index_args_destroy(index_args); | ||||
|     web_args_destroy(web_args); | ||||
| 
 | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| #import "cbr.h" | ||||
| #import "src/ctx.h" | ||||
| #include "cbr.h" | ||||
| #include "src/ctx.h" | ||||
| 
 | ||||
| unsigned int cbr_mime; | ||||
| unsigned int cbz_mime; | ||||
|  | ||||
| @ -1,10 +1,40 @@ | ||||
| #include "doc.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(); | ||||
|     if (err != NULL) { | ||||
|         if (err->level == XML_ERR_FATAL) { | ||||
| @ -15,78 +45,51 @@ int dump_text(mceTextReader_t *reader, dyn_buffer_t *buf) { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     mce_start_children(reader) { | ||||
|         mce_start_element(reader, NULL, _X("t")) { | ||||
|             mce_skip_attributes(reader); | ||||
|             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); | ||||
|     for (xmlNode *child = node; child; child = child->next) { | ||||
|         if (*child->name == 't' && *(child->name + 1) == '\0') { | ||||
|             xmlChar *text = xmlNodeListGetString(xml, child->xmlChildrenNode, 1); | ||||
| 
 | ||||
|         mce_start_element(reader, NULL, NULL) { | ||||
|             int ret = dump_text(reader, buf); | ||||
|             if (ret != 0) { | ||||
|                 return ret; | ||||
|             if (text) { | ||||
|                 text_buffer_append_string0(buf, (char *) text); | ||||
|                 text_buffer_append_char(buf, ' '); | ||||
|                 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; | ||||
| } | ||||
| 
 | ||||
| __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) { | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     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); | ||||
|     if (xml == NULL) { | ||||
|         LOG_ERROR(doc->filepath, "Could not parse XML") | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     mce_start_document(&reader) { | ||||
|         mce_start_element(&reader, NULL, NULL) { | ||||
|             ret = dump_text(&reader, buf); | ||||
|             if (ret != 0) { | ||||
|                 mceTextReaderCleanup(&reader); | ||||
|                 return -1; | ||||
|             } | ||||
|         } mce_end_element(&reader); | ||||
|     } mce_end_document(&reader); | ||||
|     xmlNode *root = xmlDocGetRootElement(xml); | ||||
|     if (root == NULL) { | ||||
|         LOG_ERROR(doc->filepath, "Empty document") | ||||
|         xmlFreeDoc(xml); | ||||
|         return -1; | ||||
|     } | ||||
| 
 | ||||
|     extract_text(xml, root, buf); | ||||
|     xmlFreeDoc(xml); | ||||
| 
 | ||||
|     mceTextReaderCleanup(&reader); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| @ -96,34 +99,42 @@ void parse_doc(void *mem, size_t mem_len, document_t *doc) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     opcContainer *c = opcContainerOpenMem(mem, mem_len, OPC_OPEN_READ_ONLY, NULL); | ||||
|     if (c == NULL) { | ||||
|         LOG_ERROR(doc->filepath, "(doc.c) Couldn't open document with opcContainerOpenMem()"); | ||||
|     struct archive *a = archive_read_new(); | ||||
|     archive_read_support_format_zip(a); | ||||
| 
 | ||||
|     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; | ||||
|     } | ||||
| 
 | ||||
|     dyn_buffer_t buf = dyn_buffer_create(); | ||||
|     text_buffer_t buf = text_buffer_create(ScanCtx.content_size); | ||||
| 
 | ||||
|     opcPart part = opcPartGetFirst(c); | ||||
|     do { | ||||
|         if (should_read_part(part)) { | ||||
|             int ret = read_part(c, &buf, part, doc); | ||||
|             if (ret != 0) { | ||||
|                 break; | ||||
|     struct archive_entry *entry; | ||||
|     while (archive_read_next_header(a, &entry) == ARCHIVE_OK) { | ||||
|         if (S_ISREG(archive_entry_stat(entry)->st_mode)) { | ||||
|             const char *path = archive_entry_pathname(entry); | ||||
| 
 | ||||
|             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) { | ||||
|         dyn_buffer_write_char(&buf, '\0'); | ||||
| 
 | ||||
|         meta_line_t *meta = malloc(sizeof(meta_line_t) + buf.cur); | ||||
|         meta_line_t *meta = malloc(sizeof(meta_line_t) + buf.dyn_buffer.cur); | ||||
|         meta->key = MetaContent; | ||||
|         strcpy(meta->strval, buf.buf); | ||||
|         strcpy(meta->strval, buf.dyn_buffer.buf); | ||||
|         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 | ||||
| 
 | ||||
| __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); | ||||
|     AVCodecContext *jpeg = avcodec_alloc_context3(jpeg_codec); | ||||
| @ -78,7 +78,7 @@ AVFrame *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int si | ||||
| } | ||||
| 
 | ||||
| __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(); | ||||
| 
 | ||||
|     AVPacket avPacket; | ||||
| @ -135,7 +135,7 @@ AVFrame *read_frame(AVFormatContext *pFormatCtx, AVCodecContext *decoder, int st | ||||
|     text_buffer_destroy(&tex); | ||||
| 
 | ||||
| __always_inline | ||||
| void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) { | ||||
| static void append_audio_meta(AVFormatContext *pFormatCtx, document_t *doc) { | ||||
| 
 | ||||
|     AVDictionaryEntry *tag = NULL; | ||||
|     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 | ||||
| void | ||||
| append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) { | ||||
| static void append_video_meta(AVFormatContext *pFormatCtx, AVFrame *frame, document_t *doc, int include_audio_tags, int is_video) { | ||||
| 
 | ||||
|     if (is_video) { | ||||
|         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); | ||||
| 
 | ||||
|         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)) | ||||
|             return NULL; | ||||
|         } | ||||
| @ -58,6 +58,7 @@ void parse(void *arg) { | ||||
| 
 | ||||
|     if (Magic == NULL) { | ||||
|         Magic = magic_open(MAGIC_MIME_TYPE); | ||||
|         magic_load(Magic, NULL); | ||||
|     } | ||||
| 
 | ||||
|     doc.filepath = job->filepath; | ||||
| @ -87,10 +88,10 @@ void parse(void *arg) { | ||||
| 
 | ||||
|     int bytes_read = 0; | ||||
| 
 | ||||
|     if (doc.mime == 0) { | ||||
|     if (doc.mime == 0 && !ScanCtx.fast) { | ||||
|         // Get mime type with libmagic
 | ||||
|         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)) | ||||
|             CLOSE_FILE(job->vfile) | ||||
|             return; | ||||
| @ -99,10 +100,16 @@ void parse(void *arg) { | ||||
|         const char *magic_mime_str = magic_buffer(Magic, buf, bytes_read); | ||||
|         if (magic_mime_str != NULL) { | ||||
|             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) { | ||||
|                 LOG_WARNINGF(job->filepath, "Couldn't find mime %s", magic_mime_str); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         magic_close(Magic); | ||||
|         Magic = NULL; | ||||
|     } | ||||
| 
 | ||||
|     int mmime = MAJOR_MIME(doc.mime); | ||||
| @ -112,11 +119,11 @@ void parse(void *arg) { | ||||
|     } else if ((mmime == MimeVideo && doc.size >= MIN_VIDEO_SIZE) || | ||||
|                (mmime == MimeImage && doc.size >= MIN_IMAGE_SIZE) || mmime == MimeAudio) { | ||||
| 
 | ||||
|         if (job->vfile.is_fs_file) { | ||||
|             parse_media_filename(job->filepath, &doc); | ||||
|         } else { | ||||
|             parse_media_vfile(&job->vfile, &doc); | ||||
|         } | ||||
| //        if (job->vfile.is_fs_file) {
 | ||||
| //            parse_media_filename(job->filepath, &doc);
 | ||||
| //        } else {
 | ||||
| //            parse_media_vfile(&job->vfile, &doc);
 | ||||
| //        }
 | ||||
| 
 | ||||
|     } else if (IS_PDF(doc.mime)) { | ||||
|         void *pdf_buf = read_all(job, (char *) buf, bytes_read); | ||||
|  | ||||
| @ -6,12 +6,13 @@ | ||||
| __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; | ||||
|     fz_page *cover = NULL; | ||||
| 
 | ||||
|     fz_var(cover); | ||||
|     fz_var(err); | ||||
|     fz_try(ctx) | ||||
|         cover = fz_load_page(ctx, fzdoc, 0); | ||||
|     fz_catch(ctx) | ||||
| @ -20,7 +21,7 @@ fz_page *render_cover(fz_context *ctx, document_t *doc, fz_document *fzdoc) { | ||||
|     if (err != 0) { | ||||
|         fz_drop_page(ctx, cover); | ||||
|         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); | ||||
| @ -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) | ||||
|         fz_drop_page(ctx, cover); | ||||
|         fz_drop_pixmap(ctx, pixmap); | ||||
|         return NULL; | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     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_pixmap(ctx, pixmap); | ||||
|     fz_drop_page(ctx, cover); | ||||
| 
 | ||||
|     if (err != 0) { | ||||
|         LOG_WARNINGF(doc->filepath, "fz_new_buffer_from_pixmap_as_png() returned error code [%d] %s", err, | ||||
|                      ctx->error.message) | ||||
|         fz_drop_page(ctx, cover); | ||||
|         return NULL; | ||||
|         return FALSE; | ||||
|     } | ||||
| 
 | ||||
|     return cover; | ||||
|     return TRUE; | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| void init_ctx(fz_context *ctx, document_t *doc) { | ||||
| static void init_ctx(fz_context *ctx, document_t *doc) { | ||||
|     fz_disable_icc(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; | ||||
| } | ||||
| 
 | ||||
| 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) { | ||||
|         return 0; | ||||
|     } | ||||
| @ -197,7 +199,7 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) { | ||||
|     fz_catch(ctx) | ||||
|         err = ctx->error.errcode; | ||||
| 
 | ||||
|     if (err) { | ||||
|     if (err != 0) { | ||||
|         fz_drop_stream(ctx, stream); | ||||
|         fz_drop_document(ctx, fzdoc); | ||||
|         fz_drop_context(ctx); | ||||
| @ -232,18 +234,11 @@ void parse_pdf(void *buf, size_t buf_len, document_t *doc) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     fz_page *cover = NULL; | ||||
|     if (ScanCtx.tn_size > 0) { | ||||
|         cover = render_cover(ctx, doc, fzdoc); | ||||
|     } else { | ||||
|         fz_var(cover); | ||||
|         fz_try(ctx) | ||||
|             cover = fz_load_page(ctx, fzdoc, 0); | ||||
|         fz_catch(ctx) | ||||
|             cover = NULL; | ||||
|         err = render_cover(ctx, doc, fzdoc); | ||||
|     } | ||||
| 
 | ||||
|     if (cover == NULL) { | ||||
|     if (err == TRUE) { | ||||
|         fz_drop_stream(ctx, stream); | ||||
|         fz_drop_document(ctx, fzdoc); | ||||
|         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++) { | ||||
|             fz_page *page = NULL; | ||||
|             if (current_page == 0) { | ||||
|                 page = cover; | ||||
|             } else { | ||||
|                 fz_var(err); | ||||
|                 fz_try(ctx) | ||||
|                             page = fz_load_page(ctx, fzdoc, current_page); | ||||
|                 fz_catch(ctx) | ||||
|                     err = ctx->error.errcode; | ||||
|                 if (err != 0) { | ||||
|                     LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message) | ||||
|                     text_buffer_destroy(&thread_buffer); | ||||
|                     fz_drop_page(ctx, page); | ||||
|                     fz_drop_stream(ctx, stream); | ||||
|                     fz_drop_document(ctx, fzdoc); | ||||
|                     fz_drop_context(ctx); | ||||
|                     return; | ||||
|                 } | ||||
|             fz_var(err); | ||||
|             fz_try(ctx) | ||||
|                 page = fz_load_page(ctx, fzdoc, current_page); | ||||
|             fz_catch(ctx) | ||||
|                 err = ctx->error.errcode; | ||||
|             if (err != 0) { | ||||
|                 LOG_WARNINGF(doc->filepath, "fz_load_page() returned error code [%d] %s", err, ctx->error.message) | ||||
|                 text_buffer_destroy(&thread_buffer); | ||||
|                 fz_drop_page(ctx, page); | ||||
|                 fz_drop_stream(ctx, stream); | ||||
|                 fz_drop_document(ctx, fzdoc); | ||||
|                 fz_drop_context(ctx); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             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_try(ctx) | ||||
|                         fz_run_page(ctx, page, dev, fz_identity, NULL); | ||||
|                 fz_run_page(ctx, page, dev, fz_identity, NULL); | ||||
|             fz_always(ctx) | ||||
|                 { | ||||
|                     fz_close_device(ctx, dev); | ||||
|                     fz_drop_device(ctx, dev); | ||||
|                 } | ||||
|             { | ||||
|                 fz_close_device(ctx, dev); | ||||
|                 fz_drop_device(ctx, dev); | ||||
|             } | ||||
|             fz_catch(ctx) | ||||
|                 err = ctx->error.errcode; | ||||
| 
 | ||||
|  | ||||
| @ -31,8 +31,8 @@ | ||||
| #include "freetype/freetype.h" | ||||
| #include <archive.h> | ||||
| #include <archive_entry.h> | ||||
| #include <opc/opc.h> | ||||
| #include <libxml/xmlstring.h> | ||||
| #include <libxml/parser.h> | ||||
| #define BOOL int | ||||
| #include <tesseract/capi.h> | ||||
| #include <pcre.h> | ||||
| @ -48,6 +48,7 @@ | ||||
| 
 | ||||
| #include "types.h" | ||||
| #include "tpool.h" | ||||
| #include "utf8.h/utf8.h" | ||||
| #include "util.h" | ||||
| #include "io/store.h" | ||||
| #include "io/serialize.h" | ||||
| @ -63,7 +64,6 @@ | ||||
| #include "parsing/cbr.h" | ||||
| #include "cli.h" | ||||
| #include "log.h" | ||||
| #include "utf8.h/utf8.h" | ||||
| 
 | ||||
| #include "src/index/elastic.h" | ||||
| #include "index/web.h" | ||||
|  | ||||
							
								
								
									
										229
									
								
								src/util.c
									
									
									
									
									
								
							
							
						
						
									
										229
									
								
								src/util.c
									
									
									
									
									
								
							| @ -1,235 +1,6 @@ | ||||
| #include "util.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 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); | ||||
| 
 | ||||
| 
 | ||||
| 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); | ||||
| int text_buffer_append_string0(text_buffer_t *buf, char *str); | ||||
| __always_inline | ||||
| 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); | ||||
| 
 | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user