/[rvvs89]/uvm/core/finput.c


UCC Code Repository

Contents of /uvm/core/finput.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 355 - (show annotations) (download)
Mon Mar 1 08:05:23 2010 UTC (11 years, 9 months ago) by rvvs89
File MIME type: text/plain
File size: 5762 byte(s)
Syncing to work on netbook.
1 /*
2 * File: finput.h
3 * Author: rvvs89
4 *
5 * $Id$
6 * Created on 20 February 2010, 8:35 PM
7 */
8
9 #include <stddef.h>
10 #include <stdlib.h>
11 #include "finput.h"
12 #include "uvm.h"
13
14 #define UVM_EOF (0x1)
15 #define UVM_EIO (0x2)
16
17 #define BUFFER_BITS (9)
18 #define BUFFER_SIZE (1 << BUFFER_BITS)
19 #define BUFFER_MASK (BUFFER_SIZE - 1)
20
21 #define MIN(a, b) ((a) < (b) ? (a) : (b))
22
23 struct finput {
24 struct binput iface;
25 FILE *file;
26 ptrdiff_t off;
27 size_t rem;
28 int flags;
29 unsigned char buf[BUFFER_SIZE];
30 };
31
32 static int finput_buffer(struct finput *in) {
33 ptrdiff_t off;
34 size_t length;
35 size_t nread;
36
37 off = (in->off + in->rem) & BUFFER_MASK;
38 length = off < in->off ? in->off - off : sizeof in->buf - off;
39 nread = fread(in->buf + off, 1, length, in->file);
40 in->rem += nread;
41 printf("Rebuffered %zd bytes\n", nread);
42 if (nread < length) {
43 if (feof(in->file)) {
44 in->flags |= UVM_EOF;
45 } else if (ferror(in->file)) {
46 in->flags |= UVM_EIO;
47 return UVME_EIO;
48 }
49 } else if (in->rem < sizeof in->buf) {
50 return finput_buffer(in);
51 }
52 return 0;
53 }
54
55 static int finput_read1(struct binput *in, uint8_t *out) {
56 int status;
57 struct finput *fin;
58
59 fin = (struct finput *) in;
60 if (fin->rem < 1) {
61 if (fin->flags & UVM_EIO)
62 return UVME_EIO;
63 if (fin->flags & UVM_EOF)
64 return UVME_EOF;
65 if (status = finput_buffer(fin))
66 return status;
67 }
68 *out = fin->buf[fin->off];
69 fin->off = (fin->off + 1) & BUFFER_MASK;
70 fin->rem--;
71 return 0;
72 }
73
74 static int finput_read2(struct binput *in, uint16_t *out) {
75 int status;
76 struct finput *fin;
77 uint_fast16_t tmp;
78
79 fin = (struct finput *) in;
80 if (fin->rem < 2) {
81 if (fin->flags & UVM_EIO)
82 return UVME_EIO;
83 if (fin->flags & UVM_EOF)
84 return UVME_EOF;
85 if (status = finput_buffer(fin))
86 return status;
87 if (fin->rem < 2)
88 return UVME_EOF;
89 }
90 tmp = (uint_fast16_t) fin->buf[fin->off] << 010;
91 fin->off = (fin->off + 1) & BUFFER_MASK;
92 tmp |= fin->buf[fin->off];
93 fin->off = (fin->off + 1) & BUFFER_MASK;
94 fin->rem -= 2;
95 *out = tmp;
96 return 0;
97 }
98
99 static int finput_read4(struct binput *in, uint32_t *out) {
100 int status;
101 struct finput *fin;
102 uint_fast32_t tmp;
103
104 fin = (struct finput *) in;
105 if (fin->rem < 4) {
106 if (fin->flags & UVM_EIO)
107 return UVME_EIO;
108 if (fin->flags & UVM_EOF)
109 return UVME_EOF;
110 if (status = finput_buffer(fin))
111 return status;
112 if (fin->rem < 4)
113 return UVME_EOF;
114 }
115 tmp = (uint_fast32_t) fin->buf[fin->off] << 030;
116 fin->off = (fin->off + 1) & BUFFER_MASK;
117 tmp |= (uint_fast32_t) fin->buf[fin->off] << 020;
118 fin->off = (fin->off + 1) & BUFFER_MASK;
119 tmp |= (uint_fast16_t) fin->buf[fin->off] << 010;
120 fin->off = (fin->off + 1) & BUFFER_MASK;
121 tmp |= fin->buf[fin->off];
122 fin->off = (fin->off + 1) & BUFFER_MASK;
123 *out = tmp;
124 fin->rem -= 4;
125 return 0;
126 }
127
128 static int finput_read8(struct binput *in, uint64_t *out) {
129 int status;
130 struct finput *fin;
131 uint_fast64_t tmp;
132
133 fin = (struct finput *) in;
134 if (fin->rem < 8) {
135 if (fin->flags & UVM_EIO)
136 return UVME_EIO;
137 if (fin->flags & UVM_EOF)
138 return UVME_EOF;
139 if (status = finput_buffer(fin))
140 return status;
141 if (fin->rem < 8)
142 return UVME_EOF;
143 }
144 tmp = (uint_fast64_t) fin->buf[fin->off] << 070;
145 fin->off = (fin->off + 1) & BUFFER_MASK;
146 tmp |= (uint_fast64_t) fin->buf[fin->off] << 060;
147 fin->off = (fin->off + 1) & BUFFER_MASK;
148 tmp |= (uint_fast64_t) fin->buf[fin->off] << 050;
149 fin->off = (fin->off + 1) & BUFFER_MASK;
150 tmp |= (uint_fast64_t) fin->buf[fin->off] << 040;
151 fin->off = (fin->off + 1) & BUFFER_MASK;
152 tmp |= (uint_fast32_t) fin->buf[fin->off] << 030;
153 fin->off = (fin->off + 1) & BUFFER_MASK;
154 tmp |= (uint_fast32_t) fin->buf[fin->off] << 020;
155 fin->off = (fin->off + 1) & BUFFER_MASK;
156 tmp |= (uint_fast16_t) fin->buf[fin->off] << 010;
157 fin->off = (fin->off + 1) & BUFFER_MASK;
158 tmp |= fin->buf[fin->off];
159 fin->off = (fin->off + 1) & BUFFER_MASK;
160 *out = tmp;
161 fin->rem -= 8;
162 return 0;
163 }
164
165 int finput_skip(struct binput *in, size_t i) {
166 int status;
167 struct finput *fin;
168
169 fin = (struct finput *) in;
170 while (i) {
171 if (fin->rem) {
172 size_t cur;
173
174 cur = MIN(i, fin->rem);
175 fin->off = (fin->off + fin->rem) & BUFFER_MASK;
176 i -= fin->rem;
177 fin->rem = 0;
178 }
179 if (fin->flags & UVM_EIO)
180 return UVME_EIO;
181 if (fin->flags & UVM_EOF)
182 return UVME_EOF;
183 if (status = finput_buffer(fin))
184 return status;
185 }
186 return 0;
187 }
188
189 static int finput_close(struct binput *in) {
190 struct finput *fin;
191
192 fin = (struct finput *) in;
193 fin->rem = 0;
194 fin->flags |= UVM_EOF;
195 if (fclose(fin->file)) {
196 free(in);
197 return UVME_EIO;
198 }
199 free(in);
200 return 0;
201 }
202
203 int finput_wrap(FILE *stream, struct binput **out) {
204 struct finput *ret;
205
206 #ifdef ENABLE_MALLOC
207 if (!(ret = malloc(sizeof *ret)))
208 return UVME_NOMEM;
209 ret->iface.read1 = &finput_read1;
210 ret->iface.read2 = &finput_read2;
211 ret->iface.read4 = &finput_read4;
212 ret->iface.read8 = &finput_read8;
213 ret->iface.skip = &finput_skip;
214 ret->iface.close = &finput_close;
215 ret->file = stream;
216 ret->off = 0;
217 ret->rem = 0;
218 ret->flags = 0;
219 *out = (struct binput *) ret;
220 return 0;
221 #else
222 return UVM_IMPL;
223 #endif
224 }

Properties

Name Value
svn:keywords Id

Managed by UCC Webmasters ViewVC Help
Powered by ViewVC 1.1.26