blob: d94c1a0a4389506153da51e339d2d784607fd6f8 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono9033e312005-11-21 02:08:39 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <pj/file_io.h>
21#include <pj/assert.h>
22#include <pj/errno.h>
23#include <stdio.h>
24#include <errno.h>
25
26PJ_DEF(pj_status_t) pj_file_open( pj_pool_t *pool,
27 const char *pathname,
28 unsigned flags,
29 pj_oshandle_t *fd)
30{
31 char mode[8];
32 char *p = mode;
33
34 PJ_ASSERT_RETURN(pathname && fd, PJ_EINVAL);
35 PJ_UNUSED_ARG(pool);
36
37 if ((flags & PJ_O_APPEND) == PJ_O_APPEND) {
38 if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY) {
39 *p++ = 'a';
40 if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY)
41 *p++ = '+';
42 } else {
43 /* This is invalid.
44 * Can not specify PJ_O_RDONLY with PJ_O_APPEND!
45 */
46 }
47 } else {
48 if ((flags & PJ_O_RDONLY) == PJ_O_RDONLY) {
49 *p++ = 'r';
50 if ((flags & PJ_O_WRONLY) == PJ_O_WRONLY)
51 *p++ = '+';
52 } else {
53 *p++ = 'w';
54 }
55 }
56
57 if (p==mode)
58 return PJ_EINVAL;
59
60 *p++ = 'b';
61 *p++ = '\0';
62
63 *fd = fopen(pathname, mode);
64 if (*fd == NULL)
65 return PJ_RETURN_OS_ERROR(errno);
66
67 return PJ_SUCCESS;
68}
69
70PJ_DEF(pj_status_t) pj_file_close(pj_oshandle_t fd)
71{
72 PJ_ASSERT_RETURN(fd, PJ_EINVAL);
73 if (fclose((FILE*)fd) != 0)
74 return PJ_RETURN_OS_ERROR(errno);
75
76 return PJ_SUCCESS;
77}
78
79PJ_DEF(pj_status_t) pj_file_write( pj_oshandle_t fd,
80 const void *data,
81 pj_ssize_t *size)
82{
83 size_t written;
84
85 clearerr((FILE*)fd);
86 written = fwrite(data, 1, *size, (FILE*)fd);
87 if (ferror((FILE*)fd)) {
88 *size = -1;
89 return PJ_RETURN_OS_ERROR(errno);
90 }
91
92 *size = written;
93 return PJ_SUCCESS;
94}
95
96PJ_DEF(pj_status_t) pj_file_read( pj_oshandle_t fd,
97 void *data,
98 pj_ssize_t *size)
99{
100 size_t bytes;
101
102 clearerr((FILE*)fd);
103 bytes = fread(data, 1, *size, (FILE*)fd);
104 if (ferror((FILE*)fd)) {
105 *size = -1;
106 return PJ_RETURN_OS_ERROR(errno);
107 }
108
109 *size = bytes;
110 return PJ_SUCCESS;
111}
112
Benny Prijono8ab968f2007-07-20 08:08:30 +0000113/*
Benny Prijono9033e312005-11-21 02:08:39 +0000114PJ_DEF(pj_bool_t) pj_file_eof(pj_oshandle_t fd, enum pj_file_access access)
115{
116 PJ_UNUSED_ARG(access);
117 return feof((FILE*)fd) ? PJ_TRUE : 0;
118}
Benny Prijono8ab968f2007-07-20 08:08:30 +0000119*/
Benny Prijono9033e312005-11-21 02:08:39 +0000120
121PJ_DEF(pj_status_t) pj_file_setpos( pj_oshandle_t fd,
122 pj_off_t offset,
123 enum pj_file_seek_type whence)
124{
125 int mode;
126
127 switch (whence) {
128 case PJ_SEEK_SET:
129 mode = SEEK_SET; break;
130 case PJ_SEEK_CUR:
131 mode = SEEK_CUR; break;
132 case PJ_SEEK_END:
133 mode = SEEK_END; break;
134 default:
135 pj_assert(!"Invalid whence in file_setpos");
136 return PJ_EINVAL;
137 }
138
139 if (fseek((FILE*)fd, (long)offset, mode) != 0)
140 return PJ_RETURN_OS_ERROR(errno);
141
142 return PJ_SUCCESS;
143}
144
145PJ_DEF(pj_status_t) pj_file_getpos( pj_oshandle_t fd,
146 pj_off_t *pos)
147{
148 long offset;
149
150 offset = ftell((FILE*)fd);
151 if (offset == -1) {
152 *pos = -1;
153 return PJ_RETURN_OS_ERROR(errno);
154 }
155
156 *pos = offset;
157 return PJ_SUCCESS;
158}
159
Benny Prijonoee738712007-03-16 09:25:47 +0000160PJ_DEF(pj_status_t) pj_file_flush(pj_oshandle_t fd)
161{
162 int rc;
Benny Prijono9033e312005-11-21 02:08:39 +0000163
Benny Prijonoee738712007-03-16 09:25:47 +0000164 rc = fflush((FILE*)fd);
165 if (rc == EOF) {
166 return PJ_RETURN_OS_ERROR(errno);
167 }
168
169 return PJ_SUCCESS;
170}