Fix coverity issue
[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 #define HANDLE_STRING_MAX 256
30
31 static unsigned char is_little_endian = 0;
32
33 inline static int _is_little_endian(void)
34 {
35         int i = 0x00000001;
36         return ((char *)&i)[0];
37 }
38
39
40 inline unsigned int mmfile_io_be_uint32(unsigned int value)
41 {
42         return (is_little_endian == 0) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
43 }
44
45
46 inline unsigned int mmfile_io_le_uint32(unsigned int value)
47 {
48         return (is_little_endian == 1) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
49 }
50
51
52 inline int mmfile_io_be_int32(unsigned int value)
53 {
54         return (is_little_endian == 0) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
55 }
56
57
58 inline int mmfile_io_le_int32(unsigned int value)
59 {
60         return (is_little_endian == 1) ? value : ((unsigned int)((((value) & 0xFF000000) >> 24) | (((value) & 0x00FF0000) >> 8) | (((value) & 0x0000FF00) << 8) | (((value) & 0x000000FF) << 24)));
61 }
62
63
64 inline unsigned short mmfile_io_be_uint16(unsigned short value)
65 {
66         return (is_little_endian == 0) ? value : ((unsigned short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
67 }
68
69
70 inline unsigned short mmfile_io_le_uint16(unsigned short value)
71 {
72         return (is_little_endian == 1) ? value : ((unsigned short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
73 }
74
75
76 inline short mmfile_io_be_int16(unsigned short value)
77 {
78         return (is_little_endian == 0) ? value : ((short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
79 }
80
81
82 inline short mmfile_io_le_int16(unsigned short value)
83 {
84         return (is_little_endian == 1) ? value : ((short)((((value) & 0xFF00) >> 8) | (((value) & 0x00FF) << 8)));
85 }
86
87
88 inline float mmfile_io_be_float32(float value)
89 {
90         /* Additional variables were introduced to avoid dereferencing type-punned pointer compilation error */
91         float *value_ptr = &value;
92         unsigned int result_uint = ((((*(unsigned int*)value_ptr) & 0x000000FF) << 24) | (((*(unsigned int*)value_ptr) & 0x0000FF00) << 8) | (((*(unsigned int*)value_ptr) & 0x00FF0000) >> 8) | (((*(unsigned int*)value_ptr) & 0xFF000000) >> 24));
93         float *result = (float*)&result_uint;
94         return (is_little_endian == 0) ? value : *result;
95 }
96
97 static MMFileIOFunc *first_io_func = NULL;
98
99 static int _mmfile_open(MMFileIOHandle **handle, struct MMFileIOFunc *Func, const char *filename, int flags)
100 {
101         MMFileIOHandle *pHandle = NULL;
102         int err = 0;
103
104         if (!handle || !Func || !filename || !Func->mmfile_open) {
105                 debug_error(DEBUG, "invalid param\n");
106                 err = MMFILE_UTIL_FAIL;
107                 goto fail;
108         }
109
110         pHandle = g_new0(MMFileIOHandle, 1);
111
112         *handle = pHandle;
113
114         pHandle->iofunc = Func;
115         pHandle->flags = flags;
116         pHandle->privateData = NULL;
117
118         debug_msg(RELEASE, "[%s]\n", filename);
119
120         pHandle->fileName = g_strdup(filename);
121
122         err = Func->mmfile_open(pHandle, filename, flags);
123         if (err < 0) {
124                 debug_error(DEBUG, "mmfile_open: pHandle->fileName\n");
125                 err = MMFILE_UTIL_FAIL;
126                 goto fail;
127         }
128
129         return MMFILE_UTIL_SUCCESS;
130
131 fail:
132         if (handle && *handle) { /* fix for prevent */
133                 mmfile_close(*handle);
134                 *handle = NULL;
135         }
136
137         return err;
138 }
139
140
141 int mmfile_open(MMFileIOHandle **handle, const char *filename, int flags)
142 {
143         MMFileIOFunc   *pFuc = NULL;
144         const char  *pFile = NULL;
145         char        handle_str[HANDLE_STRING_MAX] = {0, };
146         char        *pHandleName = NULL;
147
148         if (!handle || !filename) {
149                 debug_error(DEBUG, "invalid param\n");
150                 return MMFILE_UTIL_FAIL;
151         }
152
153         memset(handle_str, 0x00, HANDLE_STRING_MAX);
154
155         pFile = filename;
156         pHandleName = handle_str;
157
158         /* scan to find ':' */
159         while (*pFile != '\0' && *pFile != ':') {
160                 if (!isalpha(*pFile)) {
161                         goto file_handle;
162                 }
163
164                 if ((pHandleName - handle_str) < HANDLE_STRING_MAX - 1) {
165                         *pHandleName++ = *pFile;
166                 }
167                 pFile++;
168         }
169
170         if (*pFile == '\0') {
171 file_handle:
172                 if (g_strlcpy(handle_str, "file", HANDLE_STRING_MAX) >= HANDLE_STRING_MAX)
173                         debug_error(DEBUG, "truncation occurred.");
174         } else {
175                 *pHandleName = '\0';
176         }
177
178         pFuc = first_io_func;
179
180         while (pFuc != NULL) {
181                 if (!strcmp(handle_str, pFuc->handleName)) {
182                         return _mmfile_open(handle, pFuc, filename, flags);
183                 }
184                 pFuc = pFuc->next;
185         }
186
187         *handle = NULL;
188
189         return MMFILE_UTIL_FAIL;
190 }
191
192
193 int mmfile_read(MMFileIOHandle *handle, unsigned char *buf, int size)
194 {
195         int ret = 0;
196         if (!handle) {
197                 return MMFILE_UTIL_FAIL;
198         }
199
200         if (!handle->iofunc || !handle->iofunc->mmfile_read) {
201                 return MMFILE_UTIL_FAIL;
202         }
203
204         ret = handle->iofunc->mmfile_read(handle, buf, size);
205         return ret;
206 }
207
208
209 int mmfile_write(MMFileIOHandle *handle, unsigned char *buf, int size)
210 {
211         int ret = 0;
212         if (!handle) {
213                 return MMFILE_UTIL_FAIL;
214         }
215
216         if (!handle->iofunc || !handle->iofunc->mmfile_write) {
217                 return MMFILE_UTIL_FAIL;
218         }
219
220         ret = handle->iofunc->mmfile_write(handle, buf, size);
221         return ret;
222 }
223
224
225 int64_t mmfile_seek(MMFileIOHandle *handle, int64_t pos, int whence)
226 {
227         long long ret = 0;
228         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_seek) {
229                 return MMFILE_UTIL_FAIL;
230         }
231
232         ret = handle->iofunc->mmfile_seek(handle, pos, whence);
233         return ret;
234 }
235
236
237 long long mmfile_tell(MMFileIOHandle *handle)
238 {
239         long long ret = 0;
240         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_tell) {
241                 return MMFILE_UTIL_FAIL;
242         }
243
244         ret = handle->iofunc->mmfile_tell(handle);
245         return ret;
246 }
247
248
249 long long mmfile_get_size(MMFileIOHandle *handle)
250 {
251         long long filesize = 0;
252         long long cur_pos = 0;
253
254         cur_pos = mmfile_tell(handle);
255         if (cur_pos < 0)
256                 return MMFILE_UTIL_FAIL;
257
258         if (mmfile_seek(handle, 0L, MMFILE_SEEK_SET) < 0)
259                 return MMFILE_UTIL_FAIL;
260
261         if (mmfile_seek(handle, 0L, MMFILE_SEEK_END) < 0)
262                 return MMFILE_UTIL_FAIL;
263
264         filesize = mmfile_tell(handle);
265
266         if (mmfile_seek(handle, cur_pos, MMFILE_SEEK_SET) < 0)
267                 debug_error(DEBUG, "failed to restore current position");
268
269         return filesize;
270 }
271
272
273 int mmfile_close(MMFileIOHandle *handle)
274 {
275         int ret = 0;
276
277         if (!handle || !handle->iofunc || !handle->iofunc->mmfile_close) {
278                 return MMFILE_UTIL_FAIL;
279         }
280
281         ret = handle->iofunc->mmfile_close(handle);
282
283         mmfile_free(handle->fileName);
284         mmfile_free(handle);
285
286         return ret;
287 }
288
289
290 int mmfile_register_io_func(MMFileIOFunc *iofunc)
291 {
292         MMFileIOFunc **ptr = NULL;
293
294         if (!iofunc) {
295                 return MMFILE_UTIL_FAIL;
296         }
297
298         ptr = &first_io_func;
299         while (*ptr != NULL) {
300                 ptr = &(*ptr)->next;
301         }
302         *ptr = iofunc;
303         iofunc->next = NULL;
304
305         return MMFILE_UTIL_SUCCESS;
306 }
307
308
309 int mmfile_register_io_all()
310 {
311         static int initialized = 0;
312
313         if (initialized) {
314                 return MMFILE_UTIL_FAIL;
315         }
316
317         is_little_endian = _is_little_endian();
318         initialized = 1;
319
320         extern MMFileIOFunc mmfile_file_io_handler;
321         extern MMFileIOFunc mmfile_mem_io_handler;
322         extern MMFileIOFunc mmfile_mmap_io_handler;
323
324         mmfile_register_io_func(&mmfile_file_io_handler);
325         mmfile_register_io_func(&mmfile_mem_io_handler);
326         mmfile_register_io_func(&mmfile_mmap_io_handler);
327
328         return MMFILE_UTIL_SUCCESS;
329 }