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