• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 /**
17  ************************************************************************
18  * @file         M4OSA_FileCommon.c
19  * @brief        File common for Android
20  * @note         This file implements functions used by both the file writer
21  *               and file reader.
22  ************************************************************************
23 */
24 
25 #ifndef USE_STAGEFRIGHT_CODECS
26 #error "USE_STAGEFRIGHT_CODECS is not defined"
27 #endif /*USE_STAGEFRIGHT_CODECS*/
28 
29 #ifdef UTF_CONVERSION
30 #include <string.h>
31 #endif /*UTF_CONVERSION*/
32 
33 #include <sys/stat.h>
34 #include <errno.h>
35 
36 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
37 #include "M4OSA_Semaphore.h"
38 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
39 
40 
41 #include "M4OSA_Debug.h"
42 #include "M4OSA_FileCommon.h"
43 #include "M4OSA_FileCommon_priv.h"
44 #include "M4OSA_Memory.h"
45 #include "M4OSA_CharStar.h"
46 
47 /**
48  ************************************************************************
49  * @brief      This function opens the provided URL and returns its context.
50  *             If an error occured, the context is set to NULL.
51  * @param      core_id: (IN) Core ID of the caller (M4OSA_FILE_READER or M4OSA_FILE_WRITER)
52  * @param      context: (OUT) Context of the core file reader
53  * @param      url: (IN) URL of the input file
54  * @param      fileModeAccess: (IN) File mode access
55  * @return     M4NO_ERROR: there is no error
56  * @return     M4ERR_PARAMETER: at least one parameter is NULL
57  * @return     M4ERR_ALLOC: there is no more memory available
58  * @return     M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported
59  *             file
60  * @return     M4ERR_FILE_NOT_FOUND: the file cannot be found
61  * @return     M4ERR_FILE_LOCKED: the file is locked by an other
62  *             application/process
63  * @return     M4ERR_FILE_BAD_MODE_ACCESS: the file mode access is not correct
64  ************************************************************************
65 */
M4OSA_fileCommonOpen(M4OSA_UInt16 core_id,M4OSA_Context * pContext,M4OSA_Char * pUrl,M4OSA_FileModeAccess fileModeAccess)66 M4OSA_ERR M4OSA_fileCommonOpen(M4OSA_UInt16 core_id, M4OSA_Context* pContext,
67                                M4OSA_Char* pUrl, M4OSA_FileModeAccess fileModeAccess)
68 {
69 
70     M4OSA_Int32 i            = 0;
71     M4OSA_Int32 iMode        = 0;
72     M4OSA_Int32 iSize        = 0;
73     M4OSA_Int32 iSavePos    = 0;
74 
75     M4OSA_Char  mode[4]            = "";
76     M4OSA_Char* pReadString        = (M4OSA_Char*)"r";
77     M4OSA_Char* pWriteString    = (M4OSA_Char*)"w";
78     M4OSA_Char* pAppendString    = (M4OSA_Char*)"a";
79     M4OSA_Char* pBinaryString    = (M4OSA_Char*)"b";
80     M4OSA_Char* pPlusString        = (M4OSA_Char*)"+";
81 
82     M4OSA_ERR err = M4NO_ERROR;
83 
84     FILE* pFileHandler = M4OSA_NULL;
85     M4OSA_FileContext *pFileContext    = M4OSA_NULL;
86 
87 
88 #ifdef UTF_CONVERSION
89     /*FB: to test the UTF16->UTF8 conversion into Video Artist*/
90     /*Convert the URL from UTF16 to UTF8*/
91     M4OSA_Void* tempConversionBuf;
92     M4OSA_UInt32 tempConversionSize = 1000;
93 
94     tempConversionBuf = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(tempConversionSize +1, 0, "conversion buf");
95     if(tempConversionBuf == M4OSA_NULL)
96     {
97         M4OSA_TRACE1_0("Error when allocating conversion buffer\n");
98         return M4ERR_PARAMETER;
99     }
100     M4OSA_ToUTF8_OSAL(pUrl, tempConversionBuf, &tempConversionSize);
101     ((M4OSA_Char*)tempConversionBuf)[tempConversionSize ] = '\0';
102 
103     printf("file open %s\n", tempConversionBuf);
104 #endif /*UTF CONVERSION*/
105 
106     M4OSA_TRACE3_4("M4OSA_fileCommonOpen\t\tM4OSA_UInt16 %d\tM4OSA_Context* 0x%x\t"
107         "M4OSA_Char* %s\tfileModeAccess %d", core_id, pContext, pUrl, fileModeAccess);
108 
109     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext,    M4ERR_PARAMETER,    "M4OSA_fileCommonOpen: pContext is M4OSA_NULL");
110     M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl,        M4ERR_PARAMETER,    "M4OSA_fileCommonOpen: pUrl  is M4OSA_NULL");
111     M4OSA_DEBUG_IF2(0 == fileModeAccess,    M4ERR_PARAMETER,    "M4OSA_fileCommonOpen: fileModeAccess is 0");
112 
113     /* Read mode not set for the reader */
114     M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead),
115         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead");
116 
117     /* Read mode not set for the reader */
118     M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && !(fileModeAccess & M4OSA_kFileRead),
119         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileRead");
120 
121     /* M4OSAfileReadOpen cannot be used with Write file mode access */
122     M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileWrite),
123         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite");
124 
125     /* Append and Create flags cannot be used with Read */
126     M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileAppend),
127         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileAppend");
128 
129     M4OSA_DEBUG_IF1((M4OSA_FILE_READER == core_id) && (fileModeAccess & M4OSA_kFileCreate),
130         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileCreate");
131 
132     /* Write mode not set for the writer */
133     M4OSA_DEBUG_IF1((M4OSA_FILE_WRITER == core_id) && !(fileModeAccess & M4OSA_kFileWrite),
134         M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: M4OSA_kFileWrite");
135 
136     /* Create flag necessary for opening file */
137     if ((fileModeAccess & M4OSA_kFileRead) &&
138         (fileModeAccess & M4OSA_kFileWrite)&&(fileModeAccess & M4OSA_kFileCreate))
139     {
140         strncat((char *)mode, (const char *)pWriteString, (size_t)1);
141         strncat((char *)mode, (const char *)pPlusString, (size_t)1);
142     }
143     else
144     {
145         if(fileModeAccess & M4OSA_kFileAppend)
146         {
147             strncat((char *)mode, (const char *)pAppendString, (size_t)1);
148         }
149         else if(fileModeAccess & M4OSA_kFileRead)
150         {
151             strncat((char *)mode, (const char *)pReadString, (size_t)1);
152         }
153         else if(fileModeAccess & M4OSA_kFileWrite)
154         {
155             strncat((char *)mode, (const char *)pWriteString, (size_t)1);
156         }
157 
158         if((fileModeAccess & M4OSA_kFileRead)&&(fileModeAccess & M4OSA_kFileWrite))
159         {
160             strncat((char *)mode,(const char *)pPlusString, (size_t)1);
161         }
162     }
163 
164     if(!(fileModeAccess & M4OSA_kFileIsTextMode))
165     {
166         strncat((char *)mode, (const char *)pBinaryString,(size_t)1);
167     }
168 
169     /*Open the file*/
170 
171 #ifdef UTF_CONVERSION
172     /*Open the converted path*/
173     pFileHandler = fopen((const char *)tempConversionBuf, (const char *)mode);
174     /*Free the temporary decoded buffer*/
175     free(tempConversionBuf);
176 #else /* UTF_CONVERSION */
177     pFileHandler = fopen((const char *)pUrl, (const char *)mode);
178 #endif /* UTF_CONVERSION */
179 
180     if (M4OSA_NULL == pFileHandler)
181     {
182         switch(errno)
183         {
184         case ENOENT:
185             {
186                 M4OSA_DEBUG(M4ERR_FILE_NOT_FOUND, "M4OSA_fileCommonOpen: No such file or directory");
187                 M4OSA_TRACE1_1("File not found: %s", pUrl);
188                 return M4ERR_FILE_NOT_FOUND;
189             }
190         case EACCES:
191             {
192                 M4OSA_DEBUG(M4ERR_FILE_LOCKED, "M4OSA_fileCommonOpen: Permission denied");
193                 return M4ERR_FILE_LOCKED;
194             }
195          case EINVAL:
196          {
197             M4OSA_DEBUG(M4ERR_FILE_BAD_MODE_ACCESS, "M4OSA_fileCommonOpen: Invalid Argument");
198             return M4ERR_FILE_BAD_MODE_ACCESS;
199          }
200         case EMFILE:
201          case ENOSPC:
202         case ENOMEM:
203             {
204                 M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen: Too many open files");
205                 return M4ERR_ALLOC;
206             }
207         default:
208             {
209                 M4OSA_DEBUG(M4ERR_NOT_IMPLEMENTED, "M4OSA_fileCommonOpen");
210                 return M4ERR_NOT_IMPLEMENTED;
211             }
212         }
213     }
214 
215     /* Allocate the file context */
216     pFileContext = (M4OSA_FileContext*) M4OSA_32bitAlignedMalloc(sizeof(M4OSA_FileContext),
217                     core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: file context");
218     if (M4OSA_NULL == pFileContext)
219     {
220         fclose(pFileHandler);
221         M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen");
222         return M4ERR_ALLOC;
223     }
224 
225     pFileContext->file_desc        = pFileHandler;
226     pFileContext->access_mode    = fileModeAccess;
227     pFileContext->current_seek    = SeekNone;
228     pFileContext->b_is_end_of_file    = M4OSA_FALSE;
229 
230     /**
231      * Note: Never use this expression "i = (value1 == value2) ? x: y;"
232      * because that doens't compile on other platforms (ADS for example)
233      * Use: if(value1 == value2)
234      *        { i= x; ..etc
235      */
236     pFileContext->coreID_write = 0;
237     pFileContext->coreID_read = 0;
238     pFileContext->m_DescrModeAccess = M4OSA_kDescNoneAccess;
239 
240     if (M4OSA_FILE_READER == core_id)
241     {
242         pFileContext->coreID_read = core_id;
243         pFileContext->m_DescrModeAccess = M4OSA_kDescReadAccess;
244     }
245     else if (M4OSA_FILE_WRITER == core_id)
246     {
247         pFileContext->coreID_write = core_id;
248         pFileContext->m_DescrModeAccess = M4OSA_kDescWriteAccess;
249     }
250 
251     pFileContext->read_position = 0;
252     pFileContext->write_position = 0;
253 
254     /* Allocate the memory to store the URL string */
255     pFileContext->url_name = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(strlen((const char *)pUrl)+1,
256                         core_id, (M4OSA_Char*)"M4OSA_fileCommonOpen: URL name");
257     if (M4OSA_NULL == pFileContext->url_name)
258     {
259         fclose(pFileHandler);
260         free(pFileContext);
261         M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonOpen");
262         return M4ERR_ALLOC;
263     }
264     M4OSA_chrNCopy(pFileContext->url_name, pUrl, strlen((const char *)pUrl)+1);
265 
266     /* Get the file name */
267     err = M4OSA_fileCommonGetFilename(pUrl, &pFileContext->file_name);
268     if(M4NO_ERROR != err)
269     {
270         fclose(pFileHandler);
271         free(pFileContext->url_name);
272         free(pFileContext);
273         M4OSA_DEBUG(err, "M4OSA_fileCommonOpen");
274         return err;
275     }
276 
277 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
278     M4OSA_semaphoreOpen(&(pFileContext->semaphore_context), 1); /* Allocate the semaphore */
279 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
280 
281 
282 
283 #ifdef USE_STAGEFRIGHT_CODECS
284     // Workaround for file system bug on Stingray/Honeycomb where a file re-created will keep
285     // the original file's size filled with 0s. Do not seek to the end to avoid ill effects
286     if(fileModeAccess & M4OSA_kFileAppend) {
287         /* Get the file size */
288         iSavePos = ftell(pFileHandler);            /*    1- Check the first position */
289         fseek(pFileHandler, 0, SEEK_END);        /*    2- Go to the end of the file*/
290         iSize = ftell(pFileHandler);            /*    3- Check the file size        */
291         fseek(pFileHandler, iSavePos, SEEK_SET);/*    4- go to the first position */
292     } else {
293         iSize = 0;
294     }
295 #else /* USE_STAGEFRIGHT_CODECS */
296     /* Get the file size */
297     iSavePos = ftell(pFileHandler);            /*    1- Check the first position */
298     fseek(pFileHandler, 0, SEEK_END);        /*    2- Go to the end of the file*/
299     iSize = ftell(pFileHandler);            /*    3- Check the file size        */
300     fseek(pFileHandler, iSavePos, SEEK_SET);/*    4- go to the first position */
301 #endif /* USE_STAGEFRIGHT_CODECS */
302 
303 
304 
305     /* Warning possible overflow if the file is higher than 2GBytes */
306     pFileContext->file_size = iSize;
307 
308     *pContext = pFileContext;
309 
310     return M4NO_ERROR;
311 }
312 
313 
314 /**
315  ************************************************************************
316  * @brief      This function convert from UTF16 to UTF8
317  * @param      pBufferIn: (IN) UTF16 input path
318  * @param      pBufferOut: (OUT) UTF8 output path
319  * @param      bufferOutSize: (IN/OUT) size of the output path
320  * @return     M4NO_ERROR: there is no error
321  * @return     M4ERR_PARAMETER: the output path size is not enough to contain
322  *               the decoded path
323  ************************************************************************
324 */
325 #ifdef UTF_CONVERSION
M4OSA_ToUTF8_OSAL(M4OSA_Void * pBufferIn,M4OSA_UInt8 * pBufferOut,M4OSA_UInt32 * bufferOutSize)326 M4OSA_ERR M4OSA_ToUTF8_OSAL (M4OSA_Void   *pBufferIn, M4OSA_UInt8  *pBufferOut,
327                                                     M4OSA_UInt32 *bufferOutSize)
328 {
329     M4OSA_UInt16 i;
330     wchar_t      *w_str = (wchar_t *) pBufferIn;
331     M4OSA_UInt32 len, size_needed, size_given;
332     if (pBufferIn == NULL)
333     {
334         *pBufferOut=NULL;
335         *bufferOutSize=1;
336     }
337     else
338     {
339         len         = wcslen(w_str);
340         size_needed = len+1;
341         size_given  = *bufferOutSize;
342 
343        *bufferOutSize=size_needed;
344         if (size_given < size_needed )
345         {
346             return M4ERR_PARAMETER;
347         }
348         else
349         {
350             for (i=0; i<len; i++)
351             {
352                 pBufferOut[i]=(M4OSA_UInt8)w_str[i];
353             }
354             pBufferOut[len]=0;
355         }
356     }
357     return M4NO_ERROR;
358 }
359 #endif /*UTF CONVERSION*/
360 
361 /**
362  ************************************************************************
363  * @brief      This function seeks at the provided position.
364  * @param      context: (IN/OUT) Context of the core file reader
365  * @param      seekMode: (IN) Seek access mode
366  * @param      position: (IN/OUT) Position in the file
367  * @return     M4NO_ERROR: there is no error
368  * @return     M4ERR_PARAMETER: at least one parameter is NULL
369  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
370  * @return     M4ERR_ALLOC: there is no more memory available
371  * @return     M4ERR_FILE_INVALID_POSITION: the position cannot be reached
372  ************************************************************************
373 */
M4OSA_fileCommonSeek(M4OSA_Context pContext,M4OSA_FileSeekAccessMode seekMode,M4OSA_FilePosition * pFilePos)374 M4OSA_ERR M4OSA_fileCommonSeek(M4OSA_Context pContext,
375                                M4OSA_FileSeekAccessMode seekMode,
376                                M4OSA_FilePosition* pFilePos)
377 {
378     M4OSA_FileContext* pFileContext = pContext;
379     M4OSA_FilePosition fpos_current;
380     M4OSA_FilePosition fpos_seek;
381     M4OSA_FilePosition fpos_null = 0;
382     M4OSA_FilePosition fpos_neg_un = -1;
383     M4OSA_FilePosition fpos_file_size;
384     M4OSA_FilePosition fpos_seek_from_beginning;
385 
386     M4OSA_TRACE3_3("M4OSA_fileCommonSeek\t\tM4OSA_Context 0x%x\t M4OSA_FileSeekAccessMode %d\tM4OSA_FilePosition* 0x%x",
387         pContext, seekMode, pFilePos);
388 
389     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext, M4ERR_PARAMETER, "M4OSA_fileCommonSeek");
390     M4OSA_DEBUG_IF2(0 == seekMode, M4ERR_PARAMETER, "M4OSA_fileCommonSeek");
391     M4OSA_DEBUG_IF2(M4OSA_NULL == pFilePos, M4ERR_PARAMETER, "M4OSA_fileCommonSeek");
392 
393     fpos_file_size = pFileContext->file_size;
394 
395     if(SeekRead == pFileContext->current_seek)
396     {
397         fpos_current = pFileContext->read_position;
398     }
399     else if(SeekWrite == pFileContext->current_seek)
400     {
401         fpos_current = pFileContext->write_position;
402     }
403     else
404     {
405         fpos_current = 0;
406     }
407 
408     switch(seekMode)
409     {
410     case M4OSA_kFileSeekCurrent:
411         {
412             fpos_seek = *pFilePos;
413             break;
414         }
415     case M4OSA_kFileSeekBeginning:
416         {
417             fpos_seek = *pFilePos - fpos_current;
418             break;
419         }
420     case M4OSA_kFileSeekEnd:
421         {
422             fpos_seek = *pFilePos + fpos_file_size - fpos_current;
423             break;
424         }
425     default:
426         {
427             return M4ERR_PARAMETER;
428         }
429     }
430 
431     fpos_seek_from_beginning = fpos_current + fpos_seek;
432 
433     if(fseek(pFileContext->file_desc, fpos_seek, SEEK_CUR) != 0)
434     {
435         switch(errno)
436         {
437         case EINVAL:
438             {
439             /* meaning the value for origin is invalid or the position
440                 specified by offset is before the beginning of the file */
441                 return M4ERR_FILE_INVALID_POSITION;
442             }
443 
444         case EBADF:
445         default:
446             {
447                 return M4ERR_BAD_CONTEXT;/* file handle is invalid */
448             }
449         }
450     }
451 
452     /* Set the returned position from the beginning of the file */
453     *pFilePos = fpos_seek_from_beginning;
454 
455     /* SEEK done, reset end of file value */
456     pFileContext->b_is_end_of_file = M4OSA_FALSE;
457 
458     return M4NO_ERROR;
459 }
460 
461 
462 /**
463  ************************************************************************
464  * @brief      This function asks to close the file (associated to the context)
465  * @note       The context of the core file reader/writer is freed.
466  * @param      context: (IN/OUT) Context of the core file reader
467  * @return     M4NO_ERROR: there is no error
468  * @return     M4ERR_PARAMETER: at least one parameter is NULL
469  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
470  * @return     M4ERR_ALLOC: there is no more memory available
471  ************************************************************************
472 */
473 
M4OSA_fileCommonClose(M4OSA_UInt16 core_id,M4OSA_Context pContext)474 M4OSA_ERR M4OSA_fileCommonClose(M4OSA_UInt16 core_id, M4OSA_Context pContext)
475 {
476     M4OSA_FileContext* pFileContext = pContext;
477     M4OSA_Int32 i32_err_code=0;
478 
479     M4OSA_TRACE3_2("M4OSA_fileCommonClose\tM4OSA_UInt16 %d\tM4OSA_Context 0x%x",
480                                                              core_id, pContext);
481     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext,
482               M4ERR_PARAMETER, "M4OSA_fileCommonClose: pContext is M4OSA_NULL");
483 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
484     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileContext->semaphore_context, M4ERR_BAD_CONTEXT,
485                      "M4OSA_fileCommonClose: semaphore_context is M4OSA_NULL");
486 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
487 
488     free(pFileContext->url_name);
489     pFileContext->url_name = M4OSA_NULL;
490 
491     free(pFileContext->file_name);
492     pFileContext->file_name = M4OSA_NULL;
493 
494     i32_err_code = fclose(pFileContext->file_desc);
495 
496     pFileContext->file_desc = M4OSA_NULL;
497 
498 #ifdef M4OSA_FILE_BLOCK_WITH_SEMAPHORE
499     M4OSA_semaphoreClose(pFileContext->semaphore_context);/* free the semaphore */
500 #endif /* M4OSA_FILE_BLOCK_WITH_SEMAPHORE */
501 
502     free(pFileContext);
503 
504     if (i32_err_code != 0)
505     {
506         M4OSA_DEBUG(M4ERR_BAD_CONTEXT, "M4OSA_fileCommonClose");
507         return M4ERR_BAD_CONTEXT;
508     }
509 
510     return M4NO_ERROR;
511 }
512 
513 
514 /**
515  ************************************************************************
516  * @brief      This function gets the file attributes (associated to the
517  *             context)
518  * @param      context: (IN) Context of the core file reader
519  * @param      attribute: (OUT) The file attribute (allocated by the caller)
520  * @return     M4NO_ERROR: there is no error
521  * @return     M4ERR_PARAMETER: at least one parameter is NULL
522  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
523  ************************************************************************
524 */
M4OSA_fileCommonGetAttribute(M4OSA_Context pContext,M4OSA_FileAttribute * pAttribute)525 M4OSA_ERR M4OSA_fileCommonGetAttribute(M4OSA_Context pContext, M4OSA_FileAttribute* pAttribute)
526 {
527 
528     M4OSA_FileContext* fileContext = pContext;
529 
530     struct stat TheStat;
531 
532     M4OSA_TRACE3_2("M4OSA_fileCommonGetAttribute\tM4OSA_Context 0x%x\t"
533         "M4OSA_FileAttribute* 0x%x", pContext, pAttribute);
534 
535     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext,        M4ERR_PARAMETER, "M4OSA_fileCommonGetAttribute");
536     M4OSA_DEBUG_IF2(M4OSA_NULL == pAttribute,    M4ERR_PARAMETER, "M4OSA_fileCommonGetAttribute");
537 
538     if(stat((char*)fileContext->url_name, &TheStat) != 0)
539     {
540         M4OSA_DEBUG(M4ERR_BAD_CONTEXT, "M4OSA_fileCommonGetAttribute");
541         return M4ERR_BAD_CONTEXT;
542     }
543 
544     pAttribute->creationDate.time = (M4OSA_Time)TheStat.st_ctime;
545     pAttribute->lastAccessDate.time = (M4OSA_Time)TheStat.st_atime;
546     pAttribute->modifiedDate.time = (M4OSA_Time)TheStat.st_mtime;
547 
548     pAttribute->creationDate.timeScale = 1;
549     pAttribute->lastAccessDate.timeScale = 1;
550     pAttribute->modifiedDate.timeScale = 1;
551 
552     pAttribute->creationDate.referenceYear = 1970;
553     pAttribute->lastAccessDate.referenceYear = 1970;
554     pAttribute->modifiedDate.referenceYear = 1970;
555 
556     pAttribute->modeAccess = fileContext->access_mode;
557 
558     return M4NO_ERROR;
559 }
560 
561 /**
562  ************************************************************************
563  * @brief      This function gets the file URL (associated to the context).
564  * @note
565  * @param      context: (IN) Context of the core file reader
566  * @param      url: (OUT) The buffer containing the URL (allocated by
567  *             M4OSA_fileCommonGetURL)
568  * @return     M4NO_ERROR: there is no error
569  * @return     M4ERR_PARAMETER: at least one parameter is NULL
570  * @return     M4ERR_BAD_CONTEXT: provided context is not a valid one
571  * @return     M4ERR_ALLOC: there is no more memory available
572  ************************************************************************
573 */
M4OSA_fileCommonGetURL(M4OSA_Context pContext,M4OSA_Char ** pUrl)574 M4OSA_ERR M4OSA_fileCommonGetURL(M4OSA_Context pContext, M4OSA_Char** pUrl)
575 {
576     M4OSA_FileContext* pFileContext = pContext;
577     M4OSA_UInt32    uiLength;
578 
579     M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Context 0x%x\tM4OSA_Char** 0x%x",
580                     pContext, pUrl);
581 
582     M4OSA_DEBUG_IF2(M4OSA_NULL == pContext,    M4ERR_PARAMETER,
583                               "M4OSA_fileCommonGetURL: pContext is M4OSA_NULL");
584     M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl,    M4ERR_PARAMETER,
585                                   "M4OSA_fileCommonGetURL: pUrl is M4OSA_NULL");
586 
587     uiLength = strlen((const char *)pFileContext->url_name)+1;
588 
589     /* Allocate the memory to store the url_name */
590     *pUrl = (M4OSA_Char*)M4OSA_32bitAlignedMalloc(uiLength, M4OSA_FILE_COMMON,
591                                     (M4OSA_Char*)"M4OSA_fileCommonGetURL: url");
592     if(M4OSA_NULL == *pUrl)
593     {
594         M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetURL");
595         return M4ERR_ALLOC;
596     }
597 
598     M4OSA_chrNCopy(*pUrl, pFileContext->url_name, uiLength);
599 
600     return M4NO_ERROR;
601 }
602 
603 
604 /**
605  ************************************************************************
606  * @brief      This function gets a string containing the file name associated
607  *             to the input URL.
608  * @note       The user should not forget to delete the output string using
609  *             M4OSA_strDestroy
610  * @param      pUrl:            (IN) The buffer containing the URL
611  * @param      pFileName:    (OUT) The string containing the URL. It is
612  *                            allocated inside this function
613  * @return     M4NO_ERROR: there is no error
614  * @return     M4ERR_NOT_IMPLEMENTED: the URL does not match with the supported
615  *             file
616  * @return     M4ERR_ALLOC: there is no more memory available
617  ************************************************************************
618 */
M4OSA_fileCommonGetFilename(M4OSA_Char * pUrl,M4OSA_Char ** pFileName)619 M4OSA_ERR M4OSA_fileCommonGetFilename(M4OSA_Char* pUrl, M4OSA_Char** pFileName)
620 {
621     M4OSA_Int32 i            = 0;
622     M4OSA_Int32 iUrlLen        = 0;
623     M4OSA_Int32 FileNameLen = 0;
624 
625     M4OSA_Char* ptrUrl        = M4OSA_NULL;
626     M4OSA_Char* ptrFilename    = M4OSA_NULL;
627 
628     M4OSA_TRACE3_2("M4OSA_fileCommonGetURL\tM4OSA_Char* %s\tM4OSA_Char** 0x%x",
629                                                                pUrl, pFileName);
630 
631     M4OSA_DEBUG_IF2(M4OSA_NULL == pUrl,    M4ERR_PARAMETER,
632                              "M4OSA_fileCommonGetFilename: pUrl is M4OSA_NULL");
633     M4OSA_DEBUG_IF2(M4OSA_NULL == pFileName,    M4ERR_PARAMETER,
634                         "M4OSA_fileCommonGetFilename: pFileName is M4OSA_NULL");
635 
636     *pFileName = M4OSA_NULL;
637 
638     /*Parse URL*/
639     iUrlLen = strlen((const char *)pUrl);
640     for(i=iUrlLen-1; i>=0; i--)
641     {
642         if (pUrl[i] != '\\' && pUrl[i] != '/')
643         {
644             FileNameLen++;
645         }
646         else
647         {
648             break; /* find the beginning of the file name */
649         }
650     }
651 
652     ptrFilename = (M4OSA_Char*) M4OSA_32bitAlignedMalloc(FileNameLen+1, M4OSA_FILE_COMMON,
653                     (M4OSA_Char*)"M4OSA_fileCommonGetFilename: Filename string");
654     if (ptrFilename == M4OSA_NULL)
655     {
656         M4OSA_DEBUG(M4ERR_ALLOC, "M4OSA_fileCommonGetFilename");
657         return M4ERR_ALLOC;
658     }
659 
660     ptrUrl = pUrl + (iUrlLen - FileNameLen);
661     M4OSA_chrNCopy(ptrFilename, ptrUrl, FileNameLen+1);
662 
663     *pFileName = ptrFilename;
664 
665     return M4NO_ERROR;
666 }
667 
668