1 /****************************************************************************
2 ** libebml : parse EBML files, see http://embl.sourceforge.net/
4 ** <file/class description>
6 ** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved.
8 ** This file is part of libebml.
10 ** This library is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU Lesser General Public
12 ** License as published by the Free Software Foundation; either
13 ** version 2.1 of the License, or (at your option) any later version.
15 ** This library is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** Lesser General Public License for more details.
20 ** You should have received a copy of the GNU Lesser General Public
21 ** License along with this library; if not, write to the Free Software
22 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ** See http://www.matroska.org/license/lgpl/ for LGPL licensing information.
26 ** Contact license@matroska.org if any conditions of this licensing are
29 **********************************************************************/
33 \version \$Id: EbmlVoid.cpp 1232 2005-10-15 15:56:52Z robux4 $
34 \author Steve Lhomme <robux4 @ users.sf.net>
36 #include "ebml/EbmlVoid.h"
37 #include "ebml/EbmlContexts.h"
39 START_LIBEBML_NAMESPACE
41 EbmlId
EbmlVoid_TheId(0xEC, 1);
42 const EbmlCallbacks
EbmlVoid::ClassInfos(EbmlVoid::Create
, EbmlVoid_TheId
, "EBMLVoid", EbmlVoid_Context
);
49 uint32
EbmlVoid::RenderData(IOCallback
& output
, bool bForceRender
, bool bKeepIntact
)
51 // write dummy data by 4KB chunks
52 static binary DummyBuf
[4*1024];
54 uint64 SizeToWrite
= Size
;
55 while (SizeToWrite
> 4*1024)
57 output
.writeFully(DummyBuf
, 4*1024);
58 SizeToWrite
-= 4*1024;
60 output
.writeFully(DummyBuf
, SizeToWrite
);
64 uint64
EbmlVoid::ReplaceWith(EbmlElement
& EltToReplaceWith
, IOCallback
& output
, bool ComeBackAfterward
, bool bKeepIntact
)
66 EltToReplaceWith
.UpdateSize(bKeepIntact
);
67 if (HeadSize() + Size
< EltToReplaceWith
.GetSize() + EltToReplaceWith
.HeadSize()) {
68 // the element can't be written here !
71 if (HeadSize() + Size
- EltToReplaceWith
.GetSize() - EltToReplaceWith
.HeadSize() == 1) {
72 // there is not enough space to put a filling element
76 uint64 CurrentPosition
= output
.getFilePointer();
78 output
.setFilePointer(GetElementPosition());
79 EltToReplaceWith
.Render(output
, bKeepIntact
);
81 if (HeadSize() + Size
- EltToReplaceWith
.GetSize() - EltToReplaceWith
.HeadSize() > 1) {
82 // fill the rest with another void element
84 aTmp
.SetSize(HeadSize() + Size
- EltToReplaceWith
.GetSize() - EltToReplaceWith
.HeadSize() - 1); // 1 is the length of the Void ID
85 int HeadBefore
= aTmp
.HeadSize();
86 aTmp
.SetSize(aTmp
.GetSize() - CodedSizeLength(aTmp
.Size
, aTmp
.SizeLength
, aTmp
.bSizeIsFinite
));
87 int HeadAfter
= aTmp
.HeadSize();
88 if (HeadBefore
!= HeadAfter
) {
89 aTmp
.SetSizeLength(CodedSizeLength(aTmp
.Size
, aTmp
.SizeLength
, aTmp
.bSizeIsFinite
) - (HeadAfter
- HeadBefore
));
91 aTmp
.RenderHead(output
, false, bKeepIntact
); // the rest of the data is not rewritten
94 if (ComeBackAfterward
) {
95 output
.setFilePointer(CurrentPosition
);
98 return Size
+ HeadSize();
101 uint64
EbmlVoid::Overwrite(const EbmlElement
& EltToVoid
, IOCallback
& output
, bool ComeBackAfterward
, bool bKeepIntact
)
103 // EltToVoid.UpdateSize(bKeepIntact);
104 if (EltToVoid
.GetElementPosition() == 0) {
105 // this element has never been written
108 if (EltToVoid
.GetSize() + EltToVoid
.HeadSize() <2) {
109 // the element can't be written here !
113 uint64 CurrentPosition
= output
.getFilePointer();
115 output
.setFilePointer(EltToVoid
.GetElementPosition());
117 // compute the size of the voided data based on the original one
118 Size
= EltToVoid
.GetSize() + EltToVoid
.HeadSize() - 1; // 1 for the ID
119 Size
-= CodedSizeLength(Size
, SizeLength
, bSizeIsFinite
);
120 // make sure we handle even the strange cases
121 //uint32 A1 = Size + HeadSize();
122 //uint32 A2 = EltToVoid.GetSize() + EltToVoid.HeadSize();
123 if (Size
+ HeadSize() != EltToVoid
.GetSize() + EltToVoid
.HeadSize()) {
125 SetSizeLength(CodedSizeLength(Size
, SizeLength
, bSizeIsFinite
) + 1);
129 RenderHead(output
, false, bKeepIntact
); // the rest of the data is not rewritten
132 if (ComeBackAfterward
) {
133 output
.setFilePointer(CurrentPosition
);
136 return EltToVoid
.GetSize() + EltToVoid
.HeadSize();
139 END_LIBEBML_NAMESPACE