io/FileDescriptor: add method FullRead()
This commit is contained in:
		
				
					committed by
					
						
						Max Kellermann
					
				
			
			
				
	
			
			
			
						parent
						
							bd4df1ae5d
						
					
				
				
					commit
					a72878c5b9
				
			@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2012-2018 Max Kellermann <max.kellermann@gmail.com>
 | 
			
		||||
 * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
@@ -28,8 +28,10 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "FileDescriptor.hxx"
 | 
			
		||||
#include "system/Error.hxx"
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
@@ -285,6 +287,24 @@ FileDescriptor::GetSize() const noexcept
 | 
			
		||||
		: -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
FileDescriptor::FullRead(void *_buffer, size_t length)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t *buffer = (uint8_t *)_buffer;
 | 
			
		||||
 | 
			
		||||
	while (length > 0) {
 | 
			
		||||
		ssize_t nbytes = Read(buffer, length);
 | 
			
		||||
		if (nbytes <= 0) {
 | 
			
		||||
			if (nbytes < 0)
 | 
			
		||||
				throw MakeErrno("Failed to read");
 | 
			
		||||
			throw std::runtime_error("Unexpected end of file");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		buffer += nbytes;
 | 
			
		||||
		length -= nbytes;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2012-2018 Max Kellermann <max.kellermann@gmail.com>
 | 
			
		||||
 * Copyright 2012-2019 Max Kellermann <max.kellermann@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
@@ -233,6 +233,12 @@ public:
 | 
			
		||||
		return ::read(fd, buffer, length);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Read until all of the given buffer has been filled.  Throws
 | 
			
		||||
	 * on error.
 | 
			
		||||
	 */
 | 
			
		||||
	void FullRead(void *buffer, size_t length);
 | 
			
		||||
 | 
			
		||||
	ssize_t Write(const void *buffer, size_t length) noexcept {
 | 
			
		||||
		return ::write(fd, buffer, length);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -79,21 +79,6 @@ WriteOrThrow(FileDescriptor fd, const void *buffer, size_t size)
 | 
			
		||||
	return nbytes;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
FullRead(FileDescriptor fd, void *_buffer, size_t size)
 | 
			
		||||
{
 | 
			
		||||
	auto buffer = (uint8_t *)_buffer;
 | 
			
		||||
 | 
			
		||||
	while (size > 0) {
 | 
			
		||||
		size_t nbytes = ReadOrThrow(fd, buffer, size);
 | 
			
		||||
		if (nbytes == 0)
 | 
			
		||||
			throw std::runtime_error("Premature end of input");
 | 
			
		||||
 | 
			
		||||
		buffer += nbytes;
 | 
			
		||||
		size -= nbytes;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
FullWrite(FileDescriptor fd, ConstBuffer<uint8_t> src)
 | 
			
		||||
{
 | 
			
		||||
@@ -124,7 +109,7 @@ ReadFrames(FileDescriptor fd, void *_buffer, size_t size, size_t frame_size)
 | 
			
		||||
	const size_t modulo = nbytes % frame_size;
 | 
			
		||||
	if (modulo > 0) {
 | 
			
		||||
		size_t rest = frame_size - modulo;
 | 
			
		||||
		FullRead(fd, buffer + nbytes, rest);
 | 
			
		||||
		fd.FullRead(buffer + nbytes, rest);
 | 
			
		||||
		nbytes += rest;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user