/[tivodecode]/t2sami/trunk/happyfile.c
ViewVC logotype

Contents of /t2sami/trunk/happyfile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 198 - (show annotations) (download)
Sun Apr 1 04:46:08 2007 UTC (15 years, 4 months ago) by jeremyd2019
File MIME type: text/plain
File size: 3583 byte(s)
merge autoconf branch back to head.  AUTOCONF_CONVERSION_BRANCH is now closed

1 /*
2 * tivodecode, (c) 2006, Jeremy Drake
3 * See COPYING file for license terms
4 */
5 #ifdef HAVE_CONFIG_H
6 # include "config.h"
7 #endif
8 #include <errno.h>
9 #include <stdio.h>
10 #ifdef HAVE_MEMORY_H
11 # include <memory.h>
12 #endif
13 #ifdef HAVE_UNISTD_H
14 # include <unistd.h>
15 #endif
16 #ifdef WIN32
17 # include <io.h>
18 #endif
19 #include "fseeko.h"
20 #include "happyfile.h"
21
22 #if defined HAVE_FSEEKO
23 # define hftell(a) ftello(a)
24 # define hfseek(a, b, c) fseeko(a, b, c)
25 #else
26 # define hftell(a) ftell(a)
27 # define hfseek(a, b, c) fseek(a, b, c)
28 # warning Large file support is questionable on this platform
29 #endif
30
31 happy_file * hopen (const char * filename, const char * mode)
32 {
33 happy_file * fh = malloc (sizeof (happy_file));
34 fh->fh = fopen (filename, mode);
35 if (!fh->fh)
36 {
37 free (fh);
38 return NULL;
39 }
40 fh->pos = 0;
41 fh->buffer_start = 0;
42 fh->buffer_fill = 0;
43 return fh;
44 }
45
46 happy_file * hattach (FILE * fh)
47 {
48 happy_file * hfh = malloc (sizeof (happy_file));
49 hfh->fh = fh;
50 hfh->pos = 0;
51 hfh->buffer_start = 0;
52 hfh->buffer_fill = 0;
53 return hfh;
54 }
55
56 int hclose(happy_file * fh)
57 {
58 int x = fclose (fh->fh);
59 free (fh);
60 return x;
61 }
62
63 int hdetach(happy_file * fh)
64 {
65 free(fh);
66 return 0;
67 }
68
69 size_t hread (void * ptr, size_t size, happy_file * fh)
70 {
71 size_t nbytes = 0;
72
73 if (size == 0)
74 return 0;
75
76 if ((fh->pos + (hoff_t)size) - fh->buffer_start <= fh->buffer_fill)
77 {
78 memcpy (ptr, fh->buffer + (fh->pos - fh->buffer_start), size);
79 fh->pos += (hoff_t)size;
80 return size;
81 }
82 else if (fh->pos < fh->buffer_start + fh->buffer_fill)
83 {
84 memcpy (ptr, fh->buffer + (fh->pos - fh->buffer_start), (size_t)(fh->buffer_fill - (fh->pos - fh->buffer_start)));
85 nbytes += (size_t)(fh->buffer_fill - (fh->pos - fh->buffer_start));
86 }
87
88 do
89 {
90 fh->buffer_start += fh->buffer_fill;
91 fh->buffer_fill = (hoff_t)fread (fh->buffer, 1, BUFFERSIZE, fh->fh);
92
93 if (fh->buffer_fill == 0)
94 break;
95
96 memcpy((char *)ptr + nbytes, fh->buffer, ((hoff_t)(size - nbytes) < fh->buffer_fill ? (size - nbytes) : (size_t)fh->buffer_fill));
97 nbytes += ((hoff_t)(size - nbytes) < fh->buffer_fill ? (size - nbytes) : (size_t)fh->buffer_fill);
98 } while (nbytes < size);
99
100 fh->pos += (hoff_t)nbytes;
101 return nbytes;
102 }
103
104 hoff_t htell (happy_file * fh)
105 {
106 return fh->pos;
107 }
108
109 int hseek (happy_file * fh, hoff_t offset, int whence)
110 {
111 static char junk_buf[4096];
112
113 register int r;
114
115 switch (whence)
116 {
117 case SEEK_SET:
118 if (offset < fh->pos)
119 {
120 r = hfseek (fh->fh, offset, SEEK_SET);
121 if (r < 0)
122 return r;
123 fh->pos = offset;
124 fh->buffer_start = fh->pos;
125 fh->buffer_fill = 0;
126 return r;
127 }
128 else
129 {
130 int t = (int)((offset - fh->pos) & 0xfff);
131 hoff_t u = (offset - fh->pos) >> 12;
132 hoff_t s;
133 for (s=0; s < u; s++)
134 {
135 if (hread(junk_buf, 4096, fh) != 4096)
136 return -1;
137 }
138
139 if (hread(junk_buf, t, fh) != t)
140 {
141 return -1;
142 }
143
144 return 0;
145 }
146 break;
147 case SEEK_CUR:
148 if (offset < 0)
149 {
150 r = hfseek (fh->fh, offset, SEEK_CUR);
151 if (r < 0)
152 return r;
153 fh->pos += offset;
154 fh->buffer_start = fh->pos;
155 fh->buffer_fill = 0;
156 return r;
157 }
158 else
159 {
160 int t = (int)(offset & 0xfff);
161 hoff_t u = offset >> 12;
162 hoff_t s;
163 for (s=0; s < u; s++)
164 {
165 if (hread(junk_buf, 4096, fh) != 4096)
166 return -1;
167 }
168
169 if (hread(junk_buf, t, fh) != t)
170 {
171 return -1;
172 }
173
174 return 0;
175 }
176
177 break;
178 case SEEK_END:
179 r = hfseek (fh->fh, offset,whence);
180 fh->pos = hftell(fh->fh);
181 fh->buffer_start = fh->pos;
182 fh->buffer_fill = 0;
183 return r;
184 default:
185 errno=EINVAL;
186 return -1;
187 }
188 }

cvs@jdrake.com
ViewVC Help
Powered by ViewVC 1.1.13