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