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