blob: 7eb6f5c1ee4374040572a96169f4b50380548ce0 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* File object implementation */
2
Guido van Rossumdd5c7be1990-10-26 14:58:11 +00003/* XXX This should become a built-in module 'io'. It should support more
4 functionality, better exception handling for invalid calls, etc.
5 It should also cooperate with posix to support popen(), which should
6 share most code but have a special close function. */
7
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00008#include <stdio.h>
9
10#include "PROTO.h"
11#include "object.h"
12#include "stringobject.h"
13#include "intobject.h"
14#include "fileobject.h"
15#include "methodobject.h"
16#include "objimpl.h"
Guido van Rossum2b654f71990-10-14 20:03:32 +000017#include "errors.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000018
19typedef struct {
20 OB_HEAD
21 FILE *f_fp;
22 object *f_name;
23 object *f_mode;
24 /* XXX Should move the 'need space' on printing flag here */
25} fileobject;
26
27FILE *
28getfilefile(f)
29 object *f;
30{
31 if (!is_fileobject(f)) {
32 errno = EBADF;
33 return NULL;
34 }
35 return ((fileobject *)f)->f_fp;
36}
37
38object *
39newopenfileobject(fp, name, mode)
40 FILE *fp;
41 char *name;
42 char *mode;
43{
44 fileobject *f = NEWOBJ(fileobject, &Filetype);
45 if (f == NULL)
46 return NULL;
47 f->f_fp = NULL;
48 f->f_name = newstringobject(name);
49 f->f_mode = newstringobject(mode);
50 if (f->f_name == NULL || f->f_mode == NULL) {
51 DECREF(f);
52 errno = ENOMEM;
53 return NULL;
54 }
55 f->f_fp = fp;
56 return (object *) f;
57}
58
59object *
60newfileobject(name, mode)
61 char *name, *mode;
62{
63 fileobject *f;
64 FILE *fp;
65 f = (fileobject *) newopenfileobject((FILE *)NULL, name, mode);
66 if (f == NULL)
67 return NULL;
68 if ((f->f_fp = fopen(name, mode)) == NULL) {
69 DECREF(f);
70 return NULL;
71 }
72 return (object *)f;
73}
74
75/* Methods */
76
77static void
78filedealloc(f)
79 fileobject *f;
80{
81 if (f->f_fp != NULL)
82 fclose(f->f_fp);
83 if (f->f_name != NULL)
84 DECREF(f->f_name);
85 if (f->f_mode != NULL)
86 DECREF(f->f_mode);
87 free((char *)f);
88}
89
90static void
91fileprint(f, fp, flags)
92 fileobject *f;
93 FILE *fp;
94 int flags;
95{
96 fprintf(fp, "<%s file ", f->f_fp == NULL ? "closed" : "open");
97 printobject(f->f_name, fp, flags);
98 fprintf(fp, ", mode ");
99 printobject(f->f_mode, fp, flags);
100 fprintf(fp, ">");
101}
102
103static object *
104filerepr(f)
105 fileobject *f;
106{
107 char buf[300];
108 /* XXX This differs from fileprint if the filename contains
109 quotes or other funny characters. */
110 sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
111 f->f_fp == NULL ? "closed" : "open",
112 getstringvalue(f->f_name),
113 getstringvalue(f->f_mode));
114 return newstringobject(buf);
115}
116
117static object *
118fileclose(f, args)
119 fileobject *f;
120 object *args;
121{
122 if (args != NULL) {
123 errno = EINVAL;
124 return NULL;
125 }
126 if (f->f_fp != NULL) {
127 fclose(f->f_fp);
128 f->f_fp = NULL;
129 }
130 INCREF(None);
131 return None;
132}
133
134static object *
135fileread(f, args)
136 fileobject *f;
137 object *args;
138{
139 int n;
140 object *v;
141 if (f->f_fp == NULL) {
142 errno = EBADF;
143 return NULL;
144 }
145 if (args == NULL || !is_intobject(args)) {
146 errno = EINVAL;
147 return NULL;
148 }
149 n = getintvalue(args);
Guido van Rossumdd5c7be1990-10-26 14:58:11 +0000150 if (n < 0) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 errno = EDOM;
152 return NULL;
153 }
154 v = newsizedstringobject((char *)NULL, n);
155 if (v == NULL) {
156 errno = ENOMEM;
157 return NULL;
158 }
159 n = fread(getstringvalue(v), 1, n, f->f_fp);
160 /* EOF is reported as an empty string */
161 /* XXX should detect real I/O errors? */
162 resizestring(&v, n);
163 return v;
164}
165
166/* XXX Should this be unified with raw_input()? */
167
168static object *
169filereadline(f, args)
170 fileobject *f;
171 object *args;
172{
173 int n;
174 object *v;
175 if (f->f_fp == NULL) {
176 errno = EBADF;
177 return NULL;
178 }
179 if (args == NULL) {
180 n = 10000; /* XXX should really be unlimited */
181 }
182 else if (is_intobject(args)) {
183 n = getintvalue(args);
184 if (n < 0 || n > 0x7fff /*XXX*/ ) {
185 errno = EDOM;
186 return NULL;
187 }
188 }
189 else {
190 errno = EINVAL;
191 return NULL;
192 }
193 v = newsizedstringobject((char *)NULL, n);
194 if (v == NULL) {
195 errno = ENOMEM;
196 return NULL;
197 }
198 if (fgets(getstringvalue(v), n+1, f->f_fp) == NULL) {
199 /* EOF is reported as an empty string */
200 /* XXX should detect real I/O errors? */
201 n = 0;
202 }
203 else {
204 n = strlen(getstringvalue(v));
205 }
206 resizestring(&v, n);
207 return v;
208}
209
210static object *
211filewrite(f, args)
212 fileobject *f;
213 object *args;
214{
215 int n, n2;
216 if (f->f_fp == NULL) {
217 errno = EBADF;
218 return NULL;
219 }
220 if (args == NULL || !is_stringobject(args)) {
221 errno = EINVAL;
222 return NULL;
223 }
224 errno = 0;
225 n2 = fwrite(getstringvalue(args), 1, n = getstringsize(args), f->f_fp);
226 if (n2 != n) {
227 if (errno == 0)
228 errno = EIO;
229 return NULL;
230 }
231 INCREF(None);
232 return None;
233}
234
235static struct methodlist {
236 char *ml_name;
237 method ml_meth;
238} filemethods[] = {
239 {"write", filewrite},
240 {"read", fileread},
241 {"readline", filereadline},
242 {"close", fileclose},
243 {NULL, NULL} /* sentinel */
244};
245
246static object *
247filegetattr(f, name)
248 fileobject *f;
249 char *name;
250{
251 struct methodlist *ml = filemethods;
252 for (; ml->ml_name != NULL; ml++) {
253 if (strcmp(name, ml->ml_name) == 0)
254 return newmethodobject(ml->ml_name, ml->ml_meth,
255 (object *)f);
256 }
Guido van Rossum2b654f71990-10-14 20:03:32 +0000257 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000258 return NULL;
259}
260
261typeobject Filetype = {
262 OB_HEAD_INIT(&Typetype)
263 0,
264 "file",
265 sizeof(fileobject),
266 0,
267 filedealloc, /*tp_dealloc*/
268 fileprint, /*tp_print*/
269 filegetattr, /*tp_getattr*/
270 0, /*tp_setattr*/
271 0, /*tp_compare*/
272 filerepr, /*tp_repr*/
273};