support webm format
[platform/core/multimedia/libmm-fileinfo.git] / utils / mm_file_util_io.c
1 /*
2  * libmm-fileinfo
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Haejeong Kim <backto.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28
29 static unsigned char is_little_endian = 0;
30
31 inline static int _is_little_endian(void)
32 {
33         int i = 0x00000001;
34         return ((char *)&i)[0];
35 }
36
37 EXPORT_API
38 inline unsigned int mmfile_io_be_uint32(unsigned int value)
39 {
40         return (is_little_endian == 0) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
41 }
42
43 EXPORT_API
44 inline unsigned int mmfile_io_le_uint32(unsigned int value)
45 {
46         return (is_little_endian == 1) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
47 }
48
49 EXPORT_API
50 inline int mmfile_io_be_int32(unsigned int value)
51 {
52         return (is_little_endian == 0) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
53 }
54
55 EXPORT_API
56 inline int mmfile_io_le_int32(unsigned int value)
57 {
58         return (is_little_endian == 1) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
59 }
60
61 EXPORT_API
62 inline unsigned short mmfile_io_be_uint16(unsigned short value)
63 {
64         return (is_little_endian == 0) ? value : ((unsigned short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
65 }
66
67 EXPORT_API
68 inline unsigned short mmfile_io_le_uint16(unsigned short value)
69 {
70         return (is_little_endian == 1) ? value : ((unsigned short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
71 }
72
73 EXPORT_API
74 inline short mmfile_io_be_int16(unsigned short value)
75 {
76         return (is_little_endian == 0) ? value : ((short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
77 }
78
79 EXPORT_API
80 inline short mmfile_io_le_int16(unsigned short value)
81 {
82         return (is_little_endian == 1) ? value : ((short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
83 }
84
85
86
87
88 MMFileIOFunc *first_io_func = NULL;
89
90 static int _mmfile_open(MMFileIOHandle **handle, struct MMFileIOFunc *Func, const char *filename, int flags)
91 {
92         MMFileIOHandle *pHandle = NULL;
93         int err = 0;
94         int fileNameLen = 0;
95
96         if (!handle || !Func || !filename || !Func->mmfile_open) {
97                 debug_error(DEBUG, "invalid param\n");
98                 err = MMFILE_IO_FAILED;
99                 goto fail;
100         }
101
102         pHandle = mmfile_malloc(sizeof(MMFileIOHandle));
103         if (!pHandle) {
104                 debug_error(DEBUG, "mmfile_malloc: pHandle\n");
105                 err = MMFILE_IO_FAILED;
106                 goto fail;
107         }
108
109         *handle = pHandle;
110
111         pHandle->iofunc = Func;
112         pHandle->flags = flags;
113         pHandle->privateData = NULL;
114         fileNameLen = strlen(filename);
115
116         debug_msg(RELEASE, "[%d, %s]\n", fileNameLen, filename);
117
118         pHandle->fileName = mmfile_malloc(fileNameLen + 1);
119         if (!pHandle->fileName) {
120                 debug_error(DEBUG, "mmfile_malloc: pHandle->fileName\n");
121                 err = MMFILE_IO_FAILED;
122                 goto fail;
123         }
124
125         SAFE_STRLCPY(pHandle->fileName, filename, fileNameLen + 1);
126
127         err = Func->mmfile_open(pHandle, filename, flags);
128         if (err < 0) {
129                 debug_error(DEBUG, "mmfile_open: pHandle->fileName\n");
130                 err = MMFILE_IO_FAILED;
131                 goto fail;
132         }
133
134         return MMFILE_IO_SUCCESS;
135
136 fail:
137         if (handle && *handle) { /* fix for prevent */
138                 mmfile_close(*handle);
139                 *handle = NULL;
140         }
141
142         return err;
143 }
144
145 EXPORT_API
146 int mmfile_open(MMFileIOHandle **handle, const char *filename, int flags)
147 {
148         MMFileIOFunc   *pFuc = NULL;
149         const char  *pFile = NULL;
150         char        handle_str[256] = {0, };
151         char        *pHandleName = NULL;
152
153         if (!handle || !filename) {
154                 debug_error(DEBUG, "invalid param\n");
155                 return MMFILE_IO_FAILED;
156         }
157
158         memset(handle_str, 0x00, sizeof(handle_str));
159
160         pFile = filename;
161         pHandleName = handle_str;
162
163         /* scan to find ':' */
164         while (*pFile != '\0' && *pFile != ':') {
165                 if (!isalpha(*pFile)) {
166                         goto file_handle;
167                 }
168
169                 if ((pHandleName - handle_str) < (int)sizeof(handle_str) - 1) {
170                         *pHandleName++ = *pFile;
171                 }
172                 pFile++;
173         }
174
175         if (*pFile == '\0') {
176 file_handle:
177                 SAFE_STRLCPY(handle_str, "file", sizeof(handle_str));
178         } else {
179                 *pHandleName = '\0';
180         }
181
182         pFuc = first_io_func;
183
184         while (pFuc != NULL) {
185                 if (!strcmp(handle_str, pFuc->handleName)) {
186                         return _mmfile_open(handle, pFuc, filename, flags);
187                 }
188                 pFuc = pFuc->next;
189         }
190
191         *handle = NULL;
192
193         return MMFILE_IO_FAILED;
194 }
195
196 EXPORT_API
197 int mmfile_read(MMFileIOHandle *handle, unsigned char *buf, int size)
198 {
199         int ret = 0;
200         if (!handle || (handle->flags & MMFILE_WRONLY)) {
201                 return MMFILE_IO_FAILED;
202         }
203
204         if (!handle->iofunc || !handle->iofunc->mmfile_read) {
205                 return MMFILE_IO_FAILED;
206         }
207
208         ret = handle->iofunc->mmfile_read(handle, buf, size);
209         return ret;
210 }
211
212 EXPORT_API
213 int mmfile_write(MMFileIOHandle *handle, unsigned char *buf, int size)
214 {
215         int ret = 0;
216         if (!handle || !(handle->flags & (MMFILE_WRONLY | MMFILE_RDWR))) {
217                 return MMFILE_IO_FAILED;
218         }
219
220         if (!handle->iofunc || !handle->iofunc->mmfile_write) {
221                 return MMFILE_IO_FAILED;
222         }
223
224         ret = handle->iofunc->mmfile_write(handle, buf, size);
225         return ret;
226 }
227
228 EXPORT_API
229 int64_t mmfile_seek(MMFileIOHandle *handle, int64_t pos, int whence)
230 {
231         long long ret = 0;
232         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_seek) {
233                 return MMFILE_IO_FAILED;
234         }
235
236         ret = handle->iofunc->mmfile_seek(handle, pos, whence);
237         return ret;
238 }
239
240 EXPORT_API
241 long long mmfile_tell(MMFileIOHandle *handle)
242 {
243         long long ret = 0;
244         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_tell) {
245                 return MMFILE_IO_FAILED;
246         }
247
248         ret = handle->iofunc->mmfile_tell(handle);
249         return ret;
250 }
251
252 EXPORT_API
253 int mmfile_close(MMFileIOHandle *handle)
254 {
255         int ret = 0;
256
257         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_close) {
258                 return MMFILE_IO_FAILED;
259         }
260
261         ret = handle->iofunc->mmfile_close(handle);
262
263         if (handle->fileName) {
264                 mmfile_free(handle->fileName);
265         }
266
267         if (handle) mmfile_free(handle);
268
269         return ret;
270 }
271
272 EXPORT_API
273 int mmfile_register_io_func(MMFileIOFunc *iofunc)
274 {
275         MMFileIOFunc **ptr = NULL;
276
277         if (!iofunc) {
278                 return MMFILE_IO_FAILED;
279         }
280
281         ptr = &first_io_func;
282         while (*ptr != NULL) {
283                 ptr = &(*ptr)->next;
284         }
285         *ptr = iofunc;
286         iofunc->next = NULL;
287
288         return MMFILE_IO_SUCCESS;
289 }
290
291 EXPORT_API
292 int mmfile_register_io_all()
293 {
294         static int initialized = 0;
295
296         if (initialized) {
297                 return MMFILE_IO_FAILED;
298         }
299
300         is_little_endian = _is_little_endian();
301         initialized = 1;
302
303         extern MMFileIOFunc mmfile_file_io_handler;
304         extern MMFileIOFunc mmfile_mem_io_handler;
305         extern MMFileIOFunc mmfile_mmap_io_handler;
306
307         mmfile_register_io_func(&mmfile_file_io_handler);
308         mmfile_register_io_func(&mmfile_mem_io_handler);
309         mmfile_register_io_func(&mmfile_mmap_io_handler);
310
311         return MMFILE_IO_SUCCESS;
312 }
313