4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Haejeong Kim <backto.kim@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
28 #include <sys/types.h>
33 #include "mm_file_debug.h"
34 #include "mm_file_utils.h"
45 static int mmf_mmap_open(MMFileIOHandle *handle, const char *filename, int flags)
47 MMFMMapIOHandle *mmapHandle = NULL;
48 struct stat finfo = {0, };
49 int access = O_RDONLY;
51 if (!handle || !filename || !handle->iofunc || !handle->iofunc->handleName) {
52 debug_error(DEBUG, "invalid param\n");
53 return MMFILE_UTIL_FAIL;
56 filename += strlen(handle->iofunc->handleName) + 3; /* :// */
58 mmapHandle = g_new0(MMFMMapIOHandle, 1);
64 mmapHandle->fd = open(filename, access);
65 if (mmapHandle->fd < 0) {
66 debug_error(DEBUG, "error: open error: %s\n", filename);
70 if (fstat(mmapHandle->fd, &finfo) == -1) {
71 debug_error(DEBUG, "error: fstat\n");
75 if (!S_ISREG(finfo.st_mode)) {
76 debug_error(DEBUG, "error: it is not regular file\n");
80 mmapHandle->size = finfo.st_size;
81 mmapHandle->offset = 0;
82 mmapHandle->state = 0;
84 /*mmapHandle->ptr = mmap64(0, mmapHandle->size, PROT_READ, MAP_SHARED, mmapHandle->fd, 0); */
85 mmapHandle->ptr = mmap(0, mmapHandle->size, PROT_READ, MAP_SHARED, mmapHandle->fd, 0);
87 if (mmapHandle->ptr == (void *)-1) {
88 debug_error(DEBUG, "error: mmap\n");
89 mmapHandle->ptr = NULL;
93 handle->privateData = (void *) mmapHandle;
95 return MMFILE_UTIL_SUCCESS;
98 if (mmapHandle->ptr) {
99 munmap(mmapHandle->ptr, mmapHandle->size);
102 if (mmapHandle->fd > 2) {
103 close(mmapHandle->fd);
106 mmfile_free(mmapHandle);
107 handle->privateData = NULL;
109 return MMFILE_UTIL_FAIL;
112 static int mmf_mmap_read(MMFileIOHandle *h, unsigned char *buf, int size)
114 MMFMMapIOHandle *mmapHandle = NULL;
115 const unsigned char *c = NULL;
118 if (!h || !h->privateData || !buf || size <= 0) {
119 debug_error(DEBUG, "invalid para\n");
120 return MMFILE_UTIL_FAIL;
123 mmapHandle = h->privateData;
125 c = mmapHandle->ptr + mmapHandle->offset;
127 if (mmapHandle->state != EOF) {
129 if (len + mmapHandle->offset > mmapHandle->size) {
130 len = mmapHandle->size - mmapHandle->offset;
138 mmapHandle->offset += len;
140 if (mmapHandle->offset == mmapHandle->size) {
141 mmapHandle->state = EOF;
147 static int mmf_mmap_write(MMFileIOHandle *h, unsigned char *buf, int size)
149 MMFMMapIOHandle *mmapHandle = NULL;
150 unsigned char *c = NULL;
153 if (!h || !h->privateData || !buf) {
154 debug_error(DEBUG, "invalid para\n");
155 return MMFILE_UTIL_FAIL;
158 mmapHandle = h->privateData;
160 c = mmapHandle->ptr + mmapHandle->offset;
162 if (mmapHandle->state != EOF) {
164 if (len + mmapHandle->offset > mmapHandle->size) {
165 len = mmapHandle->size - mmapHandle->offset;
173 mmapHandle->offset += len;
175 if (mmapHandle->offset == mmapHandle->size) {
176 mmapHandle->state = EOF;
183 static int64_t mmf_mmap_seek(MMFileIOHandle *h, int64_t pos, int whence)
185 MMFMMapIOHandle *mmapHandle = NULL;
188 if (!h || !h->privateData) {
189 debug_error(DEBUG, "invalid para\n");
190 return MMFILE_UTIL_FAIL;
193 mmapHandle = h->privateData;
197 tmp_offset = 0 + pos;
200 tmp_offset = mmapHandle->offset + pos;
203 tmp_offset = mmapHandle->size + pos;
206 return MMFILE_UTIL_FAIL;
210 if (tmp_offset < 0) {
211 debug_error(DEBUG, "invalid file offset\n");
212 return MMFILE_UTIL_FAIL;
216 mmapHandle->state = (tmp_offset >= mmapHandle->size) ? EOF : !EOF;
217 mmapHandle->offset = tmp_offset;
219 return mmapHandle->offset;
223 static long long mmf_mmap_tell(MMFileIOHandle *h)
225 MMFMMapIOHandle *mmapHandle = NULL;
227 if (!h || !h->privateData) {
228 debug_error(DEBUG, "invalid para\n");
229 return MMFILE_UTIL_FAIL;
232 mmapHandle = h->privateData;
234 return mmapHandle->offset;
237 static int mmf_mmap_close(MMFileIOHandle *h)
239 MMFMMapIOHandle *mmapHandle = NULL;
241 if (!h || !h->privateData) {
242 debug_error(DEBUG, "invalid para\n");
243 return MMFILE_UTIL_FAIL;
246 mmapHandle = h->privateData;
249 if (mmapHandle->ptr) {
250 munmap(mmapHandle->ptr, mmapHandle->size);
253 if (mmapHandle->fd > 2) {
254 close(mmapHandle->fd);
257 mmfile_free(mmapHandle);
260 h->privateData = NULL;
262 return MMFILE_UTIL_SUCCESS;
266 MMFileIOFunc mmfile_mmap_io_handler = {