1/* 2 * Copyright (c) 2005, David McPaul 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * * Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23 * OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25#include <stdio.h> 26 27#include "MOVAtom.h" 28 29AtomBase::AtomBase(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) 30{ 31 theStream = pStream; 32 streamOffset = pstreamOffset; 33 atomType = patomType; 34 atomSize = patomSize; 35 parentAtom = NULL; 36} 37 38AtomBase::~AtomBase() 39{ 40 theStream = NULL; 41 parentAtom = NULL; 42} 43 44char *AtomBase::getAtomName() 45{ 46 char *_result; 47 _result = OnGetAtomName(); 48 if (_result) { 49 return _result; 50 } 51 52 fourcc[0] = (char)((atomType >> 24) & 0xff); 53 fourcc[1] = (char)((atomType >> 16) & 0xff); 54 fourcc[2] = (char)((atomType >> 8) & 0xff); 55 fourcc[3] = (char)((atomType >> 0) & 0xff); 56 fourcc[4] = '\0'; 57 58 return fourcc; 59} 60 61char *AtomBase::OnGetAtomName() 62{ 63 return NULL; 64} 65 66void AtomBase::ProcessMetaData() 67// ProcessMetaData() - Reads in the basic Atom Meta Data 68// - Calls OnProcessMetaData() 69// - Calls ProcessMetaData on each child atom 70// (ensures stream is correct for child via offset) 71{ 72 setAtomOffset(getStream()->Position()); 73 74 OnProcessMetaData(); 75 76 MoveToEnd(); 77} 78 79void AtomBase::OnProcessMetaData() 80{ 81 MoveToEnd(); 82} 83 84bool AtomBase::MoveToEnd() 85{ 86 off_t NewPosition = streamOffset + atomSize; 87 88 if (getStream()->Position() != NewPosition) { 89 return (getStream()->Seek(NewPosition,SEEK_SET) > 0); 90 } 91 return true; 92} 93 94uint64 AtomBase::getBytesRemaining() 95{ 96 off_t EndPosition = streamOffset + atomSize; 97 98 return (EndPosition - getStream()->Position()); 99} 100 101void AtomBase::DisplayAtoms() 102{ 103 uint32 aindent = 0; 104 DisplayAtoms(aindent); 105} 106 107void AtomBase::DisplayAtoms(uint32 pindent) 108{ 109 Indent(pindent); 110 printf("%s\n",getAtomName()); 111} 112 113void AtomBase::Indent(uint32 pindent) 114{ 115 for (uint32 i=0;i<pindent;i++) { 116 printf("-"); 117 } 118} 119 120bool AtomBase::IsKnown() 121{ 122 return (OnGetAtomName() != NULL); 123} 124 125void AtomBase::ReadArrayHeader(array_header *pHeader) 126{ 127 Read(&pHeader->Version); 128 Read(&pHeader->Flags1); 129 Read(&pHeader->Flags2); 130 Read(&pHeader->Flags3); 131 Read(&pHeader->NoEntries); 132} 133 134BPositionIO *AtomBase::OnGetStream() 135{ 136 // default implementation 137 return theStream; 138} 139 140BPositionIO *AtomBase::getStream() 141{ 142 return OnGetStream(); 143} 144 145void AtomBase::Read(uint64 *value) 146{ 147 uint32 bytes_read; 148 149 bytes_read = getStream()->Read(value,sizeof(uint64)); 150 151 // Assert((bytes_read == sizeof(uint64),"Read Error"); 152 153 *value = B_BENDIAN_TO_HOST_INT64(*value); 154} 155 156void AtomBase::Read(uint32 *value) 157{ 158 uint32 bytes_read; 159 160 bytes_read = getStream()->Read(value,sizeof(uint32)); 161 162 // Assert((bytes_read == sizeof(uint32),"Read Error"); 163 164 *value = B_BENDIAN_TO_HOST_INT32(*value); 165} 166 167void AtomBase::Read(uint16 *value) 168{ 169 uint32 bytes_read; 170 171 bytes_read = getStream()->Read(value,sizeof(uint16)); 172 173 // Assert((bytes_read == sizeof(uint16),"Read Error"); 174 175 *value = B_BENDIAN_TO_HOST_INT16(*value); 176} 177 178void AtomBase::Read(uint8 *value) 179{ 180 uint32 bytes_read; 181 182 bytes_read = getStream()->Read(value,sizeof(uint8)); 183 184 // Assert((bytes_read == sizeof(uint8),"Read Error"); 185} 186 187void AtomBase::Read(char *value, uint32 maxread) 188{ 189 uint32 bytes_read; 190 191 bytes_read = getStream()->Read(value,maxread); 192 193 // Assert((bytes_read == maxread,"Read Error"); 194} 195 196void AtomBase::Read(uint8 *value, uint32 maxread) 197{ 198 uint32 bytes_read; 199 200 bytes_read = getStream()->Read(value,maxread); 201 202 // Assert((bytes_read == maxread,"Read Error"); 203} 204 205AtomContainer::AtomContainer(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize) 206{ 207 TotalChildren = 0; 208} 209 210AtomContainer::~AtomContainer() 211{ 212} 213 214void AtomContainer::DisplayAtoms(uint32 pindent) 215{ 216 Indent(pindent); 217 printf("%ld:%s\n",TotalChildren,getAtomName()); 218 pindent++; 219 // for each child 220 for (uint32 i = 0;i < TotalChildren;i++) { 221 atomChildren[i]->DisplayAtoms(pindent); 222 } 223 224} 225 226void AtomContainer::ProcessMetaData() 227{ 228 setAtomOffset(getStream()->Position()); 229 230 OnProcessMetaData(); 231 232 AtomBase *aChild; 233 while (IsEndOfAtom() == false) { 234 aChild = getAtom(getStream()); 235 if (AddChild(aChild)) { 236 aChild->ProcessMetaData(); 237 } 238 } 239 240 OnChildProcessingComplete(); 241 242 MoveToEnd(); 243} 244 245bool AtomContainer::AddChild(AtomBase *pChildAtom) 246{ 247 if (pChildAtom) { 248 pChildAtom->setParent(this); 249 atomChildren[TotalChildren++] = pChildAtom; 250 return true; 251 } 252 return false; 253} 254 255AtomBase *AtomContainer::GetChildAtom(uint32 patomType, uint32 offset) 256{ 257 for (uint32 i=0;i<TotalChildren;i++) { 258 if (atomChildren[i]->IsType(patomType)) { 259 // found match, skip if offset non zero. 260 if (offset == 0) { 261 return atomChildren[i]; 262 } else { 263 offset--; 264 } 265 } else { 266 if (atomChildren[i]->IsContainer()) { 267 // search container 268 AtomBase *aAtomBase = (dynamic_cast<AtomContainer *>(atomChildren[i])->GetChildAtom(patomType, offset)); 269 if (aAtomBase) { 270 // found in container 271 return aAtomBase; 272 } 273 // not found 274 } 275 } 276 } 277 return NULL; 278} 279 280void AtomContainer::OnProcessMetaData() 281{ 282} 283