1 /* $Id: pushback.c,v 1.1.1.1 2006/04/17 18:44:35 tromey Exp $
2 
3    $Log: pushback.c,v $
4    Revision 1.1.1.1  2006/04/17 18:44:35  tromey
5    Imported fastjar
6 
7    Revision 1.2  2000/12/14 18:45:35  ghazi
8    Warning fixes:
9 
10    	* compress.c: Include stdlib.h and compress.h.
11    	(rcsid): Delete.
12    	(report_str_error): Make static.
13    	(ez_inflate_str): Delete unused variable.  Add parens in if-stmt.
14    	(hrd_inflate_str): Likewise.
15 
16    	* compress.h (init_compression, end_compression, init_inflation,
17    	end_inflation): Prototype void arguments.
18 
19    	* dostime.c (rcsid): Delete.
20 
21    	* jargrep.c: Include ctype.h, stdlib.h, zlib.h and compress.h.
22    	Make functions static.  Cast ctype function argument to `unsigned
23    	char'.  Add parens in if-stmts.  Constify.
24    	(Usage): Change into a macro.
25    	(jargrep): Remove unused parameter.
26 
27    	* jartool.c: Constify.  Add parens in if-stmts.  Align
28    	signed/unsigned char pointers in functions calls using casts.
29    	(rcsid): Delete.
30    	(list_jar): Fix printf format specifier.
31    	(usage): Chop long string into bits.  Reformat.
32 
33    	* pushback.c (rcsid): Delete.
34 
35    Revision 1.1  2000/12/09 03:08:23  apbianco
36    2000-12-08  Alexandre Petit-Bianco  <apbianco@cygnus.com>
37 
38            * fastjar: Imported.
39 
40    Revision 1.2  2000/08/23 19:42:17  cory
41    Added support for more Unix platforms.  The following code has been hacked
42    to work on AIX, Solaris, True 64, and HP-UX.
43    Added bigendian check.  Probably works on most big and little endian platforms
44    now.
45 
46    Revision 1.1.1.1  1999/12/06 03:09:13  toast
47    initial checkin..
48 
49 
50 
51    Revision 1.1  1999/05/10 08:32:37  burnsbr
52    Initial revision
53 
54 */
55 
56 /*
57   pushback.c - code for a pushback buffer to handle file I/O
58   Copyright (C) 1999  Bryan Burns
59 
60   This program is free software; you can redistribute it and/or
61   modify it under the terms of the GNU General Public License
62   as published by the Free Software Foundation; either version 2
63   of the License, or (at your option) any later version.
64 
65   This program is distributed in the hope that it will be useful,
66   but WITHOUT ANY WARRANTY; without even the implied warranty of
67   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
68   GNU General Public License for more details.
69 
70   You should have received a copy of the GNU General Public License
71   along with this program; if not, write to the Free Software
72   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
73  */
74 
75 #include <unistd.h>
76 #include <string.h>
77 #include <stdio.h>
78 
79 #include "jartool.h"
80 #include "pushback.h"
81 
pb_init(pb_file * pbf,int fd)82 void pb_init(pb_file *pbf, int fd){
83   pbf->fd = fd;
84   pbf->next = pbf->pb_buff;
85   pbf->buff_amt = 0;
86 }
87 
pb_push(pb_file * pbf,void * buff,int amt)88 int pb_push(pb_file *pbf, void *buff, int amt){
89   int in_amt;
90   int wrap = 0;
91 
92 #ifdef DEBUG
93   printf("%d bytes being pushed back to the buffer\n", amt);
94 #endif
95 
96   /* determine how much we can take */
97   if((int)(RDSZ - pbf->buff_amt) < amt)
98     in_amt = RDSZ - pbf->buff_amt;
99   else
100     in_amt = amt;
101 
102   if(in_amt == 0)
103     return 0;
104 
105   /* figure out if we need to wrap around, and if so, by how much */
106   if(((pbf->pb_buff + RDSZ) - pbf->next) < in_amt)
107     wrap = in_amt - ((pbf->pb_buff + RDSZ) - pbf->next);
108 
109   /* write everything up til the end of the buffer */
110   memcpy(pbf->next, buff, (in_amt - wrap));
111 
112   /* finish writing what's wrapped around */
113   memcpy(pbf->pb_buff, ((char *)buff + (in_amt - wrap)), wrap);
114 
115   /* update the buff_amt field */
116   pbf->buff_amt += in_amt;
117 
118 #ifdef DEBUG
119   printf("%d bytes we can't accept\n", (amt - in_amt));
120 #endif
121 
122   return in_amt;
123 }
124 
125 
pb_read(pb_file * pbf,void * buff,int amt)126 int pb_read(pb_file *pbf, void *buff, int amt){
127   int out_amt = 0;
128   int wrap = 0;
129   void *bp = buff;
130   int tmp;
131 
132 #ifdef DEBUG
133   printf("%d bytes requested from us\n", amt);
134 #endif
135   while(out_amt < amt){
136     /* if our push-back buffer contains some data */
137     if(pbf->buff_amt > 0){
138 
139 #ifdef DEBUG
140       printf("giving data from buffer\n");
141 #endif
142 
143       /* calculate how much we can actually give the caller */
144       if( (amt - out_amt) < (int)pbf->buff_amt )
145         tmp = (amt - out_amt);
146       else
147         tmp = pbf->buff_amt;
148 
149       /* Determine if we're going to need to wrap around the buffer */
150       if(tmp > ((pbf->pb_buff + RDSZ) - pbf->next))
151         wrap = tmp - ((pbf->pb_buff + RDSZ) - pbf->next);
152 
153       memcpy(bp, pbf->next, (tmp - wrap));
154       bp = &(((char *)bp)[tmp - wrap]);
155 
156       /* If we need to wrap, read from the start of the buffer */
157       if(wrap > 0){
158         memcpy(bp, pbf->pb_buff, wrap);
159         bp = &(((char *)bp)[wrap]);
160       }
161 
162       /* update the buff_amt field */
163       pbf->buff_amt -= tmp;
164       pbf->next += tmp;
165 
166 #ifdef DEBUG
167       printf("%d bytes remaining in buffer\n", pbf->buff_amt);
168 #endif
169 
170       /* if the buffer is empty, reset the next header to the front of the
171          buffer so subsequent pushbacks/reads won't have to wrap */
172       if(pbf->buff_amt == 0)
173         pbf->next = pbf->pb_buff;
174 
175       out_amt += tmp;
176 
177     } else {
178 #ifdef DEBUG
179       printf("Reading from file..\n");
180 #endif
181 
182       /* The pushback buffer was empty, so we just need to read from the file */
183       tmp = read(pbf->fd, bp, (amt - out_amt));
184       if(tmp == 0)
185         break;
186       else
187         out_amt += tmp;
188 
189       bp = &(((char *)bp)[tmp]);
190     }
191   }
192 
193 #ifdef DEBUG
194   printf("managed to read %d bytes\n", out_amt);
195 #endif
196   return out_amt;
197 }
198