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