sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include "mp4atom.h"
sl@0: #include <3gplibrary/mp4config.h>
sl@0: #include "mp4buffer.h"
sl@0: #include "mp4memwrap.h"
sl@0: #include "mp4file.h"
sl@0: #include "mp4list.h"
sl@0: 
sl@0: 
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_i32 addData(MP4HandleImp handle,
sl@0:  *                   mp4_u8 *buffer,
sl@0:  *                   mp4_u32 bytestowrite)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function allocates memory for the data and copies it from
sl@0:  *   buffer to the new allocated buffer.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle        MP4 library handle
sl@0:  *   buffer        Buffer containing data
sl@0:  *   bytestowrite  Size of buffer in bytes
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   Negative      Error
sl@0:  *   0             Success
sl@0:  *
sl@0:  */
sl@0: mp4_i32 addData(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestowrite)
sl@0: {
sl@0:   void *newBuffer;
sl@0: 
sl@0:   newBuffer = mp4malloc(bytestowrite);
sl@0:   if (newBuffer == NULL)
sl@0:     return -1;
sl@0: 
sl@0:   mp4memcpy(newBuffer, buffer, bytestowrite);
sl@0: 
sl@0:   if (listAppend(handle->mem, newBuffer, bytestowrite)) /* Success */
sl@0:     return 0;
sl@0:   else
sl@0: 	  {
sl@0: 	  if (newBuffer)
sl@0: 		  {
sl@0: 		  delete newBuffer;
sl@0: 		  newBuffer = NULL;
sl@0: 		  }
sl@0: 	  return -1;
sl@0: 	  }
sl@0: }
sl@0: 
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_u32 getBufferedBytes(MP4HandleImp handle)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function returns the number of bytes in the library internal
sl@0:  *   buffers.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle   MP4 library handle
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   0   The input is in a file and therefore no memory is used to store MP4
sl@0:  *       data or no memory in buffers.
sl@0:  *   >0  Number of bytes stored in the library internal buffers
sl@0:  *
sl@0:  */
sl@0: mp4_u32 getBufferedBytes(MP4HandleImp handle)
sl@0: {
sl@0:   if (handle->file)
sl@0:     return 0;
sl@0: 
sl@0:   return listBytesInList(handle->mem);
sl@0: }
sl@0: 
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_u32 getCumulativeBufferedBytes(MP4HandleImp handle)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function returns the number of bytes passed through the library
sl@0:  *   internal buffers.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle   MP4 library handle
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   0   The input is in a file and therefore no memory is used to store MP4
sl@0:  *       data or no memory in buffers.
sl@0:  *   >0  Number of bytes stored in the library internal buffers
sl@0:  *
sl@0:  */
sl@0: mp4_u32 getCumulativeBufferedBytes(MP4HandleImp handle)
sl@0: {
sl@0:   if (handle->file)
sl@0:     return 0;
sl@0: 
sl@0:   return listCumulativeBytesInList(handle->mem);
sl@0: }
sl@0: 
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_i32 readData(MP4HandleImp handle,
sl@0:  *                    mp4_u8 *buffer,
sl@0:  *                    mp4_u32 bytestoread)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function reads bytestoread bytes from memory buffers or file
sl@0:  *   to buffer.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle       MP4 library handle
sl@0:  *   buffer       Caller allocated buffer for the data
sl@0:  *   bytestoread  Number of bytes to read
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   >= 0         Success. Value tells the number of bytes read.
sl@0:  *   -1           File has not been opened
sl@0:  *   -2           End of file or file error
sl@0:  *   -10          Not enough data in memory
sl@0:  *
sl@0:  */
sl@0: mp4_i32 readData(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
sl@0: {
sl@0:   if (handle->file) /* Input is in a file */
sl@0:   {
sl@0:     switch (readFile(handle, buffer, bytestoread))
sl@0:     {
sl@0:     case -2: /* EOF or error */
sl@0:       return -2;
sl@0:     case -1: /* File not open */
sl@0:       return -1;
sl@0:     case 0: /* Ok */
sl@0:       return bytestoread;
sl@0:     default:
sl@0:       break;
sl@0:     }
sl@0:   }
sl@0:   else /* Input is in memory list */
sl@0:   {
sl@0:     mp4_u32 i, j;
sl@0:     node_s *node;
sl@0: 
sl@0:     if (handle->mem->bytesInList - handle->absPosition < bytestoread)
sl@0:       return -10;
sl@0: 
sl@0:     i = 0;
sl@0:     j = handle->absPosition;
sl@0: 
sl@0:     node = handle->mem->first;
sl@0: 
sl@0:     while (i < bytestoread)
sl@0:     {
sl@0:       if ((mp4_i32)(node->dataSize - j) <= 0)
sl@0:       {
sl@0:         j -= node->dataSize;
sl@0:         node = node->next;
sl@0:         continue;
sl@0:       }
sl@0: 
sl@0:       {
sl@0:         mp4_u32 k;
sl@0: 
sl@0:         k = node->dataSize - j >= bytestoread - i ? bytestoread - i : node->dataSize - j;
sl@0: 
sl@0:         mp4memcpy(buffer + i, ((mp4_u8 *)node->data) + j, k);
sl@0:         i += k;
sl@0:         j += k;
sl@0:       }
sl@0:     }
sl@0: 
sl@0:     handle->position = j;
sl@0:     handle->absPosition += bytestoread;
sl@0: 
sl@0:     node = handle->mem->first;
sl@0:   }
sl@0: 
sl@0:   return bytestoread;
sl@0: }
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_i32 peekData(MP4HandleImp handle,
sl@0:  *                    mp4_u8 *buffer,
sl@0:  *                    mp4_u32 bytestoread)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function reads bytestoread bytes from memory buffers or file
sl@0:  *   to buffer but doesn't change the internal position in the file/stream.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle       MP4 library handle
sl@0:  *   buffer       Caller allocated buffer for the data
sl@0:  *   bytestoread  Number of bytes to read
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   >= 0         Success. Value tells the number of bytes read.
sl@0:  *   -1           File has not been opened
sl@0:  *   -2           End of file or file error
sl@0:  *   -3           fseek failed
sl@0:  *   -10          Not enough data in memory
sl@0:  *
sl@0:  */
sl@0: mp4_i32 peekData(MP4HandleImp handle, mp4_u8 *buffer, mp4_u32 bytestoread)
sl@0: {
sl@0:   if (handle->file) /* Input is in a file */
sl@0:   {
sl@0:     switch (peekFile(handle, buffer, bytestoread))
sl@0:     {
sl@0:     case -3: /* fseek failed */
sl@0:       return -3;
sl@0:     case -2: /* EOF or error */
sl@0:       return -2;
sl@0:     case -1: /* File not open */
sl@0:       return -1;
sl@0:     case 0: /* Ok */
sl@0:       return bytestoread;
sl@0:     default:
sl@0:       break;
sl@0:     }
sl@0:   }
sl@0:   else /* Input is in memory list */
sl@0:   {
sl@0:     mp4_u32 i, j;
sl@0:     node_s *node;
sl@0: 
sl@0:     if ((mp4_i32)(handle->mem->bytesInList - handle->absPosition) < (mp4_i32)bytestoread)
sl@0:       return -10;
sl@0: 
sl@0:     i = 0;
sl@0:     j = handle->absPosition;
sl@0: 
sl@0:     node = handle->mem->first;
sl@0: 
sl@0:     while (i < bytestoread)
sl@0:     {
sl@0:       if ((mp4_i32)(node->dataSize - j) <= 0)
sl@0:       {
sl@0:         j -= node->dataSize;
sl@0:         node = node->next;
sl@0:         continue;
sl@0:       }
sl@0: 
sl@0:       {
sl@0:         mp4_u32 k;
sl@0: 
sl@0:         k = node->dataSize - j >= bytestoread - i ? bytestoread - i : node->dataSize - j;
sl@0: 
sl@0:         mp4memcpy(buffer + i, ((mp4_u8 *)node->data) + j, k);
sl@0:         i += k;
sl@0:         j += k;
sl@0:       }
sl@0:     }
sl@0:   }
sl@0: 
sl@0:   return bytestoread;
sl@0: }
sl@0: 
sl@0: 
sl@0: /*
sl@0:  * Function:
sl@0:  *
sl@0:  *   mp4_i32 discardData(MP4HandleImp handle,
sl@0:  *                       mp4_i32 bytesToDiscard)
sl@0:  *
sl@0:  * Description:
sl@0:  *
sl@0:  *   This function reads and discards bytesToDiscard bytes from file/stream.
sl@0:  *
sl@0:  * Parameters:
sl@0:  *
sl@0:  *   handle             MP4 library handle
sl@0:  *   bytesToDiscard     This many bytes are discarded
sl@0:  *
sl@0:  * Return value:
sl@0:  *
sl@0:  *   Negative integer   Error
sl@0:  *   >= 0               Success. Value tells how many bytes were read.
sl@0:  *
sl@0:  */
sl@0: mp4_i32 discardData(MP4HandleImp handle, mp4_i32 bytesToDiscard)
sl@0: {
sl@0:   mp4_i32 bytesread;
sl@0:   mp4_i32 bytestoread;
sl@0:   mp4_i32 totalbytesread = 0;
sl@0: 
sl@0:   while (totalbytesread < bytesToDiscard)
sl@0:   {
sl@0:     bytestoread = bytesToDiscard - totalbytesread;
sl@0:     if (bytestoread > TMPBUFSIZE)
sl@0:       bytestoread = TMPBUFSIZE;
sl@0: 
sl@0:     bytesread = readData(handle, handle->buf, bytestoread);
sl@0:     if (bytesread < 0)
sl@0:       return -1;
sl@0:     totalbytesread += bytesread;
sl@0:   }
sl@0: 
sl@0:   return totalbytesread;
sl@0: }
sl@0: // End of File