Ap4ByteStream.cpp

00001 /*****************************************************************
00002 |
00003 |    AP4 - Byte Stream support
00004 |
00005 |    Copyright 2002 Gilles Boccon-Gibod
00006 |
00007 |
00008 |    This file is part of Bento4/AP4 (MP4 Atom Processing Library).
00009 |
00010 |    Unless you have obtained Bento4 under a difference license,
00011 |    this version of Bento4 is Bento4|GPL.
00012 |    Bento4|GPL is free software; you can redistribute it and/or modify
00013 |    it under the terms of the GNU General Public License as published by
00014 |    the Free Software Foundation; either version 2, or (at your option)
00015 |    any later version.
00016 |
00017 |    Bento4|GPL is distributed in the hope that it will be useful,
00018 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 |    GNU General Public License for more details.
00021 |
00022 |    You should have received a copy of the GNU General Public License
00023 |    along with Bento4|GPL; see the file COPYING.  If not, write to the
00024 |    Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
00025 |    02111-1307, USA.  
00026 |
00027  ****************************************************************/
00028 
00029 /*----------------------------------------------------------------------
00030 |       includes
00031 +---------------------------------------------------------------------*/
00032 #include "Ap4ByteStream.h"
00033 #include "Ap4Utils.h"
00034 #include "Ap4Debug.h"
00035 
00036 /*----------------------------------------------------------------------
00037 |       constants
00038 +---------------------------------------------------------------------*/
00039 const int AP4_BYTE_STREAM_COPY_BUFFER_SIZE = 4096;
00040 
00041 /*----------------------------------------------------------------------
00042 |       AP4_ByteStream::WriteString
00043 +---------------------------------------------------------------------*/
00044 AP4_Result
00045 AP4_ByteStream::WriteString(const char* buffer)
00046 {
00047     AP4_Size string_length = static_cast<AP4_Size>(strlen(buffer));
00048 
00049     // shortcut
00050     if ((buffer == NULL) || (string_length == 0)) return AP4_SUCCESS;
00051 
00052     // write the string
00053     return Write((const void*)buffer, string_length);
00054 }
00055 
00056 /*----------------------------------------------------------------------
00057 |       AP4_ByteStream::WriteUI64
00058 +---------------------------------------------------------------------*/
00059 AP4_Result
00060 AP4_ByteStream::WriteUI64(AP4_UI64 value)
00061 {
00062     unsigned char buffer[8];
00063 
00064     // convert value to bytes
00065     AP4_BytesFromUInt64BE(buffer, value);
00066 
00067     // write bytes to the stream
00068     return Write((void*)buffer, 8);
00069 }
00070 
00071 /*----------------------------------------------------------------------
00072 |       AP4_ByteStream::WriteUI32
00073 +---------------------------------------------------------------------*/
00074 AP4_Result
00075 AP4_ByteStream::WriteUI32(AP4_UI32 value)
00076 {
00077     unsigned char buffer[4];
00078 
00079     // convert value to bytes
00080     AP4_BytesFromUInt32BE(buffer, value);
00081 
00082     // write bytes to the stream
00083     return Write((void*)buffer, 4);
00084 }
00085 
00086 /*----------------------------------------------------------------------
00087 |       AP4_ByteStream::WriteUI24
00088 +---------------------------------------------------------------------*/
00089 AP4_Result
00090 AP4_ByteStream::WriteUI24(AP4_UI32 value)
00091 {
00092     unsigned char buffer[3];
00093 
00094     // convert value to bytes
00095     AP4_BytesFromUInt24BE(buffer, value);
00096 
00097     // write bytes to the stream
00098     return Write((void*)buffer, 3);
00099 }
00100 
00101 /*----------------------------------------------------------------------
00102 |       AP4_ByteStream::WriteUI16
00103 +---------------------------------------------------------------------*/
00104 AP4_Result
00105 AP4_ByteStream::WriteUI16(AP4_UI16 value)
00106 {
00107     unsigned char buffer[2];
00108 
00109     // convert value to bytes
00110     AP4_BytesFromUInt16BE(buffer, value);
00111 
00112     // write bytes to the stream
00113     return Write((void*)buffer, 2);
00114 }
00115 
00116 /*----------------------------------------------------------------------
00117 |       AP4_ByteStream::WriteUI08
00118 +---------------------------------------------------------------------*/
00119 AP4_Result
00120 AP4_ByteStream::WriteUI08(AP4_UI08 value)
00121 {
00122     return Write((void*)&value, 1);
00123 }
00124 
00125 /*----------------------------------------------------------------------
00126 |       AP4_ByteStream::ReadUI64
00127 +---------------------------------------------------------------------*/
00128 AP4_Result
00129 AP4_ByteStream::ReadUI64(AP4_UI64& value)
00130 {
00131     unsigned char buffer[8];
00132 
00133     // read bytes from the stream
00134     AP4_Result result;
00135     result = Read((void*)buffer, 8);
00136     if (AP4_FAILED(result)) {
00137         value = 0;
00138         return result;
00139     }
00140 
00141     // convert bytes to value
00142     value = AP4_BytesToUInt64BE(buffer);
00143     
00144     return AP4_SUCCESS;
00145 }
00146 
00147 /*----------------------------------------------------------------------
00148 |       AP4_ByteStream::ReadUI32
00149 +---------------------------------------------------------------------*/
00150 AP4_Result
00151 AP4_ByteStream::ReadUI32(AP4_UI32& value)
00152 {
00153     unsigned char buffer[4];
00154 
00155     // read bytes from the stream
00156     AP4_Result result;
00157     result = Read((void*)buffer, 4);
00158     if (AP4_FAILED(result)) {
00159         value = 0;
00160         return result;
00161     }
00162 
00163     // convert bytes to value
00164     value = AP4_BytesToUInt32BE(buffer);
00165     
00166     return AP4_SUCCESS;
00167 }
00168 
00169 /*----------------------------------------------------------------------
00170 |       AP4_ByteStream::ReadUI24
00171 +---------------------------------------------------------------------*/
00172 AP4_Result
00173 AP4_ByteStream::ReadUI24(AP4_UI32& value)
00174 {
00175     unsigned char buffer[3];
00176 
00177     // read bytes from the stream
00178     AP4_Result result;
00179     result = Read((void*)buffer, 3);
00180     if (AP4_FAILED(result)) {
00181         value = 0;
00182         return result;
00183     }
00184 
00185     // convert bytes to value
00186     value = AP4_BytesToUInt24BE(buffer);
00187     
00188     return AP4_SUCCESS;
00189 }
00190 
00191 /*----------------------------------------------------------------------
00192 |       AP4_ByteStream::ReadUI16
00193 +---------------------------------------------------------------------*/
00194 AP4_Result
00195 AP4_ByteStream::ReadUI16(AP4_UI16& value)
00196 {
00197     unsigned char buffer[2];
00198 
00199     // read bytes from the stream
00200     AP4_Result result;
00201     result = Read((void*)buffer, 2);
00202     if (AP4_FAILED(result)) {
00203         value = 0;
00204         return result;
00205     }
00206 
00207     // convert bytes to value
00208     value = AP4_BytesToUInt16BE(buffer);
00209     
00210     return AP4_SUCCESS;
00211 }
00212 
00213 /*----------------------------------------------------------------------
00214 |       AP4_ByteStream::ReadUI08
00215 +---------------------------------------------------------------------*/
00216 AP4_Result
00217 AP4_ByteStream::ReadUI08(AP4_UI08& value)
00218 {
00219     unsigned char buffer[1];
00220 
00221     // read bytes from the stream
00222     AP4_Result result;
00223     result = Read((void*)buffer, 1);
00224     if (AP4_FAILED(result)) {        
00225         value = 0;
00226         return result;
00227     }
00228 
00229     // convert bytes to value
00230     value = buffer[0];
00231     
00232     return AP4_SUCCESS;
00233 }
00234 
00235 /*----------------------------------------------------------------------
00236 |       AP4_ByteStream::ReadString
00237 +---------------------------------------------------------------------*/
00238 AP4_Result
00239 AP4_ByteStream::ReadString(char* buffer, AP4_Size size)
00240 {
00241     if (buffer == NULL || size == 0) {
00242         return AP4_ERROR_INVALID_PARAMETERS;
00243     }
00244 
00245     AP4_Size bytes_read = 0;
00246     while (bytes_read < size-1) {      
00247         AP4_Result result;
00248         result = Read(&buffer[bytes_read], 1, NULL);
00249         if (AP4_FAILED(result)) {
00250             buffer[bytes_read] = '\0';
00251             return result;
00252         }
00253         if (buffer[bytes_read] == '\0') {
00254             // end of string
00255             return AP4_SUCCESS;
00256         }
00257         bytes_read++;
00258     }
00259 
00260     // the string was not null terminated, terminate it
00261     buffer[size-1] = '\0';
00262     return AP4_SUCCESS;
00263 }
00264 
00265 /*----------------------------------------------------------------------
00266 |       AP4_ByteStream::CopyTo
00267 +---------------------------------------------------------------------*/
00268 AP4_Result
00269 AP4_ByteStream::CopyTo(AP4_ByteStream& stream, AP4_Size size)
00270 {
00271     unsigned char buffer[AP4_BYTE_STREAM_COPY_BUFFER_SIZE];
00272     while (size) {
00273         AP4_Size bytes_read;
00274         AP4_Size bytes_to_read;
00275         AP4_Result result;
00276 
00277         // decide how much to read
00278         if (size >= sizeof(buffer)) {
00279             bytes_to_read = sizeof(buffer);
00280         } else {
00281             bytes_to_read = size;
00282         }
00283 
00284         // read up to one buffer full
00285         result = Read(buffer, bytes_to_read, &bytes_read);
00286         if (AP4_FAILED(result)) return result;
00287 
00288         // copy to destination
00289         if (bytes_read != 0) {
00290             result = stream.Write(buffer, bytes_read);
00291             if (AP4_FAILED(result)) return result;
00292         }
00293 
00294         // update the size
00295         size -= bytes_read;
00296     }
00297 
00298     return AP4_SUCCESS;
00299 }
00300 
00301 /*----------------------------------------------------------------------
00302 |       AP4_SubStream::AP4_SubStream
00303 +---------------------------------------------------------------------*/
00304 AP4_SubStream::AP4_SubStream(AP4_ByteStream& container, 
00305                              AP4_Offset      offset, 
00306                              AP4_Size        size) :
00307     m_Container(container),
00308     m_Offset(offset),
00309     m_Size(size),
00310     m_Position(0),
00311     m_ReferenceCount(1)
00312 {
00313     m_Container.AddReference();
00314 }
00315 
00316 /*----------------------------------------------------------------------
00317 |       AP4_SubStream::~AP4_SubStream
00318 +---------------------------------------------------------------------*/
00319 AP4_SubStream::~AP4_SubStream()
00320 {
00321     m_Container.Release();
00322 }
00323 
00324 /*----------------------------------------------------------------------
00325 |       AP4_SubStream::Read
00326 +---------------------------------------------------------------------*/
00327 AP4_Result 
00328 AP4_SubStream::Read(void*     buffer, 
00329                     AP4_Size  bytes_to_read, 
00330                     AP4_Size* bytes_read)
00331 {
00332     // default values
00333     if (bytes_read) *bytes_read = 0;
00334 
00335     // shortcut
00336     if (bytes_to_read == 0) {
00337         return AP4_SUCCESS;
00338     }
00339 
00340     // clamp to range
00341     if (m_Position+bytes_to_read > m_Size) {
00342         bytes_to_read = m_Size - m_Position;
00343     }
00344 
00345     // check for end of substream
00346     if (bytes_to_read == 0) {
00347         return AP4_ERROR_EOS;
00348     }
00349 
00350     // seek inside container
00351     //AP4_Result result;
00352     //result = m_Container.Seek(m_Offset+m_Position);
00353     //if (AP4_FAILED(result)) {
00354     //    return result;
00355     //}
00356 
00357     // read from the container
00358     AP4_Size local_bytes_read;
00359     AP4_Result result = m_Container.Read(buffer, bytes_to_read, &local_bytes_read);
00360     if (bytes_read) *bytes_read = local_bytes_read;
00361     if (AP4_SUCCEEDED(result)) {
00362         m_Position += local_bytes_read;
00363     }
00364     return result;
00365 }
00366 
00367 /*----------------------------------------------------------------------
00368 |       AP4_SubStream::Write
00369 +---------------------------------------------------------------------*/
00370 AP4_Result 
00371 AP4_SubStream::Write(const void* buffer, 
00372                      AP4_Size    bytes_to_write, 
00373                      AP4_Size*   bytes_written)
00374 {
00375     // default values
00376     if (bytes_written) *bytes_written = 0;
00377 
00378     // shortcut
00379     if (bytes_to_write == 0) {
00380         return AP4_SUCCESS;
00381     }
00382 
00383     // clamp to range
00384     if (m_Position+bytes_to_write > m_Size) {
00385         bytes_to_write = m_Size - m_Position;
00386     }
00387 
00388     // check for en of substream
00389     if (bytes_to_write == 0) {
00390         return AP4_ERROR_EOS;
00391     }
00392 
00393     // seek inside container
00394     //AP4_Result result;
00395     //result = m_Container.Seek(m_Offset+m_Position);
00396     //if (AP4_FAILED(result)) return result;
00397 
00398     // write to container
00399     AP4_Size local_bytes_written;
00400     AP4_Result result = m_Container.Write(buffer, bytes_to_write, &local_bytes_written);
00401     if (bytes_written) *bytes_written = local_bytes_written;
00402     if (AP4_SUCCEEDED(result)) {
00403         m_Position += local_bytes_written;
00404     }
00405     return result;
00406 }
00407 
00408 /*----------------------------------------------------------------------
00409 |       AP4_SubStream::Seek
00410 +---------------------------------------------------------------------*/
00411 AP4_Result 
00412 AP4_SubStream::Seek(AP4_Offset offset)
00413 {
00414     if (offset > m_Size) return AP4_FAILURE;
00415     AP4_Result result;
00416     result = m_Container.Seek(m_Offset+offset);
00417     if (AP4_SUCCEEDED(result)) {
00418         m_Position = offset;
00419     }
00420     return result;
00421 }
00422 
00423 /*----------------------------------------------------------------------
00424 |       AP4_SubStream::AddReference
00425 +---------------------------------------------------------------------*/
00426 void
00427 AP4_SubStream::AddReference()
00428 {
00429     m_ReferenceCount++;
00430 }
00431 
00432 /*----------------------------------------------------------------------
00433 |       AP4_SubStream::Release
00434 +---------------------------------------------------------------------*/
00435 void
00436 AP4_SubStream::Release()
00437 {
00438     if (--m_ReferenceCount == 0) {
00439         delete this;
00440     }
00441 }
00442 
00443 /*----------------------------------------------------------------------
00444 |       AP4_MemoryByteStream::AP4_MemoryByteStream
00445 +---------------------------------------------------------------------*/
00446 AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_Size size) :
00447     m_BufferIsLocal(true),
00448     m_Size(size),
00449     m_Position(0),
00450     m_ReferenceCount(1)
00451 {
00452     m_Buffer = new AP4_UI08[size];
00453 }
00454 
00455 /*----------------------------------------------------------------------
00456 |       AP4_MemoryByteStream::AP4_MemoryByteStream
00457 +---------------------------------------------------------------------*/
00458 AP4_MemoryByteStream::AP4_MemoryByteStream(AP4_UI08* buffer, AP4_Size size) :
00459     m_BufferIsLocal(false),
00460     m_Buffer(buffer),
00461     m_Size(size),
00462     m_Position(0),
00463     m_ReferenceCount(1)
00464 {}
00465 
00466 /*----------------------------------------------------------------------
00467 |       AP4_MemoryByteStream::~AP4_MemoryByteStream
00468 +---------------------------------------------------------------------*/
00469 AP4_MemoryByteStream::~AP4_MemoryByteStream()
00470 {
00471     if (m_BufferIsLocal) delete[] m_Buffer;
00472 }
00473 
00474 /*----------------------------------------------------------------------
00475 |       AP4_MemoryByteStream::Read
00476 +---------------------------------------------------------------------*/
00477 AP4_Result 
00478 AP4_MemoryByteStream::Read(void*     buffer, 
00479                            AP4_Size  bytes_to_read, 
00480                            AP4_Size* bytes_read)
00481 {
00482     // default values
00483     if (bytes_read) *bytes_read = 0;
00484 
00485     // shortcut
00486     if (bytes_to_read == 0) {
00487         return AP4_SUCCESS;
00488     }
00489 
00490     // clamp to range
00491     if (m_Position+bytes_to_read > m_Size) {
00492         bytes_to_read = m_Size - m_Position;
00493     }
00494 
00495     // check for end of stream
00496     if (bytes_to_read == 0) {
00497         return AP4_ERROR_EOS;
00498     }
00499 
00500     // read from the memory
00501     memcpy(buffer, &m_Buffer[m_Position], bytes_to_read);
00502     m_Position += bytes_to_read;
00503 
00504     if (bytes_read) *bytes_read = bytes_to_read;
00505 
00506     return AP4_SUCCESS;
00507 }
00508 
00509 /*----------------------------------------------------------------------
00510 |       AP4_MemoryByteStream::Write
00511 +---------------------------------------------------------------------*/
00512 AP4_Result 
00513 AP4_MemoryByteStream::Write(const void* buffer, 
00514                             AP4_Size    bytes_to_write, 
00515                             AP4_Size*   bytes_written)
00516 {
00517     // default values
00518     if (bytes_written) *bytes_written = 0;
00519 
00520     // shortcut
00521     if (bytes_to_write == 0) {
00522         return AP4_SUCCESS;
00523     }
00524 
00525     // clamp to range
00526     if (m_Position+bytes_to_write > m_Size) {
00527         bytes_to_write = m_Size - m_Position;
00528     }
00529 
00530     // check for en of stream
00531     if (bytes_to_write == 0) {
00532         return AP4_ERROR_EOS;
00533     }
00534 
00535     // write to memory
00536     memcpy(&m_Buffer[m_Position], buffer, bytes_to_write);
00537     m_Position += bytes_to_write;
00538 
00539     if (bytes_written) *bytes_written = bytes_to_write;
00540 
00541     return AP4_SUCCESS;
00542 }
00543 
00544 /*----------------------------------------------------------------------
00545 |       AP4_MemoryByteStream::Seek
00546 +---------------------------------------------------------------------*/
00547 AP4_Result 
00548 AP4_MemoryByteStream::Seek(AP4_Offset offset)
00549 {
00550     if (offset > m_Size) return AP4_FAILURE;
00551     m_Position = offset;
00552     return AP4_SUCCESS;
00553 }
00554 
00555 /*----------------------------------------------------------------------
00556 |       AP4_MemoryByteStream::AddReference
00557 +---------------------------------------------------------------------*/
00558 void
00559 AP4_MemoryByteStream::AddReference()
00560 {
00561     m_ReferenceCount++;
00562 }
00563 
00564 /*----------------------------------------------------------------------
00565 |       AP4_MemoryByteStream::Release
00566 +---------------------------------------------------------------------*/
00567 void
00568 AP4_MemoryByteStream::Release()
00569 {
00570     if (--m_ReferenceCount == 0) {
00571         delete this;
00572     }
00573 }

Generated on Tue Dec 13 14:47:19 2005 for guliverkli by  doxygen 1.4.5