vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / media / plugins / mov_reader / libMOV / MOVAtom.cpp
blob2d859aa4d36e9ed99e6bf8678c2356673900cd43
1 /*
2 * Copyright (c) 2005, David McPaul
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
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.
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.
25 #include <stdio.h>
27 #include "MOVAtom.h"
29 AtomBase::AtomBase(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize)
31 theStream = pStream;
32 streamOffset = pstreamOffset;
33 atomType = patomType;
34 atomSize = patomSize;
35 parentAtom = NULL;
38 AtomBase::~AtomBase()
40 theStream = NULL;
41 parentAtom = NULL;
44 char *AtomBase::getAtomName()
46 char *_result;
47 _result = OnGetAtomName();
48 if (_result) {
49 return _result;
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';
58 return fourcc;
61 char *AtomBase::OnGetAtomName()
63 return NULL;
66 void 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)
72 setAtomOffset(getStream()->Position());
74 OnProcessMetaData();
76 MoveToEnd();
79 void AtomBase::OnProcessMetaData()
81 MoveToEnd();
84 bool AtomBase::MoveToEnd()
86 off_t NewPosition = streamOffset + atomSize;
88 if (getStream()->Position() != NewPosition) {
89 return (getStream()->Seek(NewPosition,SEEK_SET) > 0);
91 return true;
94 uint64 AtomBase::getBytesRemaining()
96 off_t EndPosition = streamOffset + atomSize;
98 return (EndPosition - getStream()->Position());
101 void AtomBase::DisplayAtoms()
103 uint32 aindent = 0;
104 DisplayAtoms(aindent);
107 void AtomBase::DisplayAtoms(uint32 pindent)
109 Indent(pindent);
110 printf("%s\n",getAtomName());
113 void AtomBase::Indent(uint32 pindent)
115 for (uint32 i=0;i<pindent;i++) {
116 printf("-");
120 bool AtomBase::IsKnown()
122 return (OnGetAtomName() != NULL);
125 void AtomBase::ReadArrayHeader(array_header *pHeader)
127 Read(&pHeader->Version);
128 Read(&pHeader->Flags1);
129 Read(&pHeader->Flags2);
130 Read(&pHeader->Flags3);
131 Read(&pHeader->NoEntries);
134 BPositionIO *AtomBase::OnGetStream()
136 // default implementation
137 return theStream;
140 BPositionIO *AtomBase::getStream()
142 return OnGetStream();
145 void AtomBase::Read(uint64 *value)
147 uint32 bytes_read;
149 bytes_read = getStream()->Read(value,sizeof(uint64));
151 // Assert((bytes_read == sizeof(uint64),"Read Error");
153 *value = B_BENDIAN_TO_HOST_INT64(*value);
156 void AtomBase::Read(uint32 *value)
158 uint32 bytes_read;
160 bytes_read = getStream()->Read(value,sizeof(uint32));
162 // Assert((bytes_read == sizeof(uint32),"Read Error");
164 *value = B_BENDIAN_TO_HOST_INT32(*value);
167 void AtomBase::Read(uint16 *value)
169 uint32 bytes_read;
171 bytes_read = getStream()->Read(value,sizeof(uint16));
173 // Assert((bytes_read == sizeof(uint16),"Read Error");
175 *value = B_BENDIAN_TO_HOST_INT16(*value);
178 void AtomBase::Read(uint8 *value)
180 uint32 bytes_read;
182 bytes_read = getStream()->Read(value,sizeof(uint8));
184 // Assert((bytes_read == sizeof(uint8),"Read Error");
187 void AtomBase::Read(char *value, uint32 maxread)
189 uint32 bytes_read;
191 bytes_read = getStream()->Read(value,maxread);
193 // Assert((bytes_read == maxread,"Read Error");
196 void AtomBase::Read(uint8 *value, uint32 maxread)
198 uint32 bytes_read;
200 bytes_read = getStream()->Read(value,maxread);
202 // Assert((bytes_read == maxread,"Read Error");
205 AtomContainer::AtomContainer(BPositionIO *pStream, off_t pstreamOffset, uint32 patomType, uint64 patomSize) : AtomBase(pStream, pstreamOffset, patomType, patomSize)
207 TotalChildren = 0;
210 AtomContainer::~AtomContainer()
214 void AtomContainer::DisplayAtoms(uint32 pindent)
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);
226 void AtomContainer::ProcessMetaData()
228 setAtomOffset(getStream()->Position());
230 OnProcessMetaData();
232 AtomBase *aChild;
233 while (IsEndOfAtom() == false) {
234 aChild = getAtom(getStream());
235 if (AddChild(aChild)) {
236 aChild->ProcessMetaData();
240 OnChildProcessingComplete();
242 MoveToEnd();
245 bool AtomContainer::AddChild(AtomBase *pChildAtom)
247 if (pChildAtom) {
248 pChildAtom->setParent(this);
249 atomChildren[TotalChildren++] = pChildAtom;
250 return true;
252 return false;
255 AtomBase *AtomContainer::GetChildAtom(uint32 patomType, uint32 offset)
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--;
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;
273 // not found
277 return NULL;
280 void AtomContainer::OnProcessMetaData()