• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
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
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /*! \file oscl_file_native.cpp
19     \brief This file contains file io APIs
20 */
21 
22 #include "oscl_file_native.h"
23 #include "oscl_stdstring.h"
24 #include "oscl_utf8conv.h"
25 #include "oscl_int64_utils.h"
26 
27 #ifdef ENABLE_SHAREDFD_PLAYBACK
28 #undef LOG_TAG
29 #define LOG_TAG "OsclNativeFile"
30 #include <utils/Log.h>
31 #endif
32 #include "oscl_mem.h"
33 #include "oscl_file_types.h"
34 #include "oscl_file_handle.h"
35 
36 // FIXME:
37 // Is 100 milliseconds a good choice for writing out a single
38 // compressed video frame?
39 static const int FILE_WRITER_SPEED_TOLERANCE_IN_MILLISECONDS = 100;
40 
OsclNativeFile()41 OsclNativeFile::OsclNativeFile()
42 {
43     iOpenFileHandle = false;
44     iMode = 0;
45 
46     iFile = 0;
47 #ifdef ENABLE_SHAREDFD_PLAYBACK
48     iSharedFd = -1;
49 #endif
50 
51 }
52 
~OsclNativeFile()53 OsclNativeFile::~OsclNativeFile()
54 {
55 }
56 
Open(const OsclFileHandle & aHandle,uint32 mode,const OsclNativeFileParams & params,Oscl_FileServer & fileserv)57 int32  OsclNativeFile::Open(const OsclFileHandle& aHandle, uint32 mode
58                             , const OsclNativeFileParams& params
59                             , Oscl_FileServer& fileserv)
60 {
61     //open with an external file handle
62 
63     OSCL_UNUSED_ARG(fileserv);
64 
65     iMode = mode;
66     iOpenFileHandle = true;
67 
68     {
69         OSCL_UNUSED_ARG(params);
70         //Just save the open file handle
71         iFile = aHandle.Handle();
72     }
73 
74     return 0;
75 }
76 
OpenModeToString(uint32 mode,char mode_str[4])77 static void OpenModeToString(uint32 mode, char mode_str[4])
78 {
79     uint32 index = 0;
80 
81     if (mode & Oscl_File::MODE_READWRITE)
82     {
83         if (mode & Oscl_File::MODE_APPEND)
84         {
85             mode_str[index++] = 'a';
86             mode_str[index++] = '+';
87         }
88         else
89         {
90             mode_str[index++] = 'w';
91             mode_str[index++] = '+';
92         }
93     }
94     else if (mode & Oscl_File::MODE_APPEND)
95     {
96         mode_str[index++] = 'a';
97         mode_str[index++] = '+';
98     }
99     else if (mode & Oscl_File::MODE_READ)
100     {
101         mode_str[index++] = 'r';
102     }
103     else if (mode & Oscl_File::MODE_READ_PLUS)
104     {
105         mode_str[index++] = 'r';
106         mode_str[index++] = '+';
107     }
108 
109     if (mode & Oscl_File::MODE_TEXT)
110     {
111         mode_str[index++] = 't';
112     }
113     else
114     {
115         mode_str[index++] = 'b';
116     }
117 
118     mode_str[index++] = '\0';
119 }
120 
OpenFileOrSharedFd(const char * filename,const char * openmode)121 int32 OsclNativeFile::OpenFileOrSharedFd(
122     const char *filename, const char *openmode)
123 {
124 #ifdef ENABLE_SHAREDFD_PLAYBACK
125     int fd;
126     long long offset;
127     long long len;
128     if (sscanf(filename, "sharedfd://%d:%lld:%lld", &fd, &offset, &len) == 3)
129     {
130         iSharedFd = fd;
131         iSharedFilePosition = 0;
132         iSharedFileOffset = offset;
133         long long size = lseek64(iSharedFd, 0, SEEK_END);
134         lseek64(iSharedFd, 0, SEEK_SET);
135         size -= offset;
136         iSharedFileSize = size < len ? size : len;
137     }
138     else
139 #endif
140     {
141         if ((iFile = fopen(filename, openmode)) == NULL)
142         {
143             return -1;
144         }
145     }
146 
147     return 0;
148 }
149 
Open(const oscl_wchar * filename,uint32 mode,const OsclNativeFileParams & params,Oscl_FileServer & fileserv)150 int32 OsclNativeFile::Open(const oscl_wchar *filename, uint32 mode
151                            , const OsclNativeFileParams& params
152                            , Oscl_FileServer& fileserv)
153 {
154     iMode = mode;
155     iOpenFileHandle = false;
156 
157     {
158         OSCL_UNUSED_ARG(fileserv);
159         OSCL_UNUSED_ARG(params);
160 
161         if (!filename || *filename == '\0') return -1; // Null string not supported in fopen, error out
162 
163         char openmode[4];
164 
165         OpenModeToString(mode, openmode);
166 
167 #ifdef _UNICODE
168         oscl_wchar convopenmode[4];
169         if (0 == oscl_UTF8ToUnicode(openmode, oscl_strlen(openmode), convopenmode, 4))
170         {
171             return -1;
172         }
173 
174         if ((iFile = _wfopen(filename, convopenmode)) == NULL)
175         {
176             return -1;
177         }
178 #else
179         //Convert to UTF8
180         char convfilename[OSCL_IO_FILENAME_MAXLEN];
181         if (0 == oscl_UnicodeToUTF8(filename, oscl_strlen(filename), convfilename, OSCL_IO_FILENAME_MAXLEN))
182         {
183             return -1;
184         }
185         return OpenFileOrSharedFd(convfilename, openmode);
186 #endif
187     }
188 
189 }
190 
Open(const char * filename,uint32 mode,const OsclNativeFileParams & params,Oscl_FileServer & fileserv)191 int32 OsclNativeFile::Open(const char *filename, uint32 mode
192                            , const OsclNativeFileParams& params
193                            , Oscl_FileServer& fileserv)
194 {
195     iMode = mode;
196     iOpenFileHandle = false;
197 
198     OSCL_UNUSED_ARG(fileserv);
199     OSCL_UNUSED_ARG(params);
200 
201     if (!filename || *filename == '\0') return -1; // Null string not supported in fopen, error out
202 
203     char openmode[4];
204 
205     OpenModeToString(mode, openmode);
206 
207     return OpenFileOrSharedFd(filename, openmode);
208 
209 }
210 
Size()211 TOsclFileOffset OsclNativeFile::Size()
212 {
213     //this is the default for platforms with no
214     //native size query.
215     //Just do seek to end, tell, then seek back.
216     TOsclFileOffset curPos = Tell();
217     if (curPos >= 0
218             && Seek(0, Oscl_File::SEEKEND) == 0)
219     {
220         TOsclFileOffset endPos = Tell();
221         if (Seek(curPos, Oscl_File::SEEKSET) == 0)
222         {
223             return endPos;
224         }
225         else
226         {
227             return (-1);
228         }
229     }
230     return (-1);
231 }
232 
Close()233 int32 OsclNativeFile::Close()
234 {
235     int32 closeret = 0;
236 
237     {
238         if (iOpenFileHandle)
239             closeret = Flush();
240         else if (iFile != NULL)
241         {
242             closeret = fclose(iFile);
243             iFile = NULL;
244         }
245 #ifdef ENABLE_SHAREDFD_PLAYBACK
246         else if (iSharedFd >= 0)
247         {
248             // we don't need to, and in fact MUST NOT, close mSharedFd here,
249             // since it might still be shared by another OsclFileNative, and
250             // will be closed by the playerdriver when we're done with it.
251             closeret = 0;
252         }
253 #endif
254         else
255         {
256             return -1; //Linux Porting : Fix 1
257         }
258     }
259 
260     return closeret;
261 }
262 
263 
Read(OsclAny * buffer,uint32 size,uint32 numelements)264 uint32 OsclNativeFile::Read(OsclAny *buffer, uint32 size, uint32 numelements)
265 {
266 #ifdef ENABLE_SHAREDFD_PLAYBACK
267     if (iSharedFd >= 0)
268     {
269         // restore position, no locking is needed because all access to the
270         // shared filedescriptor is done by the same thread.
271         lseek64(iSharedFd, iSharedFilePosition + iSharedFileOffset, SEEK_SET);
272         uint32 count = size * numelements;
273         if (iSharedFilePosition + count > iSharedFileSize)
274         {
275             count = iSharedFileSize - iSharedFilePosition;
276         }
277         ssize_t numread = read(iSharedFd, buffer, count);
278         // unlock
279         long long curpos = lseek64(iSharedFd, 0, SEEK_CUR);
280         if (curpos >= 0)
281         {
282             iSharedFilePosition = curpos - iSharedFileOffset;
283         }
284         if (numread < 0)
285         {
286             return numread;
287         }
288         return numread / size;
289     }
290 #endif
291 
292     if (iFile)
293     {
294         return fread(buffer, OSCL_STATIC_CAST(int32, size), OSCL_STATIC_CAST(int32, numelements), iFile);
295     }
296     return 0;
297 }
298 
HasAsyncRead()299 bool OsclNativeFile::HasAsyncRead()
300 {
301     return false;//not supported.
302 }
303 
ReadAsync(OsclAny * buffer,uint32 size,uint32 numelements,OsclAOStatus & status)304 int32 OsclNativeFile::ReadAsync(OsclAny*buffer, uint32 size, uint32 numelements, OsclAOStatus& status)
305 {
306     OSCL_UNUSED_ARG(buffer);
307     OSCL_UNUSED_ARG(size);
308     OSCL_UNUSED_ARG(numelements);
309     OSCL_UNUSED_ARG(status);
310     return -1;//not supported
311 }
312 
ReadAsyncCancel()313 void OsclNativeFile::ReadAsyncCancel()
314 {
315 }
316 
GetReadAsyncNumElements()317 uint32 OsclNativeFile::GetReadAsyncNumElements()
318 {
319     return 0;//not supported
320 }
321 
322 
323 
Write(const OsclAny * buffer,uint32 size,uint32 numelements)324 uint32 OsclNativeFile::Write(const OsclAny *buffer, uint32 size, uint32 numelements)
325 {
326 #ifdef ENABLE_SHAREDFD_PLAYBACK
327     if (iSharedFd >= 0)
328         return 0;
329 #endif
330     if (iFile)
331     {
332         struct timeval startTimeVal, endTimeVal;
333         gettimeofday(&startTimeVal, NULL);
334         uint32 items = fwrite(buffer, OSCL_STATIC_CAST(int32, size), OSCL_STATIC_CAST(int32, numelements), iFile);
335         gettimeofday(&endTimeVal, NULL);
336         long long timeInMicroSeconds = (endTimeVal.tv_sec - startTimeVal.tv_sec) * 1000000LL + (endTimeVal.tv_usec - startTimeVal.tv_usec);
337         if (timeInMicroSeconds/1000 > FILE_WRITER_SPEED_TOLERANCE_IN_MILLISECONDS) {
338             LOGW("writing %d bytes takes too long (%lld micro seconds)", items, timeInMicroSeconds);
339         }
340         return items;
341     }
342     return 0;
343 }
344 
Seek(TOsclFileOffset offset,Oscl_File::seek_type origin)345 int32 OsclNativeFile::Seek(TOsclFileOffset offset, Oscl_File::seek_type origin)
346 {
347 
348     {
349 #ifdef ENABLE_SHAREDFD_PLAYBACK
350         if (iSharedFd >= 0)
351         {
352             int newpos = iSharedFilePosition;
353             if (origin == Oscl_File::SEEKCUR) newpos = newpos + offset;
354             else if (origin == Oscl_File::SEEKSET) newpos = offset;
355             else if (origin == Oscl_File::SEEKEND) newpos = iSharedFileSize + offset;
356             if (newpos < 0)
357                 return EINVAL;
358             if (newpos > iSharedFileSize) // is this valid?
359                 newpos = iSharedFileSize;
360             iSharedFilePosition = newpos;
361             return 0;
362         }
363 #endif
364         if (iFile)
365         {
366             int32 seekmode = SEEK_CUR;
367 
368             if (origin == Oscl_File::SEEKCUR)
369                 seekmode = SEEK_CUR;
370             else if (origin == Oscl_File::SEEKSET)
371                 seekmode = SEEK_SET;
372             else if (origin == Oscl_File::SEEKEND)
373                 seekmode = SEEK_END;
374 #if OSCL_HAS_LARGE_FILE_SUPPORT
375             return fseeko(iFile, offset, seekmode);
376 #else
377             return fseek(iFile, offset, seekmode);
378 #endif
379         }
380     }
381     return -1;
382 }
383 
384 
Tell()385 TOsclFileOffset OsclNativeFile::Tell()
386 {
387     TOsclFileOffset result = -1;
388 #ifdef ENABLE_SHAREDFD_PLAYBACK
389     if (iSharedFd >= 0)
390         return iSharedFilePosition;
391 #endif
392     if (iFile)
393     {
394 #if OSCL_HAS_LARGE_FILE_SUPPORT
395         result = ftello(iFile);
396 #else
397         result = ftell(iFile);
398 #endif
399     }
400     return result;
401 }
402 
403 
404 
Flush()405 int32 OsclNativeFile::Flush()
406 {
407 #ifdef ENABLE_SHAREDFD_PLAYBACK
408     if (iSharedFd >= 0)
409         return iSharedFilePosition >= iSharedFileSize;
410 #endif
411     if (iFile)
412         return fflush(iFile);
413     return EOF;
414 }
415 
416 
417 
EndOfFile()418 int32 OsclNativeFile::EndOfFile()
419 {
420 #ifdef ENABLE_SHAREDFD_PLAYBACK
421     if (iSharedFd >= 0)
422         return iSharedFilePosition >= iSharedFileSize;
423 #endif
424     if (iFile)
425         return feof(iFile);
426     return 0;
427 }
428 
429 
GetError()430 int32 OsclNativeFile::GetError()
431 {
432 //FIXME ENABLE_SHAREDFD_PLAYBACK
433     if (iFile)
434         return ferror(iFile);
435     return 0;
436 }
437 
438