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