support webm format
[platform/core/multimedia/libmm-fileinfo.git] / utils / mm_file_util_io_mem.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 <stdlib.h>
24 #include <string.h>
25
26 #include "mm_file_debug.h"
27 #include "mm_file_utils.h"
28
29
30 typedef struct {
31         unsigned char *ptr;
32         long long size;
33         long long offset;
34         int     state;
35 } MMFmemIOHandle;
36
37 static int mmf_mem_open(MMFileIOHandle *handle, const char *filename, int flags)
38 {
39         MMFmemIOHandle *memHandle = NULL;
40         char **splitedString = NULL;
41
42         if (!handle || !filename || !handle->iofunc || !handle->iofunc->handleName) {
43                 debug_error(DEBUG, "invalid param\n");
44                 return MMFILE_IO_FAILED;
45         }
46
47         filename += strlen(handle->iofunc->handleName) + 3; /* ://%d:%d means (memory addr:mem size)*/
48
49         splitedString = mmfile_strsplit(filename, ":");
50         if (splitedString == NULL) {
51                 debug_error(DEBUG, "invalid param\n");
52                 return MMFILE_IO_FAILED;
53         }
54
55         if (!splitedString[0] || !splitedString[1]) {
56                 debug_error(DEBUG, "invalid param\n");
57                 goto exception;
58         }
59
60         memHandle = mmfile_malloc(sizeof(MMFmemIOHandle));
61         if (!memHandle) {
62                 debug_error(DEBUG, "error: mmfile_malloc memHandle\n");
63                 goto exception;
64         }
65
66         memHandle->ptr = (unsigned char *)atoll(splitedString[0]);      /*memory allocation address changed. memHandle->ptr = (unsigned char*)atoi(splitedString[0]); */
67         memHandle->size = atoi(splitedString[1]);
68         memHandle->offset = 0;
69         memHandle->state = 0;
70
71         handle->privateData = (void *) memHandle;
72
73         if (splitedString) {
74                 mmfile_strfreev(splitedString);
75         }
76
77         return MMFILE_IO_SUCCESS;
78
79 exception:
80
81         if (splitedString) {
82                 mmfile_strfreev(splitedString);
83         }
84
85 #if 0   /*dead code */
86         if (memHandle) {
87                 mmfile_free(memHandle);
88                 handle->privateData  = NULL;
89         }
90 #endif
91
92         return MMFILE_IO_FAILED;
93 }
94
95 static int mmf_mem_read(MMFileIOHandle *h, unsigned char *buf, int size)
96 {
97         MMFmemIOHandle *memHandle = NULL;
98         const unsigned char *c = NULL;
99         int len = 0;
100
101         if (!h || !h->privateData || !buf || size <= 0) {
102                 debug_error(DEBUG, "invalid para\n");
103                 return MMFILE_IO_FAILED;
104         }
105
106         memHandle = h->privateData;
107
108         if (!memHandle->ptr) {
109                 debug_error(DEBUG, "invalid para\n");
110                 return MMFILE_IO_FAILED;
111         }
112
113         c = memHandle->ptr + memHandle->offset;
114
115         if (memHandle->state != EOF) {
116                 len = size;
117                 if (len + memHandle->offset > memHandle->size) {
118                         len = memHandle->size - memHandle->offset;
119                 }
120         }
121
122         memcpy(buf, c, len);
123
124         memHandle->offset += len;
125
126         if (memHandle->offset == memHandle->size) {
127                 memHandle->state = EOF;
128         }
129
130         return len;
131 }
132
133 static int mmf_mem_write(MMFileIOHandle *h, unsigned char *buf, int size)
134 {
135         MMFmemIOHandle *memHandle = NULL;
136         unsigned char *c = NULL;
137         int len = 0;
138
139         if (!h || !h->privateData || !buf) {
140                 debug_error(DEBUG, "invalid para\n");
141                 return MMFILE_IO_FAILED;
142         }
143
144         memHandle = h->privateData;
145
146         c = memHandle->ptr + memHandle->offset;
147
148         if (memHandle->state != EOF) {
149                 len = size;
150                 if (len + memHandle->offset > memHandle->size) {
151                         len = memHandle->size - memHandle->offset;
152                 }
153         }
154
155         memcpy(c, buf, len);
156
157         memHandle->offset += len;
158
159         if (memHandle->offset == memHandle->size) {
160                 memHandle->state = EOF;
161         }
162
163         return len;
164 }
165
166
167 static int64_t mmf_mem_seek(MMFileIOHandle *h, int64_t pos, int whence)
168 {
169         MMFmemIOHandle *memHandle = NULL;
170         long tmp_offset = 0;
171
172         if (!h || !h->privateData) {
173                 debug_error(DEBUG, "invalid para\n");
174                 return MMFILE_IO_FAILED;
175         }
176
177         memHandle = h->privateData;
178
179         switch (whence) {
180         case MMFILE_SEEK_SET:
181                 tmp_offset = 0 + pos;
182                 break;
183         case MMFILE_SEEK_CUR:
184                 tmp_offset = memHandle->offset + pos;
185                 break;
186         case MMFILE_SEEK_END:
187                 tmp_offset = memHandle->size + pos;
188                 break;
189         default:
190                 return MMFILE_IO_FAILED;
191         }
192
193         /*check validation*/
194         if (tmp_offset < 0) {
195                 debug_error(DEBUG, "invalid file offset\n");
196                 return MMFILE_IO_FAILED;
197         }
198
199         /*set */
200         memHandle->state = (tmp_offset >= memHandle->size) ? EOF : !EOF;
201         memHandle->offset = tmp_offset;
202
203         return memHandle->offset;
204 }
205
206
207 static long long mmf_mem_tell(MMFileIOHandle *h)
208 {
209         MMFmemIOHandle *memHandle = NULL;
210
211         if (!h || !h->privateData) {
212                 debug_error(DEBUG, "invalid para\n");
213                 return MMFILE_IO_FAILED;
214         }
215
216         memHandle = h->privateData;
217
218         return memHandle->offset;
219 }
220
221 static int mmf_mem_close(MMFileIOHandle *h)
222 {
223         MMFmemIOHandle *memHandle = NULL;
224
225         if (!h || !h->privateData) {
226                 debug_error(DEBUG, "invalid para\n");
227                 return MMFILE_IO_FAILED;
228         }
229
230         memHandle = h->privateData;
231
232         if (memHandle) {
233                 mmfile_free(memHandle);
234                 h->privateData = NULL;
235         }
236
237         return MMFILE_IO_SUCCESS;
238 }
239
240
241 MMFileIOFunc mmfile_mem_io_handler = {
242         "mem",
243         mmf_mem_open,
244         mmf_mem_read,
245         mmf_mem_write,
246         mmf_mem_seek,
247         mmf_mem_tell,
248         mmf_mem_close,
249         NULL
250 };