LCOV - code coverage report
Current view: top level - isomedia - data_map.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 159 215 74.0 %
Date: 2021-04-29 23:48:07 Functions: 13 14 92.9 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2019
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / ISO Media File Format sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : #include <gpac/internal/isomedia_dev.h>
      27             : #include <gpac/network.h>
      28             : #include <gpac/thread.h>
      29             : 
      30             : 
      31             : /*File Mapping object, read-only mode on complete files (no download)*/
      32             : //#define GF_ISOM_DATA_FILE_MAPPING 0x02
      33             : 
      34             : #ifndef GPAC_DISABLE_ISOM
      35             : 
      36             : 
      37       17096 : void gf_isom_datamap_del(GF_DataMap *ptr)
      38             : {
      39       17096 :         if (!ptr) return;
      40             : 
      41       16430 :         if (ptr->szName) gf_free(ptr->szName);
      42             : 
      43             :         //then delete the structure itself....
      44       16430 :         switch (ptr->type) {
      45             :         //file-based
      46       16430 :         case GF_ISOM_DATA_FILE:
      47             :         case GF_ISOM_DATA_MEM:
      48       16430 :                 gf_isom_fdm_del((GF_FileDataMap *)ptr);
      49       16430 :                 break;
      50             : #if 0
      51             :         case GF_ISOM_DATA_FILE_MAPPING:
      52             :                 gf_isom_fmo_del((GF_FileMappingDataMap *)ptr);
      53             :                 break;
      54             : #endif
      55           0 :         default:
      56           0 :                 if (ptr->bs) gf_bs_del(ptr->bs);
      57           0 :                 gf_free(ptr);
      58           0 :                 break;
      59             :         }
      60             : }
      61             : 
      62             : //Close a data entry
      63      646743 : void gf_isom_datamap_close(GF_MediaInformationBox *minf)
      64             : {
      65             :         GF_DataEntryBox *ent = NULL;
      66      646743 :         if (!minf || !minf->dataHandler) return;
      67             : 
      68      646743 :         if (minf->dataInformation && minf->dataInformation->dref) {
      69      646737 :                 ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->child_boxes, minf->dataEntryIndex - 1);
      70             :         }
      71             : 
      72             :         //if ent NULL, the data entry was not used (smooth)
      73      646737 :         if (ent == NULL) return;
      74             : 
      75             :         //self contained, do nothing
      76      646735 :         switch (ent->type) {
      77      646732 :         case GF_ISOM_BOX_TYPE_URL:
      78             :         case GF_ISOM_BOX_TYPE_URN:
      79      646732 :                 if (ent->flags == 1) return;
      80             :                 break;
      81             :         default:
      82             :                 return;
      83             :         }
      84             : 
      85             :         //finally close it
      86           0 :         gf_isom_datamap_del(minf->dataHandler);
      87           0 :         minf->dataHandler = NULL;
      88             : }
      89             : 
      90             : /*cf below, we disable filedatamap since it tricks mem usage on w32*/
      91             : #if 0
      92             : static Bool IsLargeFile(char *path)
      93             : {
      94             : #ifndef _WIN32_WCE
      95             :         FILE *stream;
      96             :         s64 size;
      97             :         stream = gf_fopen(path, "rb");
      98             :         if (!stream) return 0;
      99             :         size = gf_fsize(stream);
     100             :         gf_fclose(stream);
     101             :         if (size == -1L) return 0;
     102             :         if (size > 0xFFFFFFFF) return 1;
     103             : #endif
     104             :         return 0;
     105             : }
     106             : #endif
     107             : 
     108             : 
     109             : //Special constructor, we need some error feedback...
     110             : 
     111       16432 : GF_Err gf_isom_datamap_new(const char *location, const char *parentPath, u8 mode, GF_DataMap **outDataMap)
     112             : {
     113             :         Bool extern_file;
     114             :         char *sPath;
     115       16432 :         *outDataMap = NULL;
     116             : 
     117             :         //if nothing specified, this is a MEMORY data map
     118       16432 :         if (!location) {
     119           1 :                 *outDataMap = gf_isom_fdm_new(location, GF_ISOM_DATA_MAP_WRITE);
     120           1 :                 if (!(*outDataMap)) {
     121             :                         return GF_IO_ERR;
     122             :                 }
     123           1 :                 return GF_OK;
     124             :         }
     125             :         //we need a temp file ...
     126       16431 :         if (!strcmp(location, "_gpac_isobmff_tmp_edit")) {
     127             : #ifndef GPAC_DISABLE_ISOM_WRITE
     128        1169 :                 *outDataMap = gf_isom_fdm_new_temp(parentPath);
     129        1169 :                 if (! (*outDataMap)) {
     130             :                         return GF_IO_ERR;
     131             :                 }
     132        1169 :                 return GF_OK;
     133             : #else
     134             :                 return GF_NOT_SUPPORTED;
     135             : #endif
     136       15262 :         } else if (!strncmp(location, "gmem://", 7) || !strncmp(location, "gfio://", 7)) {
     137        6047 :                 *outDataMap = gf_isom_fdm_new(location, GF_ISOM_DATA_MAP_READ);
     138        6047 :                 if (! (*outDataMap)) {
     139             :                         return GF_IO_ERR;
     140             :                 }
     141        6047 :                 return GF_OK;
     142        9215 :         } else if (!strcmp(location, "_gpac_isobmff_redirect")) {
     143        2844 :                 *outDataMap = gf_isom_fdm_new(location, mode);
     144        2844 :                 if (! (*outDataMap)) {
     145             :                         return GF_IO_ERR;
     146             :                 }
     147        2844 :                 return GF_OK;
     148             :         }
     149             : 
     150        6371 :         extern_file = !gf_url_is_local(location);
     151             : 
     152        6371 :         if (mode == GF_ISOM_DATA_MAP_EDIT) {
     153             :                 //we need a local file for edition!!!
     154         221 :                 if (extern_file) return GF_ISOM_INVALID_MODE;
     155             :                 //OK, switch back to READ mode
     156             :                 mode = GF_ISOM_DATA_MAP_READ;
     157             :         }
     158             : 
     159             :         //TEMP: however, only support for file right now (we'd have to add some callback functions at some point)
     160        6371 :         if (extern_file) {
     161             :                 return GF_NOT_SUPPORTED;
     162             :         }
     163             : 
     164        6371 :         sPath = gf_url_concatenate(parentPath, location);
     165        6371 :         if (sPath == NULL) {
     166             :                 return GF_URL_ERROR;
     167             :         }
     168             : 
     169        6371 :         if (mode == GF_ISOM_DATA_MAP_READ_ONLY) {
     170             :                 mode = GF_ISOM_DATA_MAP_READ;
     171             : 
     172             : #if 0 //file mapping is disabled
     173             :                 if (IsLargeFile(sPath)) {
     174             :                         *outDataMap = gf_isom_fdm_new(sPath, mode);
     175             :                 } else {
     176             :                         *outDataMap = gf_isom_fmo_new(sPath, mode);
     177             :                 }
     178             : #else
     179        5503 :                 *outDataMap = gf_isom_fdm_new(sPath, mode);
     180             : #endif
     181             :         } else {
     182         868 :                 *outDataMap = gf_isom_fdm_new(sPath, mode);
     183         868 :                 if (*outDataMap) {
     184         868 :                         (*outDataMap)->szName = sPath;
     185             :                         sPath = NULL;
     186             :                 }
     187             :         }
     188             : 
     189             :         if (sPath) {
     190        5503 :                 gf_free(sPath);
     191             :         }
     192        6371 :         if (! (*outDataMap)) {
     193             :                 return GF_URL_ERROR;
     194             :         }
     195             : 
     196        6369 :         return GF_OK;
     197             : }
     198             : 
     199             : //Open a data entry of a track
     200             : //Edit is used to switch between original and edition file
     201      646440 : GF_Err gf_isom_datamap_open(GF_MediaBox *mdia, u32 dataRefIndex, u8 Edit)
     202             : {
     203             :         GF_DataEntryBox *ent;
     204             :         GF_MediaInformationBox *minf;
     205             :         u32 SelfCont, count;
     206             :         GF_Err e = GF_OK;
     207      646440 :         if ((mdia == NULL) || (! mdia->information) || !dataRefIndex)
     208             :                 return GF_ISOM_INVALID_MEDIA;
     209             : 
     210             :         minf = mdia->information;
     211      646440 :         if (!minf->dataInformation || !minf->dataInformation->dref)
     212             :                 return GF_ISOM_INVALID_MEDIA;
     213             : 
     214      646440 :         count = gf_list_count(minf->dataInformation->dref->child_boxes);
     215      646440 :         if (!count) {
     216             :                 SelfCont = 1;
     217             :                 ent = NULL;
     218             :         } else {
     219      646440 :                 if (dataRefIndex > gf_list_count(minf->dataInformation->dref->child_boxes))
     220             :                         return GF_BAD_PARAM;
     221             : 
     222      646440 :                 ent = (GF_DataEntryBox*)gf_list_get(minf->dataInformation->dref->child_boxes, dataRefIndex - 1);
     223      646440 :                 if (ent == NULL) return GF_ISOM_INVALID_MEDIA;
     224             : 
     225             :                 //if the current dataEntry is the desired one, and not self contained, return
     226      646440 :                 if ((minf->dataEntryIndex == dataRefIndex) && (ent->flags != 1)) {
     227             :                         return GF_OK;
     228             :                 }
     229             : 
     230             :                 SelfCont = 0;
     231      646440 :                 switch (ent->type) {
     232      646437 :                 case GF_ISOM_BOX_TYPE_URL:
     233             :                 case GF_ISOM_BOX_TYPE_URN:
     234      646437 :                         if (ent->flags == 1) SelfCont = 1;
     235             :                         break;
     236             :                 default:
     237             :                         SelfCont = 1;
     238             :                         break;
     239             :                 }
     240             :         }
     241             : 
     242             :         //we need to open a new one
     243             :         //first close the existing one
     244      646440 :         if (minf->dataHandler) gf_isom_datamap_close(minf);
     245             : 
     246             :         //if self-contained, assign the input file
     247      646440 :         if (SelfCont) {
     248             :                 //if no edit, open the input file
     249      646440 :                 if (!Edit) {
     250       66652 :                         if (mdia->mediaTrack->moov->mov->movieFileMap == NULL) return GF_ISOM_INVALID_FILE;
     251       66652 :                         minf->dataHandler = mdia->mediaTrack->moov->mov->movieFileMap;
     252             :                 } else {
     253             : #ifndef GPAC_DISABLE_ISOM_WRITE
     254      579788 :                         if (mdia->mediaTrack->moov->mov->editFileMap == NULL) return GF_ISOM_INVALID_FILE;
     255      579788 :                         minf->dataHandler = mdia->mediaTrack->moov->mov->editFileMap;
     256             : #else
     257             :                         //this should never be the case in an read-only MP4 file
     258             :                         return GF_BAD_PARAM;
     259             : #endif
     260             :                 }
     261             :                 //else this is a URL (read mode only)
     262             :         } else {
     263           0 :                 e = gf_isom_datamap_new(ent->location, mdia->mediaTrack->moov->mov->fileName ? mdia->mediaTrack->moov->mov->fileName : mdia->mediaTrack->moov->mov->finalName, GF_ISOM_DATA_MAP_READ, & mdia->information->dataHandler);
     264           0 :                 if (e) return (e==GF_URL_ERROR) ? GF_ISOM_UNKNOWN_DATA_REF : e;
     265             :         }
     266             :         //OK, set the data entry index
     267      646440 :         minf->dataEntryIndex = dataRefIndex;
     268      646440 :         return GF_OK;
     269             : }
     270             : 
     271             : //return the NB of bytes actually read (used for HTTP, ...) in case file is uncomplete
     272     1546920 : u32 gf_isom_datamap_get_data(GF_DataMap *map, u8 *buffer, u32 bufferLength, u64 Offset)
     273             : {
     274     1546920 :         if (!map || !buffer) return 0;
     275             : 
     276     1546920 :         switch (map->type) {
     277     1546920 :         case GF_ISOM_DATA_FILE:
     278             :         case GF_ISOM_DATA_MEM:
     279     1546920 :                 return gf_isom_fdm_get_data((GF_FileDataMap *)map, buffer, bufferLength, Offset);
     280             : 
     281             : #if 0
     282             :         case GF_ISOM_DATA_FILE_MAPPING:
     283             :                 return gf_isom_fmo_get_data((GF_FileMappingDataMap *)map, buffer, bufferLength, Offset);
     284             : #endif
     285             : 
     286             :         default:
     287             :                 return 0;
     288             :         }
     289             : }
     290             : 
     291         453 : void gf_isom_datamap_flush(GF_DataMap *map)
     292             : {
     293         453 :         if (!map) return;
     294             : 
     295         453 :         if (map->type == GF_ISOM_DATA_FILE || map->type == GF_ISOM_DATA_MEM) {
     296             :                 GF_FileDataMap *fdm = (GF_FileDataMap *)map;
     297         453 :                 gf_bs_flush(fdm->bs);
     298             :         }
     299             : }
     300             : 
     301             : #ifndef GPAC_DISABLE_ISOM_WRITE
     302             : 
     303             : u64 FDM_GetTotalOffset(GF_FileDataMap *ptr);
     304             : GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize);
     305             : 
     306      560921 : u64 gf_isom_datamap_get_offset(GF_DataMap *map)
     307             : {
     308      560921 :         if (!map) return 0;
     309             : 
     310      560921 :         switch (map->type) {
     311             :         case GF_ISOM_DATA_FILE:
     312      560921 :                 return FDM_GetTotalOffset((GF_FileDataMap *)map);
     313           0 :         case GF_ISOM_DATA_MEM:
     314           0 :                 return gf_bs_get_position(map->bs);
     315             :         default:
     316             :                 return 0;
     317             :         }
     318             : }
     319             : 
     320             : 
     321      560614 : GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, u8 *data, u32 dataSize)
     322             : {
     323      560614 :         if (!ptr || !data|| !dataSize) return GF_BAD_PARAM;
     324             : 
     325      560614 :         switch (ptr->type) {
     326      560614 :         case GF_ISOM_DATA_FILE:
     327             :         case GF_ISOM_DATA_MEM:
     328      560614 :                 return FDM_AddData((GF_FileDataMap *)ptr, data, dataSize);
     329             :         default:
     330             :                 return GF_NOT_SUPPORTED;
     331             :         }
     332             : }
     333             : 
     334        1169 : GF_DataMap *gf_isom_fdm_new_temp(const char *sPath)
     335             : {
     336             :         GF_FileDataMap *tmp;
     337        1169 :         GF_SAFEALLOC(tmp, GF_FileDataMap);
     338        1169 :         if (!tmp) return NULL;
     339             : 
     340        1169 :         tmp->type = GF_ISOM_DATA_FILE;
     341        1169 :         tmp->mode = GF_ISOM_DATA_MAP_WRITE;
     342             : 
     343        1169 :         if (!sPath) {
     344        1169 :                 tmp->stream = gf_file_temp(&tmp->temp_file);
     345             :         } else {
     346             :                 char szPath[GF_MAX_PATH];
     347           0 :                 if ((sPath[strlen(sPath)-1] != '\\') && (sPath[strlen(sPath)-1] != '/')) {
     348             :                         sprintf(szPath, "%s%c%p_isotmp", sPath, GF_PATH_SEPARATOR, (void*) tmp);
     349             :                 } else {
     350             :                         sprintf(szPath, "%s%p_isotmp", sPath, (void*) tmp);
     351             :                 }
     352           0 :                 tmp->stream = gf_fopen(szPath, "w+b");
     353           0 :                 tmp->temp_file = gf_strdup(szPath);
     354             :         }
     355        1169 :         if (!tmp->stream) {
     356           0 :                 if (tmp->temp_file) gf_free(tmp->temp_file);
     357           0 :                 gf_free(tmp);
     358           0 :                 return NULL;
     359             :         }
     360        1169 :         tmp->bs = gf_bs_from_file(tmp->stream, GF_BITSTREAM_WRITE);
     361        1169 :         if (!tmp->bs) {
     362           0 :                 gf_fclose(tmp->stream);
     363           0 :                 gf_free(tmp);
     364           0 :                 return NULL;
     365             :         }
     366             :         return (GF_DataMap *)tmp;
     367             : }
     368             : 
     369             : #endif /*GPAC_DISABLE_ISOM_WRITE*/
     370             : 
     371             : #include <errno.h>
     372             : #include <string.h>
     373       15263 : GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode)
     374             : {
     375             :         u8 bs_mode;
     376             :         GF_FileDataMap *tmp;
     377       15263 :         GF_SAFEALLOC(tmp, GF_FileDataMap);
     378       15263 :         if (!tmp) return NULL;
     379             : 
     380       15263 :         tmp->mode = mode;
     381             : 
     382       15263 :         if (sPath == NULL) {
     383           1 :                 tmp->type = GF_ISOM_DATA_MEM;
     384           1 :                 tmp->bs = gf_bs_new (NULL, 0, GF_BITSTREAM_WRITE);
     385           1 :                 if (!tmp->bs) {
     386           0 :                         gf_free(tmp);
     387           0 :                         return NULL;
     388             :                 }
     389             :                 return (GF_DataMap *)tmp;
     390             :         }
     391             : 
     392       15262 :         tmp->type = GF_ISOM_DATA_FILE;
     393             : #ifndef GPAC_DISABLE_ISOM_WRITE
     394             :         //open a temp file
     395       15262 :         if (!strcmp(sPath, "_gpac_isobmff_tmp_edit")) {
     396             :                 //create a temp file (that only occurs in EDIT/WRITE mode)
     397           0 :                 tmp->stream = gf_file_temp(&tmp->temp_file);
     398             : //              bs_mode = GF_BITSTREAM_READ;
     399             :         }
     400             : #endif
     401       15262 :         if (!strncmp(sPath, "gmem://", 7)) {
     402        6042 :                 if (sscanf(sPath, "gmem://%p", &tmp->blob) != 1)
     403             :                         return NULL;
     404        6042 :                 tmp->bs = gf_bs_new(tmp->blob->data, tmp->blob->size, GF_BITSTREAM_READ);
     405        6042 :                 if (!tmp->bs) {
     406           0 :                         gf_free(tmp);
     407           0 :                         return NULL;
     408             :                 }
     409             :                 return (GF_DataMap *)tmp;
     410             :         }
     411             : 
     412        9220 :         switch (mode) {
     413        6368 :         case GF_ISOM_DATA_MAP_READ:
     414        6368 :                 if (!tmp->stream) tmp->stream = gf_fopen(sPath, "rb");
     415             :                 bs_mode = GF_BITSTREAM_READ;
     416             :                 break;
     417             :         ///we open the file in READ/WRITE mode, in case
     418        2852 :         case GF_ISOM_DATA_MAP_WRITE:
     419        2852 :                 if (!strcmp(sPath, "_gpac_isobmff_redirect")) {
     420        2844 :                         tmp->stream = NULL;
     421        2844 :                         tmp->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     422             :                 } else {
     423           8 :                         if (!strcmp(sPath, "std")) {
     424           0 :                                 tmp->stream = stdout;
     425           0 :                                 tmp->is_stdout = 1;
     426             :                         }
     427             : 
     428           8 :                         if (!tmp->stream) tmp->stream = gf_fopen(sPath, "w+b");
     429           8 :                         if (!tmp->stream) tmp->stream = gf_fopen(sPath, "wb");
     430             :                 }
     431             :                 bs_mode = GF_BITSTREAM_WRITE;
     432             :                 break;
     433             :         ///we open the file in CAT mode, in case
     434           0 :         case GF_ISOM_DATA_MAP_CAT:
     435           0 :                 if (!strcmp(sPath, "_gpac_isobmff_redirect")) {
     436           0 :                         tmp->stream = NULL;
     437           0 :                         tmp->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
     438             :                 } else {
     439           0 :                         if (!strcmp(sPath, "std")) {
     440           0 :                                 tmp->stream = stdout;
     441           0 :                                 tmp->is_stdout = 1;
     442             :                         }
     443             : 
     444           0 :                         if (!tmp->stream) tmp->stream = gf_fopen(sPath, "a+b");
     445           0 :                         if (tmp->stream) gf_fseek(tmp->stream, 0, SEEK_END);
     446             :                 }
     447             :                 bs_mode = GF_BITSTREAM_WRITE;
     448             :                 break;
     449           0 :         default:
     450           0 :                 gf_free(tmp);
     451           0 :                 return NULL;
     452             :         }
     453        9220 :         if (!tmp->stream && !tmp->bs) {
     454           2 :                 gf_free(tmp);
     455           2 :                 return NULL;
     456             :         }
     457        9218 :         if (!tmp->bs)
     458        6374 :                 tmp->bs = gf_bs_from_file(tmp->stream, bs_mode);
     459             : 
     460        9218 :         if (!tmp->bs) {
     461           0 :                 gf_fclose(tmp->stream);
     462           0 :                 gf_free(tmp);
     463           0 :                 return NULL;
     464             :         }
     465             :         return (GF_DataMap *)tmp;
     466             : }
     467             : 
     468       16430 : void gf_isom_fdm_del(GF_FileDataMap *ptr)
     469             : {
     470       16430 :         if (!ptr || (ptr->type != GF_ISOM_DATA_FILE && ptr->type != GF_ISOM_DATA_MEM)) return;
     471       16430 :         if (ptr->bs) gf_bs_del(ptr->bs);
     472       16430 :         if (ptr->stream && !ptr->is_stdout)
     473        7543 :                 gf_fclose(ptr->stream);
     474             : 
     475             : #ifndef GPAC_DISABLE_ISOM_WRITE
     476       16430 :         if (ptr->temp_file) {
     477           0 :                 gf_file_delete(ptr->temp_file);
     478           0 :                 gf_free(ptr->temp_file);
     479             :         }
     480             : #endif
     481       16430 :         gf_free(ptr);
     482             : }
     483             : 
     484     1546920 : u32 gf_isom_fdm_get_data(GF_FileDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
     485             : {
     486             :         u32 bytesRead;
     487             : 
     488             :         //can we seek till that point ???
     489     1546920 :         if (fileOffset > gf_bs_get_size(ptr->bs))
     490             :                 return 0;
     491             : 
     492     1546920 :         if (ptr->blob) {
     493       49685 :                 gf_mx_p(ptr->blob->mx);
     494       49685 :                 gf_bs_reassign_buffer(ptr->bs, ptr->blob->data, ptr->blob->size);
     495       49685 :                 if (gf_bs_seek(ptr->bs, fileOffset) != GF_OK) {
     496           0 :                         gf_mx_v(ptr->blob->mx);
     497           0 :                         return 0;
     498             :                 }
     499     1497235 :         } else if (gf_bs_get_position(ptr->bs) != fileOffset) {
     500             :                 //we are not at the previous location, do a seek
     501      122546 :                 if (gf_bs_seek(ptr->bs, fileOffset) != GF_OK) return 0;
     502             :         }
     503     1546920 :         ptr->curPos = fileOffset;
     504             : 
     505             :         //read our data.
     506     1546920 :         bytesRead = gf_bs_read_data(ptr->bs, buffer, bufferLength);
     507             :         //update our cache
     508     1546920 :         if (bytesRead == bufferLength) {
     509     1546920 :                 ptr->curPos += bytesRead;
     510             :         } else {
     511           0 :                 gf_bs_get_refreshed_size(ptr->bs);
     512           0 :                 gf_bs_seek(ptr->bs, fileOffset);
     513           0 :                 bytesRead = gf_bs_read_data(ptr->bs, buffer, bufferLength);
     514             :                 //update our cache
     515           0 :                 if (bytesRead == bufferLength) {
     516           0 :                         ptr->curPos += bytesRead;
     517             :                 } else {
     518           0 :                         gf_bs_seek(ptr->bs, ptr->curPos);
     519             :                         bytesRead = 0;
     520             :                 }
     521             :         }
     522     1546920 :         ptr->last_acces_was_read = 1;
     523             : 
     524     1546920 :         if (ptr->blob) {
     525       49685 :                 gf_mx_v(ptr->blob->mx);
     526             :         }
     527             :         return bytesRead;
     528             : }
     529             : 
     530             : 
     531             : #ifndef GPAC_DISABLE_ISOM_WRITE
     532             : 
     533             : 
     534           0 : u64 FDM_GetTotalOffset(GF_FileDataMap *ptr)
     535             : {
     536           0 :         if (!ptr) return 0;
     537             :         //the pos is not always at the end
     538             :         //this function is called to set up the chunks
     539             :         //so we need the next WRITE offset
     540      560921 :         return gf_bs_get_size(ptr->bs);
     541             : }
     542             : 
     543      560614 : GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize)
     544             : {
     545             :         u32 ret;
     546             :         u64 orig;
     547      560614 :         if (ptr->mode == GF_ISOM_DATA_MAP_READ) return GF_BAD_PARAM;
     548             : 
     549      560614 :         orig = gf_bs_get_size(ptr->bs);
     550             : 
     551             :         /*last access was read, seek to end of file*/
     552      560614 :         if (ptr->last_acces_was_read) {
     553        5011 :                 gf_bs_seek(ptr->bs, orig);
     554        5011 :                 ptr->last_acces_was_read = 0;
     555             :         }
     556             :         //OK, write our stuff to the datamap...
     557             :         //we don't use bs here cause we want to know more about what has been written
     558      560614 :         ret = gf_bs_write_data(ptr->bs, data, dataSize);
     559      560614 :         if (ret != dataSize) {
     560           0 :                 ptr->curPos = orig;
     561           0 :                 gf_bs_seek(ptr->bs, orig);
     562           0 :                 return GF_IO_ERR;
     563             :         }
     564      560614 :         ptr->curPos = gf_bs_get_position(ptr->bs);
     565             : #if 0
     566             :         //flush the stream !!
     567             :         if (ptr->stream) gf_bs_flush(ptr->bs);
     568             : #endif
     569      560614 :         return GF_OK;
     570             : }
     571             : 
     572             : #endif  /*GPAC_DISABLE_ISOM_WRITE*/
     573             : 
     574             : 
     575             : #if 0 //file mapping disabled
     576             : 
     577             : #ifdef WIN32
     578             : 
     579             : #include <windows.h>
     580             : #include <winerror.h>
     581             : 
     582             : GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode)
     583             : {
     584             :         GF_FileMappingDataMap *tmp;
     585             :         HANDLE fileH, fileMapH;
     586             : #ifdef _WIN32_WCE
     587             :         unsigned short sWPath[MAX_PATH];
     588             : #endif
     589             : 
     590             :         //only in read only
     591             :         if (mode != GF_ISOM_DATA_MAP_READ) return NULL;
     592             : 
     593             :         GF_SAFEALLOC(tmp, GF_FileMappingDataMap);
     594             :         if (!tmp) return NULL;
     595             : 
     596             :         tmp->type = GF_ISOM_DATA_FILE_MAPPING;
     597             :         tmp->mode = mode;
     598             :         tmp->name = gf_strdup(sPath);
     599             : 
     600             :         //
     601             :         //      Open the file
     602             :         //
     603             : #ifdef _WIN32_WCE
     604             :         //convert to WIDE
     605             :         CE_CharToWide((char *)sPath, sWPath);
     606             : 
     607             :         fileH = CreateFileForMapping(sWPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
     608             :                                      (FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS), NULL );
     609             : #else
     610             :         fileH = CreateFile(sPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
     611             :                            (FILE_ATTRIBUTE_READONLY | FILE_FLAG_RANDOM_ACCESS), NULL );
     612             : #endif
     613             : 
     614             : 
     615             :         if (fileH == INVALID_HANDLE_VALUE) {
     616             :                 gf_free(tmp->name);
     617             :                 gf_free(tmp);
     618             :                 return NULL;
     619             :         }
     620             : 
     621             :         tmp->file_size = GetFileSize(fileH, NULL);
     622             :         if (tmp->file_size == 0xFFFFFFFF) {
     623             :                 CloseHandle(fileH);
     624             :                 gf_free(tmp->name);
     625             :                 gf_free(tmp);
     626             :                 return NULL;
     627             :         }
     628             : 
     629             :         //
     630             :         //      Create the mapping
     631             :         //
     632             :         fileMapH = CreateFileMapping(fileH, NULL, PAGE_READONLY, 0, 0, NULL);
     633             :         if (fileMapH == NULL) {
     634             :                 CloseHandle(fileH);
     635             :                 gf_free(tmp->name);
     636             :                 gf_free(tmp);
     637             :                 return NULL;
     638             :         }
     639             : 
     640             :         tmp->byte_map = MapViewOfFile(fileMapH, FILE_MAP_READ, 0, 0, 0);
     641             :         if (tmp->byte_map == NULL) {
     642             :                 CloseHandle(fileMapH);
     643             :                 CloseHandle(fileH);
     644             :                 gf_free(tmp->name);
     645             :                 gf_free(tmp);
     646             :                 return NULL;
     647             :         }
     648             : 
     649             :         CloseHandle(fileH);
     650             :         CloseHandle(fileMapH);
     651             : 
     652             :         //finaly open our bitstream (from buffer)
     653             :         tmp->bs = gf_bs_new(tmp->byte_map, tmp->file_size, GF_BITSTREAM_READ);
     654             :         return (GF_DataMap *)tmp;
     655             : }
     656             : 
     657             : void gf_isom_fmo_del(GF_FileMappingDataMap *ptr)
     658             : {
     659             :         if (!ptr || (ptr->type != GF_ISOM_DATA_FILE_MAPPING)) return;
     660             : 
     661             :         if (ptr->bs) gf_bs_del(ptr->bs);
     662             :         if (ptr->byte_map) UnmapViewOfFile(ptr->byte_map);
     663             :         gf_free(ptr->name);
     664             :         gf_free(ptr);
     665             : }
     666             : 
     667             : 
     668             : u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
     669             : {
     670             :         //can we seek till that point ???
     671             :         if (fileOffset > ptr->file_size) return 0;
     672             : 
     673             :         //we do only read operations, so trivial
     674             :         memcpy(buffer, ptr->byte_map + fileOffset, bufferLength);
     675             :         return bufferLength;
     676             : }
     677             : 
     678             : #else
     679             : 
     680             : GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode)
     681             : {
     682             :         return gf_isom_fdm_new(sPath, mode);
     683             : }
     684             : 
     685             : void gf_isom_fmo_del(GF_FileMappingDataMap *ptr)
     686             : {
     687             :         gf_isom_fdm_del((GF_FileDataMap *)ptr);
     688             : }
     689             : 
     690             : u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, u8 *buffer, u32 bufferLength, u64 fileOffset)
     691             : {
     692             :         return gf_isom_fdm_get_data((GF_FileDataMap *)ptr, buffer, bufferLength, fileOffset);
     693             : }
     694             : 
     695             : #endif //win32
     696             : #endif //file mapping disabled
     697             : 
     698             : #endif /*GPAC_DISABLE_ISOM*/

Generated by: LCOV version 1.13