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