File: big_buf_io_z.c

package info (click to toggle)
drawmap 1.7-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 472 kB
  • ctags: 396
  • sloc: ansic: 4,194; makefile: 61
file content (142 lines) | stat: -rw-r--r-- 3,682 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 * =========================================================================
 * big_buf_io_z - A library to allow efficient small reads and writes from gzipped files.
 * Copyright (c) 1997  Fred M. Erickson
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 * =========================================================================
 *
 *
 * Routines that let you do a lot of small reads from a gzip-compressed file,
 * without a lot of OS penalty.  Simply call buf_read_z() instead of read().
 * These routines read a file in large chunks and pass you the data in the
 * small chunks that you ask for.  Note some caveats:
 *
 *	You can't reset the file pointer with lseek() or you will
 *	mess up these routines.
 *
 *	You can only use these routines with one file at a time,
 *	since there is only one buffer to hold the data.
 *
 *      If you only have one file to read, you can simply open it
 *      and begin calling these routines.  If you have more than
 *      one file to read (consecutively, of course), you should use
 *      buf_open_z() to open the files, so that proper initialization
 *      gets done.  buf_close_z() has been added for completeness, but
 *      it doesn't do anything except call close().
 *
 * get_a_line_z() fills a buffer with information until it finds a newline,
 * or runs out of space.
 *
 * These routines depend on the zread() function, in the file gunzip.c
 */

#include <sys/types.h>
#include <fcntl.h>
#include "gzip.h"

int buf_open_z(const char *, int, mode_t, ...);
int buf_close_z(int);
ssize_t buf_read_z(int, void *, size_t);
ssize_t get_a_line_z(int, void *, size_t);

#define BUF_SIZE  WSIZE		/* This MUST be at least as large as WSIZE, or zread() won't work properly */
static r_place = 0;
static r_size = 0;
static w_place = 0;
static new_flag = 1;




int buf_open_z(const char *pathname, int flags, mode_t mode, ...)
{
	r_place = 0;
	r_size = 0;
	w_place = 0;
	new_flag = 1;

	if (flags & O_CREAT)  {
		return(open(pathname, flags, mode));
	}
	else  {
		return(open(pathname, flags));
	}
}




int
buf_close_z(int fdesc)
{
	return(close(fdesc));
}




ssize_t buf_read_z(int filedes, void *buf, size_t nbyte)
{
	static char bigbuf[BUF_SIZE];
	long amount;
	long tmp_nbyte;
	char *local_buf;

	local_buf = (char *)buf;

	tmp_nbyte = nbyte;

	while (tmp_nbyte > 0)  {
		if ((r_size <= 0) || (r_place == r_size))  {
			r_size = zread(filedes, bigbuf, BUF_SIZE, new_flag);
			if (r_size <= 0)  {
				return(r_size);
			}
			r_place = 0;
			new_flag = 0;
		}

		amount = (r_size - r_place) >= tmp_nbyte ? tmp_nbyte : r_size - r_place;
		memcpy(local_buf, &bigbuf[r_place], amount);
		local_buf = local_buf + amount;
		r_place = r_place + amount;
		tmp_nbyte = tmp_nbyte - amount;
	}

	return(nbyte);
}




ssize_t get_a_line_z(int filedes, void *buf, size_t nbyte)
{
	long i = 0;
	ssize_t ret_val;

	while (i < nbyte)  {
		ret_val = buf_read_z(filedes, buf + i, 1);
		if (ret_val != 1)  {
			return(i);
		}

		if (*((unsigned char *)buf + i) == '\n')  {
			return(i + 1);
		}

		i++;
	}
}