 7e2fe3a9fc
			
		
	
	7e2fe3a9fc
	
	
	
		
			
			All previous users of buffer_read_string have already been converted to use the more intuitive buffer_read_binary, so remove the old API to avoid some confusion. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
		
			
				
	
	
		
			131 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Licensed under a two-clause BSD-style license.
 | |
|  * See LICENSE for details.
 | |
|  */
 | |
| 
 | |
| #include "git-compat-util.h"
 | |
| #include "line_buffer.h"
 | |
| #include "strbuf.h"
 | |
| 
 | |
| #define COPY_BUFFER_LEN 4096
 | |
| 
 | |
| int buffer_init(struct line_buffer *buf, const char *filename)
 | |
| {
 | |
| 	buf->infile = filename ? fopen(filename, "r") : stdin;
 | |
| 	if (!buf->infile)
 | |
| 		return -1;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int buffer_fdinit(struct line_buffer *buf, int fd)
 | |
| {
 | |
| 	buf->infile = fdopen(fd, "r");
 | |
| 	if (!buf->infile)
 | |
| 		return -1;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int buffer_tmpfile_init(struct line_buffer *buf)
 | |
| {
 | |
| 	buf->infile = tmpfile();
 | |
| 	if (!buf->infile)
 | |
| 		return -1;
 | |
| 	return 0;
 | |
| }
 | |
| 
 | |
| int buffer_deinit(struct line_buffer *buf)
 | |
| {
 | |
| 	int err;
 | |
| 	if (buf->infile == stdin)
 | |
| 		return ferror(buf->infile);
 | |
| 	err = ferror(buf->infile);
 | |
| 	err |= fclose(buf->infile);
 | |
| 	return err;
 | |
| }
 | |
| 
 | |
| FILE *buffer_tmpfile_rewind(struct line_buffer *buf)
 | |
| {
 | |
| 	rewind(buf->infile);
 | |
| 	return buf->infile;
 | |
| }
 | |
| 
 | |
| long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
 | |
| {
 | |
| 	long pos = ftell(buf->infile);
 | |
| 	if (pos < 0)
 | |
| 		return error("ftell error: %s", strerror(errno));
 | |
| 	if (fseek(buf->infile, 0, SEEK_SET))
 | |
| 		return error("seek error: %s", strerror(errno));
 | |
| 	return pos;
 | |
| }
 | |
| 
 | |
| int buffer_ferror(struct line_buffer *buf)
 | |
| {
 | |
| 	return ferror(buf->infile);
 | |
| }
 | |
| 
 | |
| int buffer_read_char(struct line_buffer *buf)
 | |
| {
 | |
| 	return fgetc(buf->infile);
 | |
| }
 | |
| 
 | |
| /* Read a line without trailing newline. */
 | |
| char *buffer_read_line(struct line_buffer *buf)
 | |
| {
 | |
| 	char *end;
 | |
| 	if (!fgets(buf->line_buffer, sizeof(buf->line_buffer), buf->infile))
 | |
| 		/* Error or data exhausted. */
 | |
| 		return NULL;
 | |
| 	end = buf->line_buffer + strlen(buf->line_buffer);
 | |
| 	if (end[-1] == '\n')
 | |
| 		end[-1] = '\0';
 | |
| 	else if (feof(buf->infile))
 | |
| 		; /* No newline at end of file.  That's fine. */
 | |
| 	else
 | |
| 		/*
 | |
| 		 * Line was too long.
 | |
| 		 * There is probably a saner way to deal with this,
 | |
| 		 * but for now let's return an error.
 | |
| 		 */
 | |
| 		return NULL;
 | |
| 	return buf->line_buffer;
 | |
| }
 | |
| 
 | |
| void buffer_read_binary(struct line_buffer *buf,
 | |
| 				struct strbuf *sb, uint32_t size)
 | |
| {
 | |
| 	strbuf_fread(sb, size, buf->infile);
 | |
| }
 | |
| 
 | |
| off_t buffer_copy_bytes(struct line_buffer *buf, off_t nbytes)
 | |
| {
 | |
| 	char byte_buffer[COPY_BUFFER_LEN];
 | |
| 	off_t done = 0;
 | |
| 	while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
 | |
| 		off_t len = nbytes - done;
 | |
| 		size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
 | |
| 		in = fread(byte_buffer, 1, in, buf->infile);
 | |
| 		done += in;
 | |
| 		fwrite(byte_buffer, 1, in, stdout);
 | |
| 		if (ferror(stdout))
 | |
| 			return done + buffer_skip_bytes(buf, nbytes - done);
 | |
| 	}
 | |
| 	return done;
 | |
| }
 | |
| 
 | |
| off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes)
 | |
| {
 | |
| 	char byte_buffer[COPY_BUFFER_LEN];
 | |
| 	off_t done = 0;
 | |
| 	while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
 | |
| 		off_t len = nbytes - done;
 | |
| 		size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
 | |
| 		done += fread(byte_buffer, 1, in, buf->infile);
 | |
| 	}
 | |
| 	return done;
 | |
| }
 | |
| 
 | |
| void buffer_reset(struct line_buffer *buf)
 | |
| {
 | |
| }
 |