2 * Copyright (c) 2005, David McPaul
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.
32 AtomBase::AtomBase(BPositionIO
*pStream
, off_t pstreamOffset
, uint32 patomType
,
36 streamOffset
= pstreamOffset
;
51 AtomBase::GetAtomTypeAsFourcc()
53 fourcc
[0] = (char)((atomType
>> 24) & 0xff);
54 fourcc
[1] = (char)((atomType
>> 16) & 0xff);
55 fourcc
[2] = (char)((atomType
>> 8) & 0xff);
56 fourcc
[3] = (char)((atomType
>> 0) & 0xff);
64 AtomBase::GetAtomName()
67 _result
= OnGetAtomName();
72 fourcc
[0] = (char)((atomType
>> 24) & 0xff);
73 fourcc
[1] = (char)((atomType
>> 16) & 0xff);
74 fourcc
[2] = (char)((atomType
>> 8) & 0xff);
75 fourcc
[3] = (char)((atomType
>> 0) & 0xff);
83 AtomBase::OnGetAtomName()
90 AtomBase::ProcessMetaData()
91 // ProcessMetaData() - Reads in the basic Atom Meta Data
92 // - Calls OnProcessMetaData()
93 // - Calls ProcessMetaData on each child atom
94 // (ensures stream is correct for child via offset)
96 SetAtomOffset(GetStream()->Position());
105 AtomBase::OnProcessMetaData()
112 AtomBase::MoveToEnd()
114 off_t NewPosition
= streamOffset
+ atomSize
;
116 if (GetStream()->Position() != NewPosition
) {
117 return (GetStream()->Seek(NewPosition
,0) > 0);
124 AtomBase::GetBytesRemaining()
126 off_t EndPosition
= streamOffset
+ atomSize
;
127 off_t CurrPosition
= GetStream()->Position();
129 if (CurrPosition
> EndPosition
) {
130 printf("ERROR: Read past atom boundary by %Ld bytes\n",
131 CurrPosition
- EndPosition
);
135 return (EndPosition
- CurrPosition
);
140 AtomBase::DisplayAtoms()
143 DisplayAtoms(aindent
);
148 AtomBase::DisplayAtoms(uint32 pindent
)
151 printf("(%s)\n",GetAtomName());
156 AtomBase::Indent(uint32 pindent
)
158 for (uint32 i
=0;i
<pindent
;i
++) {
167 return (OnGetAtomName() != NULL
);
172 AtomBase::ReadArrayHeader(array_header
*pHeader
)
174 Read(&pHeader
->NoEntries
);
179 AtomBase::OnGetStream()
181 // default implementation
187 AtomBase::GetStream()
189 return OnGetStream();
194 AtomBase::Read(uint64
*value
)
198 bytes_read
= GetStream()->Read(value
,sizeof(uint64
));
200 // Assert((bytes_read == sizeof(uint64),"Read Error");
202 *value
= B_BENDIAN_TO_HOST_INT64(*value
);
207 AtomBase::Read(uint32
*value
)
211 bytes_read
= GetStream()->Read(value
,sizeof(uint32
));
213 // Assert((bytes_read == sizeof(uint32),"Read Error");
215 *value
= B_BENDIAN_TO_HOST_INT32(*value
);
220 AtomBase::Read(int32
*value
)
224 bytes_read
= GetStream()->Read(value
,sizeof(int32
));
226 // Assert((bytes_read == sizeof(int32),"Read Error");
228 *value
= B_BENDIAN_TO_HOST_INT32(*value
);
233 AtomBase::Read(uint16
*value
)
237 bytes_read
= GetStream()->Read(value
,sizeof(uint16
));
239 // Assert((bytes_read == sizeof(uint16),"Read Error");
241 *value
= B_BENDIAN_TO_HOST_INT16(*value
);
246 AtomBase::Read(uint8
*value
)
250 bytes_read
= GetStream()->Read(value
,sizeof(uint8
));
252 // Assert((bytes_read == sizeof(uint8),"Read Error");
257 AtomBase::Read(char *value
, uint32 maxread
)
261 bytes_read
= GetStream()->Read(value
,maxread
);
263 // Assert((bytes_read == maxread,"Read Error");
268 AtomBase::Read(uint8
*value
, uint32 maxread
)
272 bytes_read
= GetStream()->Read(value
,maxread
);
274 // Assert((bytes_read == maxread,"Read Error");
279 AtomBase::GetBits(uint64 buffer
, uint8 startBit
, uint8 totalBits
)
281 // startBit should range from 0-63, totalBits should range from 1-64
282 if ((startBit
< 64) && (totalBits
> 0) && (totalBits
<= 64)
283 && (startBit
+ totalBits
<= 64)) {
284 // Ok pull from the buffer the bits wanted.
285 buffer
= buffer
<< startBit
;
286 buffer
= buffer
>> (64 - (totalBits
+ startBit
) + startBit
);
296 AtomBase::GetBits(uint32 buffer
, uint8 startBit
, uint8 totalBits
)
298 // startBit should range from 0-31, totalBits should range from 1-32
299 if ((startBit
< 32) && (totalBits
> 0) && (totalBits
<= 32)
300 && (startBit
+ totalBits
<= 32)) {
301 // Ok pull from the buffer the bits wanted.
302 buffer
= buffer
<< startBit
;
303 buffer
= buffer
>> (32 - (startBit
+ totalBits
) + startBit
);
312 FullAtom::FullAtom(BPositionIO
*pStream
, off_t pstreamOffset
, uint32 patomType
,
315 AtomBase(pStream
, pstreamOffset
, patomType
, patomSize
)
320 FullAtom::~FullAtom()
326 FullAtom::OnProcessMetaData()
335 AtomContainer::AtomContainer(BPositionIO
*pStream
, off_t pstreamOffset
,
336 uint32 patomType
, uint64 patomSize
)
338 AtomBase(pStream
, pstreamOffset
, patomType
, patomSize
)
344 AtomContainer::~AtomContainer()
350 AtomContainer::DisplayAtoms(uint32 pindent
)
353 printf("%ld:(%s)\n",TotalChildren
,GetAtomName());
356 for (uint32 i
= 0;i
< TotalChildren
;i
++) {
357 atomChildren
[i
]->DisplayAtoms(pindent
);
364 AtomContainer::ProcessMetaData()
366 SetAtomOffset(GetStream()->Position());
371 while (IsEndOfAtom() == false) {
372 aChild
= GetAtom(GetStream());
373 if (AddChild(aChild
)) {
374 aChild
->ProcessMetaData();
378 OnChildProcessingComplete();
385 AtomContainer::AddChild(AtomBase
*pChildAtom
)
388 pChildAtom
->SetParent(this);
389 atomChildren
.push_back(pChildAtom
);
397 AtomBase
*AtomContainer::GetChildAtom(uint32 patomType
, uint32 offset
)
399 for (uint32 i
=0;i
<TotalChildren
;i
++) {
400 if (atomChildren
[i
]->IsType(patomType
)) {
401 // found match, skip if offset non zero.
403 return atomChildren
[i
];
408 if (atomChildren
[i
]->IsContainer()) {
410 AtomBase
*aAtomBase
= dynamic_cast<AtomContainer
*>
411 (atomChildren
[i
])->GetChildAtom(patomType
, offset
);
413 // found in container
425 AtomContainer::OnProcessMetaData()