1 /* 2 * $Id: ebml.h 775 2011-07-03 08:27:03Z robux4 $ 3 * Copyright (c) 2008-2010, Matroska (non-profit organisation) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * * Neither the name of the Matroska assocation nor the 14 * names of its contributors may be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY the Matroska association ``AS IS'' AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL The Matroska Foundation BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef LIBEBML2_H 30 #define LIBEBML2_H 31 32 #include "corec/node/node.h" 33 #include "corec/helpers/file/file.h" 34 35 #if defined(CONFIG_EBML_UNICODE) 36 #include "corec/helpers/parser/parser.h" 37 #endif 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 #define CONTEXT_LIBEBML_VERSION 0x400 44 45 #define EBML_MAX_VERSION 1 46 #define EBML_MAX_ID 4 47 #define EBML_MAX_SIZE 8 48 49 #define SCOPE_PARTIAL_DATA 0 // read all data, except inside some binary elements (useful for binary data with a (internal) header) 50 #define SCOPE_ALL_DATA 1 51 #define SCOPE_NO_DATA 2 52 53 // base classes 54 #define EBML_ELEMENT_CLASS FOURCC('E','B','E','L') 55 #define EBML_BINARY_CLASS FOURCC('E','B','I','N') 56 #define EBML_DATE_CLASS FOURCC('E','B','D','T') 57 #define EBML_INTEGER_CLASS FOURCC('E','B','I','T') 58 #define EBML_SINTEGER_CLASS FOURCC('E','B','S','I') 59 #define EBML_FLOAT_CLASS FOURCC('E','B','F','L') 60 #define EBML_MASTER_CLASS FOURCC('E','B','M','T') 61 #define EBML_STRING_CLASS FOURCC('E','B','S','G') 62 #define EBML_UNISTRING_CLASS FOURCC('E','B','S','U') 63 #define EBML_BOOLEAN_CLASS FOURCC('E','B','B','O') 64 65 // global classes 66 #define EBML_CRC_CLASS FOURCC('E','B','C','R') 67 #define EBML_VOID_CLASS FOURCC('E','B','V','D') 68 69 #define EBML_DUMMY_ID FOURCC('E','B','D','U') 70 71 #define EBML_ELEMENT_INFINITESIZE 0x100 72 #define EBML_ELEMENT_OBJECT 0x101 73 74 #if defined(EBML2_EXPORTS) 75 #define EBML_DLL DLLEXPORT 76 #elif defined(EBML2_IMPORTS) 77 #define EBML_DLL DLLIMPORT 78 #else 79 #define EBML_DLL 80 #endif 81 82 typedef struct ebml_context ebml_context; 83 typedef struct ebml_parser_context ebml_parser_context; 84 typedef struct ebml_semantic ebml_semantic; 85 typedef struct ebml_element ebml_element; 86 typedef struct ebml_crc ebml_crc; 87 88 typedef struct ebml_master ebml_master; 89 typedef struct ebml_integer ebml_integer; 90 typedef struct ebml_string ebml_string; 91 typedef struct ebml_binary ebml_binary; 92 typedef struct ebml_integer ebml_date; 93 typedef struct ebml_float ebml_float; 94 typedef struct ebml_dummy ebml_dummy; 95 96 struct ebml_semantic 97 { 98 bool_t Mandatory; 99 bool_t Unique; 100 const ebml_context *eClass; 101 int DisabledProfile; // PROFILE_MATROSKA_V1 and others 102 }; 103 104 struct ebml_parser_context 105 { 106 const ebml_context *Context; 107 const ebml_parser_context *UpContext; 108 filepos_t EndPosition; 109 int Profile; 110 }; 111 112 typedef struct ebml_element_vmt 113 { 114 nodetree_vmt Base; 115 bool_t (*ValidateSize)(const void*); 116 err_t (*ReadData)(void*, stream *Input, const ebml_parser_context *ParserContext, bool_t AllowDummyElt, int Scope, size_t DepthCheckCRC); 117 #if defined(CONFIG_EBML_WRITING) 118 err_t (*RenderData)(void*, stream *Output, bool_t bForceWithoutMandatory, bool_t bWithDefault, filepos_t *Rendered); 119 #endif 120 bool_t (*IsDefaultValue)(const void*); 121 bool_t (*DefaultIsSet)(const void*); 122 filepos_t (*UpdateDataSize)(void*, bool_t bWithDefault, bool_t bForceWithoutMandatory); 123 bool_t (*NeedsDataSizeUpdate)(const void*, bool_t bWithDefault); 124 int (*Cmp)(const void*, const void*); 125 ebml_element *(*Copy)(const void*, const void *Cookie); 126 127 // internal call only 128 void (*PostCreate)(void*, bool_t SetDefault); 129 130 } ebml_element_vmt; 131 132 #define EBML_ElementValidateSize(p) VMT_FUNC(p,ebml_element_vmt)->ValidateSize(p) 133 #define EBML_ElementReadData(p,i,c,d,s,r) VMT_FUNC(p,ebml_element_vmt)->ReadData(p,i,c,d,s,r) 134 #define EBML_ElementRenderData(p,s,f,k,r) VMT_FUNC(p,ebml_element_vmt)->RenderData(p,s,f,k,r) 135 #define EBML_ElementIsDefaultValue(p) VMT_FUNC(p,ebml_element_vmt)->IsDefaultValue(p) 136 #define EBML_ElementUpdateSize(p,k,f) VMT_FUNC(p,ebml_element_vmt)->UpdateDataSize(p,k,f) 137 #define EBML_ElementNeedsDataSizeUpdate(p,d) VMT_FUNC(p,ebml_element_vmt)->NeedsDataSizeUpdate(p,d) 138 #define EBML_ElementCmp(p,e) VMT_FUNC(p,ebml_element_vmt)->Cmp(p,e) 139 #define EBML_ElementCopy(p,c) VMT_FUNC(p,ebml_element_vmt)->Copy(p,c) 140 141 EBML_DLL err_t EBML_Init(nodecontext *p); 142 EBML_DLL err_t EBML_Done(nodecontext *p); 143 144 EBML_DLL ebml_element *EBML_ElementCreate(anynode *Any, const ebml_context *Context, bool_t SetDefault, const void *Cookie); 145 146 EBML_DLL ebml_element *EBML_FindNextId(stream *Input, const ebml_context *Context, size_t MaxDataSize); 147 EBML_DLL ebml_element *EBML_FindNextElement(stream *Input, const ebml_parser_context *Context, int *UpperLevels, bool_t AllowDummy); 148 EBML_DLL uint8_t EBML_CodedSizeLength(filepos_t Length, uint8_t SizeLength, bool_t bSizeIsFinite); // TODO: turn into a macro ? 149 EBML_DLL uint8_t EBML_CodedSizeLengthSigned(filepos_t Length, uint8_t SizeLength); // TODO: turn into a macro ? 150 EBML_DLL uint8_t EBML_CodedValueLength(filepos_t Length, size_t CodedSize, uint8_t *OutBuffer, bool_t bSizeIsFinite); // TODO: turn into a macro ? 151 EBML_DLL uint8_t EBML_CodedValueLengthSigned(filepos_t Length, size_t CodedSize, uint8_t * OutBuffer); // TODO: turn into a macro ? 152 EBML_DLL filepos_t EBML_ReadCodedSizeValue(const uint8_t *InBuffer, size_t *BufferSize, filepos_t *SizeUnknown); 153 EBML_DLL filepos_t EBML_ReadCodedSizeSignedValue(const uint8_t *InBuffer, size_t *BufferSize, filepos_t *SizeUnknown); 154 155 EBML_DLL void EBML_ElementGetName(const ebml_element *Element, tchar_t *Out, size_t OutLen); 156 EBML_DLL const char *EBML_ElementGetClassName(const ebml_element *Element); 157 158 EBML_DLL const ebml_context *EBML_ElementContext(const ebml_element *Element); 159 160 EBML_DLL ebml_element *EBML_ElementSkipData(ebml_element *Element, stream *Input, const ebml_parser_context *Context, ebml_element *TestReadElt, bool_t AllowDummy); 161 EBML_DLL bool_t EBML_ElementIsFiniteSize(const ebml_element *Element); 162 EBML_DLL void EBML_ElementSetInfiniteSize(const ebml_element *Element, bool_t Set); 163 EBML_DLL bool_t EBML_ElementInfiniteForceSize(ebml_element *Element, filepos_t NewSize); 164 EBML_DLL bool_t EBML_ElementIsDummy(const ebml_element *Element); 165 166 EBML_DLL fourcc_t EBML_ElementClassID(const ebml_element *Element); 167 EBML_DLL filepos_t EBML_ElementPosition(const ebml_element *Element); 168 EBML_DLL filepos_t EBML_ElementPositionData(const ebml_element *Element); 169 EBML_DLL filepos_t EBML_ElementPositionEnd(const ebml_element *Element); 170 EBML_DLL void EBML_ElementForcePosition(ebml_element *Element, filepos_t Pos); 171 172 EBML_DLL filepos_t EBML_ElementFullSize(const ebml_element *Element, bool_t bWithDefault); 173 EBML_DLL filepos_t EBML_ElementDataSize(const ebml_element *Element, bool_t bWithDefault); 174 EBML_DLL void EBML_ElementForceDataSize(ebml_element *Element, filepos_t Size); 175 EBML_DLL uint8_t EBML_ElementSizeLength(const ebml_element *Element); 176 EBML_DLL void EBML_ElementSetSizeLength(ebml_element *Element, uint8_t SizeLength); /// 0 (for auto) to EBML_MAX_SIZE 177 178 EBML_DLL bool_t EBML_ElementIsType(const ebml_element *Element, const ebml_context *Context); 179 180 #if defined(CONFIG_EBML_WRITING) 181 // TODO: replace the list of bools by flags ? 182 EBML_DLL err_t EBML_ElementRender(ebml_element *Element, stream *Output, bool_t bWithDefault, bool_t bKeepPosition, bool_t bForceWithoutMandatory, filepos_t *Rendered); 183 EBML_DLL err_t EBML_ElementRenderHead(ebml_element *Element, stream *Output, bool_t bKeepPosition, filepos_t *Rendered); 184 #endif 185 186 // type specific routines 187 EBML_DLL ebml_element *EBML_MasterFindFirstElt(ebml_master *Element, const ebml_context *Context, bool_t bCreateIfNull, bool_t SetDefault); 188 EBML_DLL err_t EBML_MasterAppend(ebml_master *Element, ebml_element *Append); 189 EBML_DLL err_t EBML_MasterRemove(ebml_master *Element, ebml_element *Remove); 190 EBML_DLL ebml_element *EBML_MasterFindNextElt(ebml_master *Element, const ebml_element *Current, bool_t bCreateIfNull, bool_t SetDefault); 191 EBML_DLL ebml_element *EBML_MasterAddElt(ebml_master *Element, const ebml_context *Context, bool_t SetDefault); 192 EBML_DLL size_t EBML_MasterCount(const ebml_master *Element); 193 EBML_DLL void EBML_MasterClear(ebml_master *Element); // clear the list (the children and not freed) 194 EBML_DLL void EBML_MasterErase(ebml_master *Element); 195 EBML_DLL void EBML_MasterAddMandatory(ebml_master *Element, bool_t SetDefault); // add the mandatory elements 196 EBML_DLL bool_t EBML_MasterCheckMandatory(const ebml_master *Element, bool_t bWithDefault); 197 EBML_DLL void EBML_MasterSort(ebml_master *Element, arraycmp Cmp, const void* CmpParam); 198 EBML_DLL bool_t EBML_MasterUseChecksum(ebml_master *Element, bool_t Use); 199 EBML_DLL bool_t EBML_MasterIsChecksumValid(const ebml_master *Element); 200 #define EBML_MasterGetChild(e,c) EBML_MasterFindFirstElt(e,c,1,1) 201 #define EBML_MasterFindChild(e,c) EBML_MasterFindFirstElt((ebml_master*)e,c,0,0) 202 #define EBML_MasterNextChild(e,c) EBML_MasterFindNextElt((ebml_master*)e,(ebml_element*)c,0,0) 203 #define EBML_MasterChildren(p) ((ebml_element*)NodeTree_Children(p)) 204 #define EBML_MasterNext(p) ((ebml_element*)NodeTree_Next(p)) 205 #define EBML_ElementParent(p) ((ebml_element*)NodeTree_Parent(p)) 206 207 EBML_DLL int64_t EBML_IntegerValue(const ebml_integer *Element); 208 EBML_DLL void EBML_IntegerSetValue(ebml_integer *Element, int64_t Value); 209 210 EBML_DLL double EBML_FloatValue(const ebml_float *Element); 211 EBML_DLL void EBML_FloatSetValue(ebml_float *Element, double Value); 212 213 EBML_DLL err_t EBML_StringSetValue(ebml_string *Element,const char *Value); 214 #if defined(CONFIG_EBML_UNICODE) 215 EBML_DLL err_t EBML_UniStringSetValue(ebml_string *Element,const tchar_t *Value); 216 #endif 217 EBML_DLL void EBML_StringGet(ebml_string *Element,tchar_t *Out, size_t OutLen); 218 219 EBML_DLL datetime_t EBML_DateTime(const ebml_date *Element); 220 EBML_DLL err_t EBML_DateSetDateTime(ebml_date *Element, datetime_t Date); 221 222 EBML_DLL err_t EBML_BinarySetData(ebml_binary *Element, const uint8_t *Data, size_t DataSize); 223 EBML_DLL const uint8_t *EBML_BinaryGetData(ebml_binary *Element); 224 225 #if defined(CONFIG_EBML_WRITING) 226 EBML_DLL bool_t EBML_VoidSetFullSize(ebml_element *Void, filepos_t); 227 EBML_DLL filepos_t EBML_VoidReplaceWith(ebml_element *Void, ebml_element *Replaced, stream *Output, bool_t ComeBackAfterward, bool_t bWithDefault); 228 #endif 229 EBML_DLL size_t EBML_FillBufferID(uint8_t *Buffer, size_t BufSize, fourcc_t Id); 230 EBML_DLL size_t EBML_IdToString(tchar_t *Out, size_t OutLen, fourcc_t Id); 231 EBML_DLL fourcc_t EBML_BufferToID(const uint8_t *Buffer); 232 233 #define MASTER_CHECK_PROFILE_INVALID 0 234 #define MASTER_CHECK_MISSING_MANDATORY 1 235 #define MASTER_CHECK_MULTIPLE_UNIQUE 2 236 237 typedef bool_t (*ContextCallback)(void *cookie, int type, const tchar_t *ClassName, const ebml_element*); 238 EBML_DLL void EBML_MasterCheckContext(ebml_master *Element, int ProfileMask, ContextCallback callback, void *cookie); 239 240 #if defined(EBML_LEGACY_API) 241 #define CONTEXT_CONST 242 #else 243 #define CONTEXT_CONST const 244 #endif 245 246 // EBML contexts 247 extern CONTEXT_CONST ebml_context EBML_ContextHead; 248 extern CONTEXT_CONST ebml_context EBML_ContextDummy; 249 extern CONTEXT_CONST ebml_context EBML_ContextVersion; 250 extern CONTEXT_CONST ebml_context EBML_ContextReadVersion; 251 extern CONTEXT_CONST ebml_context EBML_ContextMaxIdLength; 252 extern CONTEXT_CONST ebml_context EBML_ContextMaxSizeLength; 253 extern CONTEXT_CONST ebml_context EBML_ContextDocType; 254 extern CONTEXT_CONST ebml_context EBML_ContextDocTypeVersion; 255 extern CONTEXT_CONST ebml_context EBML_ContextDocTypeReadVersion; 256 257 extern CONTEXT_CONST ebml_context EBML_ContextEbmlVoid; 258 extern CONTEXT_CONST ebml_context EBML_ContextEbmlCrc32; 259 260 //extern const ebml_context EBML_ContextGlobals; 261 extern const ebml_semantic EBML_SemanticGlobals[]; 262 263 #ifdef __cplusplus 264 } 265 #endif 266 267 #endif /* LIBEBML2_H */ 268