blob: dafa329d381da451afe65bc8428ddff5ce381d64 [file] [log] [blame]
Benny Prijono9033e312005-11-21 02:08:39 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
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
112PJ_DEF(pj_bool_t) pj_file_eof(pj_oshandle_t fd, enum pj_file_access access)
113{
114 PJ_UNUSED_ARG(access);
115 return feof((FILE*)fd) ? PJ_TRUE : 0;
116}
117
118PJ_DEF(pj_status_t) pj_file_setpos( pj_oshandle_t fd,
119 pj_off_t offset,
120 enum pj_file_seek_type whence)
121{
122 int mode;
123
124 switch (whence) {
125 case PJ_SEEK_SET:
126 mode = SEEK_SET; break;
127 case PJ_SEEK_CUR:
128 mode = SEEK_CUR; break;
129 case PJ_SEEK_END:
130 mode = SEEK_END; break;
131 default:
132 pj_assert(!"Invalid whence in file_setpos");
133 return PJ_EINVAL;
134 }
135
136 if (fseek((FILE*)fd, (long)offset, mode) != 0)
137 return PJ_RETURN_OS_ERROR(errno);
138
139 return PJ_SUCCESS;
140}
141
142PJ_DEF(pj_status_t) pj_file_getpos( pj_oshandle_t fd,
143 pj_off_t *pos)
144{
145 long offset;
146
147 offset = ftell((FILE*)fd);
148 if (offset == -1) {
149 *pos = -1;
150 return PJ_RETURN_OS_ERROR(errno);
151 }
152
153 *pos = offset;
154 return PJ_SUCCESS;
155}
156
157