1 /*
2 * $Id$
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 #include "ebml/ebml.h"
29 #include "ebml/ebml_internal.h"
30
ReadData(ebml_binary * Element,stream * Input,const ebml_parser_context * ParserContext,bool_t AllowDummyElt,int Scope,size_t DepthCheckCRC)31 static err_t ReadData(ebml_binary *Element, stream *Input, const ebml_parser_context *ParserContext, bool_t AllowDummyElt, int Scope, size_t DepthCheckCRC)
32 {
33 err_t Result;
34
35 Element->Base.bValueIsSet = 0;
36
37 if (Scope == SCOPE_NO_DATA)
38 return ERR_NONE;
39
40 if (Stream_Seek(Input,EBML_ElementPositionData((ebml_element*)Element),SEEK_SET)==INVALID_FILEPOS_T)
41 {
42 Result = ERR_READ;
43 goto failed;
44 }
45
46 if (!ArrayResize(&Element->Data,(size_t)Element->Base.DataSize,0))
47 {
48 Result = ERR_OUT_OF_MEMORY;
49 goto failed;
50 }
51
52 Result = Stream_Read(Input,ARRAYBEGIN(Element->Data,void),(size_t)Element->Base.DataSize,NULL);
53 if (Result == ERR_NONE)
54 Element->Base.bValueIsSet = 1;
55 failed:
56 return Result;
57 }
58
59 #if defined(CONFIG_EBML_WRITING)
RenderData(ebml_binary * Element,stream * Output,bool_t bForceWithoutMandatory,bool_t bWithDefault,filepos_t * Rendered)60 static err_t RenderData(ebml_binary *Element, stream *Output, bool_t bForceWithoutMandatory, bool_t bWithDefault, filepos_t *Rendered)
61 {
62 size_t Written;
63 err_t Err = Stream_Write(Output,ARRAYBEGIN(Element->Data,uint8_t),ARRAYCOUNT(Element->Data,uint8_t),&Written);
64 if (Rendered)
65 *Rendered = Written;
66 return Err;
67 }
68 #endif
69
Delete(ebml_binary * Element)70 static void Delete(ebml_binary *Element)
71 {
72 ArrayClear(&Element->Data);
73 }
74
IsDefaultValue(const ebml_binary * Element)75 static bool_t IsDefaultValue(const ebml_binary *Element)
76 {
77 return 0; // TODO: a default binary value needs a size too (use a structure to set the value in the structure)
78 }
79
UpdateDataSize(ebml_binary * Element,bool_t bWithDefault,bool_t bForceWithoutMandatory)80 static filepos_t UpdateDataSize(ebml_binary *Element, bool_t bWithDefault, bool_t bForceWithoutMandatory)
81 {
82 Element->Base.DataSize = ARRAYCOUNT(Element->Data,uint8_t);
83
84 return INHERITED(Element,ebml_element_vmt,EBML_BINARY_CLASS)->UpdateDataSize(Element, bWithDefault, bForceWithoutMandatory);
85 }
86
ValidateSize(const ebml_element * p)87 static bool_t ValidateSize(const ebml_element *p)
88 {
89 return EBML_ElementIsFiniteSize(p);
90 }
91
Copy(const ebml_binary * Element,const void * Cookie)92 static ebml_binary *Copy(const ebml_binary *Element, const void *Cookie)
93 {
94 ebml_binary *Result = (ebml_binary*)EBML_ElementCreate(Element,Element->Base.Context,0,Cookie);
95 if (Result)
96 {
97 ArrayCopy(&Result->Data,&Element->Data);
98 Result->Base.bValueIsSet = Element->Base.bValueIsSet;
99 Result->Base.DataSize = Element->Base.DataSize;
100 Result->Base.ElementPosition = Element->Base.ElementPosition;
101 Result->Base.SizeLength = Element->Base.SizeLength;
102 Result->Base.SizePosition = Element->Base.SizePosition;
103 Result->Base.bNeedDataSizeUpdate = Element->Base.bNeedDataSizeUpdate;
104 }
105 return Result;
106 }
107
META_START(EBMLBinary_Class,EBML_BINARY_CLASS)108 META_START(EBMLBinary_Class,EBML_BINARY_CLASS)
109 META_CLASS(SIZE,sizeof(ebml_binary))
110 META_CLASS(DELETE,Delete)
111 META_DATA(TYPE_ARRAY,0,ebml_binary,Data)
112 META_VMT(TYPE_FUNC,ebml_element_vmt,ValidateSize,ValidateSize)
113 META_VMT(TYPE_FUNC,ebml_element_vmt,ReadData,ReadData)
114 META_VMT(TYPE_FUNC,ebml_element_vmt,IsDefaultValue,IsDefaultValue)
115 META_VMT(TYPE_FUNC,ebml_element_vmt,UpdateDataSize,UpdateDataSize)
116 #if defined(CONFIG_EBML_WRITING)
117 META_VMT(TYPE_FUNC,ebml_element_vmt,RenderData,RenderData)
118 #endif
119 META_VMT(TYPE_FUNC,ebml_element_vmt,Copy,Copy)
120 META_END(EBML_ELEMENT_CLASS)
121
122 err_t EBML_BinarySetData(ebml_binary *Element, const uint8_t *Data, size_t DataSize)
123 {
124 if (!ArrayResize(&Element->Data,DataSize,0))
125 return ERR_OUT_OF_MEMORY;
126 memcpy(ARRAYBEGIN(Element->Data,void),Data,DataSize);
127 Element->Base.DataSize = DataSize;
128 Element->Base.bNeedDataSizeUpdate = 0;
129 Element->Base.bValueIsSet = 1;
130 return ERR_NONE;
131 }
132
EBML_BinaryGetData(ebml_binary * Element)133 const uint8_t *EBML_BinaryGetData(ebml_binary *Element)
134 {
135 if (!ARRAYCOUNT(Element->Data,uint8_t))
136 return NULL;
137 return ARRAYBEGIN(Element->Data,uint8_t);
138 }
139