1/**************************************************************************** 2** libebml : parse EBML files, see http://embl.sourceforge.net/ 3** 4** <file/class description> 5** 6** Copyright (C) 2002-2005 Steve Lhomme. All rights reserved. 7** 8** This file is part of libebml. 9** 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. 14** 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. 19** 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 23** 24** See http://www.matroska.org/license/lgpl/ for LGPL licensing information. 25** 26** Contact license@matroska.org if any conditions of this licensing are 27** not clear to you. 28** 29**********************************************************************/ 30 31/*! 32 \file 33 \version \$Id: EbmlVoid.cpp 1232 2005-10-15 15:56:52Z robux4 $ 34 \author Steve Lhomme <robux4 @ users.sf.net> 35*/ 36#include "ebml/EbmlVoid.h" 37#include "ebml/EbmlContexts.h" 38 39START_LIBEBML_NAMESPACE 40 41EbmlId EbmlVoid_TheId(0xEC, 1); 42const EbmlCallbacks EbmlVoid::ClassInfos(EbmlVoid::Create, EbmlVoid_TheId, "EBMLVoid", EbmlVoid_Context); 43 44EbmlVoid::EbmlVoid() 45{ 46 bValueIsSet = true; 47} 48 49uint32 EbmlVoid::RenderData(IOCallback & output, bool bForceRender, bool bKeepIntact) 50{ 51 // write dummy data by 4KB chunks 52 static binary DummyBuf[4*1024]; 53 54 uint64 SizeToWrite = Size; 55 while (SizeToWrite > 4*1024) 56 { 57 output.writeFully(DummyBuf, 4*1024); 58 SizeToWrite -= 4*1024; 59 } 60 output.writeFully(DummyBuf, SizeToWrite); 61 return Size; 62} 63 64uint64 EbmlVoid::ReplaceWith(EbmlElement & EltToReplaceWith, IOCallback & output, bool ComeBackAfterward, bool bKeepIntact) 65{ 66 EltToReplaceWith.UpdateSize(bKeepIntact); 67 if (HeadSize() + Size < EltToReplaceWith.GetSize() + EltToReplaceWith.HeadSize()) { 68 // the element can't be written here ! 69 return 0; 70 } 71 if (HeadSize() + Size - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() == 1) { 72 // there is not enough space to put a filling element 73 return 0; 74 } 75 76 uint64 CurrentPosition = output.getFilePointer(); 77 78 output.setFilePointer(GetElementPosition()); 79 EltToReplaceWith.Render(output, bKeepIntact); 80 81 if (HeadSize() + Size - EltToReplaceWith.GetSize() - EltToReplaceWith.HeadSize() > 1) { 82 // fill the rest with another void element 83 EbmlVoid aTmp; 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)); 90 } 91 aTmp.RenderHead(output, false, bKeepIntact); // the rest of the data is not rewritten 92 } 93 94 if (ComeBackAfterward) { 95 output.setFilePointer(CurrentPosition); 96 } 97 98 return Size + HeadSize(); 99} 100 101uint64 EbmlVoid::Overwrite(const EbmlElement & EltToVoid, IOCallback & output, bool ComeBackAfterward, bool bKeepIntact) 102{ 103// EltToVoid.UpdateSize(bKeepIntact); 104 if (EltToVoid.GetElementPosition() == 0) { 105 // this element has never been written 106 return 0; 107 } 108 if (EltToVoid.GetSize() + EltToVoid.HeadSize() <2) { 109 // the element can't be written here ! 110 return 0; 111 } 112 113 uint64 CurrentPosition = output.getFilePointer(); 114 115 output.setFilePointer(EltToVoid.GetElementPosition()); 116 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()) { 124 Size--; 125 SetSizeLength(CodedSizeLength(Size, SizeLength, bSizeIsFinite) + 1); 126 } 127 128 if (Size != 0) { 129 RenderHead(output, false, bKeepIntact); // the rest of the data is not rewritten 130 } 131 132 if (ComeBackAfterward) { 133 output.setFilePointer(CurrentPosition); 134 } 135 136 return EltToVoid.GetSize() + EltToVoid.HeadSize(); 137} 138 139END_LIBEBML_NAMESPACE 140