/[pkg-grass]/packages/drawmap/trunk/big_buf_io.c
ViewVC logotype

Contents of /packages/drawmap/trunk/big_buf_io.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 836 - (show annotations) (download)
Fri May 18 12:29:08 2007 UTC (6 years ago) by frankie
File MIME type: text/plain
File size: 4502 byte(s)
[svn-inject] Forking drawmap source to Trunk
1 /*
2 * =========================================================================
3 * big_buf_io - A library to allow efficient small reads and writes.
4 * Copyright (c) 1997,2001 Fred M. Erickson
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * =========================================================================
20 *
21 *
22 * Routines that let you do a lot of small reads and writes from a file,
23 * without a lot of OS penalty. Simply call buf_read() and buf_write()
24 * instead of read() and write(). These routines read/write a file in
25 * large chunks and pass you the data in the small chunks that you ask
26 * for. Note some caveats:
27 *
28 * You must call buf_write(filedes, buf, 0) when you are done
29 * writing so that it can flush the write buffer.
30 * (Should maybe implement buf_flush() to take care of this.)
31 *
32 * You can't reset the file pointer with lseek() or you will
33 * mess up these routines.
34 *
35 * You can only use these routines with one file at a time,
36 * since there is only one buffer to hold the data.
37 *
38 * If you only have one file to read, you can simply open it
39 * and begin calling these routines. If you have more than
40 * one file to read (consecutively, of course), you should use
41 * buf_open() to open the files, so that proper initialization
42 * gets done. buf_close() has been added for completeness, but
43 * it doesn't do anything except call close().
44 *
45 * get_a_line() fills a buffer with information until it finds a newline,
46 * or runs out of space.
47 */
48
49 #include <sys/types.h>
50 #include <fcntl.h>
51
52 int buf_open(const char *, int, mode_t, ...);
53 int buf_close(int);
54 ssize_t buf_read(int, void *, size_t);
55 ssize_t buf_write(int, const void *, size_t);
56 ssize_t get_a_line(int, void *, size_t);
57
58 #define BUF_SIZE 16384
59 static r_place = 0;
60 static r_size = 0;
61 static w_place = 0;
62
63
64
65
66 int
67 buf_open(const char *pathname, int flags, mode_t mode, ...)
68 {
69 r_place = 0;
70 r_size = 0;
71 w_place = 0;
72
73 if (flags & O_CREAT) {
74 return(open(pathname, flags, mode));
75 }
76 else {
77 return(open(pathname, flags));
78 }
79 }
80
81
82
83
84 int
85 buf_close(int fdesc)
86 {
87 return(close(fdesc));
88 }
89
90
91
92
93 ssize_t
94 buf_read(int filedes, void *buf, size_t nbyte)
95 {
96 static char bigbuf[BUF_SIZE];
97 long amount;
98 long tmp_nbyte;
99 char *local_buf;
100
101 local_buf = (char *)buf;
102
103 tmp_nbyte = nbyte;
104
105 while (tmp_nbyte > 0) {
106 if ((r_size <= 0) || (r_place == r_size)) {
107 r_size = read(filedes, bigbuf, BUF_SIZE);
108 if (r_size <= 0) {
109 return(r_size);
110 }
111 r_place = 0;
112 }
113
114 amount = (r_size - r_place) >= tmp_nbyte ? tmp_nbyte : r_size - r_place;
115 memcpy(local_buf, &bigbuf[r_place], amount);
116 local_buf = local_buf + amount;
117 r_place = r_place + amount;
118 tmp_nbyte = tmp_nbyte - amount;
119 }
120
121 return(nbyte);
122 }
123
124
125
126 ssize_t
127 buf_write(int filedes, const void *buf, size_t nbyte)
128 {
129 static char bigbuf[BUF_SIZE];
130 long amount;
131 long tmp_nbyte;
132 long ret_val;
133 char *local_buf;
134
135 local_buf = (char *)buf;
136
137 if (nbyte == 0) {
138 ret_val = write(filedes, bigbuf, w_place);
139 if (ret_val < 0) {
140 return(ret_val);
141 }
142 else {
143 return(0);
144 }
145 }
146
147 tmp_nbyte = nbyte;
148
149 while (tmp_nbyte > 0) {
150 amount = (BUF_SIZE - w_place) >= tmp_nbyte ? tmp_nbyte : BUF_SIZE - w_place;
151 memcpy(&bigbuf[w_place], local_buf, amount);
152 local_buf = local_buf + amount;
153 w_place = w_place + amount;
154 tmp_nbyte = tmp_nbyte - amount;
155
156 if (w_place == BUF_SIZE) {
157 if (write(filedes, bigbuf, BUF_SIZE) != BUF_SIZE) {
158 return(-1);
159 }
160 w_place = 0;
161 }
162 }
163
164 return(nbyte);
165 }
166
167
168
169
170
171 ssize_t
172 get_a_line(int filedes, void *buf, size_t nbyte)
173 {
174 long i = 0;
175 ssize_t ret_val;
176
177 while (i < nbyte) {
178 ret_val = buf_read(filedes, buf + i, 1);
179 if (ret_val < 0) {
180 return(ret_val);
181 }
182 else if (ret_val == 0) {
183 return((ssize_t)i);
184 }
185
186 if (*((unsigned char *)buf + i) == '\n') {
187 return(i + 1);
188 }
189
190 i++;
191 }
192
193 return((ssize_t)nbyte);
194 }

  ViewVC Help
Powered by ViewVC 1.1.5