diff src/Input/console/abstract_file.cxx @ 0:13389e613d67 trunk

[svn] - initial import of audacious-plugins tree (lots to do)
author nenolod
date Mon, 18 Sep 2006 01:11:49 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/Input/console/abstract_file.cxx	Mon Sep 18 01:11:49 2006 -0700
@@ -0,0 +1,282 @@
+
+#include "abstract_file.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/* Copyright (C) 2005 Shay Green. Permission is hereby granted, free of
+charge, to any person obtaining a copy of this software module and associated
+documentation files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use, copy, modify,
+merge, publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to the
+following conditions: The above copyright notice and this permission notice
+shall be included in all copies or substantial portions of the Software. THE
+SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+// to do: remove?
+#ifndef RAISE_ERROR
+	#define RAISE_ERROR( str ) return str
+#endif
+
+typedef Data_Reader::error_t error_t;
+
+error_t Data_Writer::write( const void*, long ) { return NULL; }
+
+void Data_Writer::satisfy_lame_linker_() { }
+
+error_t Data_Reader::read( void* p, long s )
+{
+	long result = read_avail( p, s );
+	if ( result != s )
+	{
+		if ( result >= 0 && result < s )
+			RAISE_ERROR( "Unexpected end-of-file" );
+		
+		RAISE_ERROR( "Read error" );
+	}
+	
+	return NULL;
+}
+
+error_t Data_Reader::skip( long count )
+{
+	char buf [512];
+	while ( count )
+	{
+		int n = sizeof buf;
+		if ( n > count )
+			n = count;
+		count -= n;
+		RAISE_ERROR( read( buf, n ) );
+	}
+	return NULL;
+}
+
+long File_Reader::remain() const
+{
+	return size() - tell();
+}
+
+error_t File_Reader::skip( long n )
+{
+	assert( n >= 0 );
+	if ( n )
+		RAISE_ERROR( seek( tell() + n ) );
+	
+	return NULL;
+}
+
+
+// Subset_Reader
+
+Subset_Reader::Subset_Reader( Data_Reader* in_, long size ) :
+	in( in_ ),
+	remain_( in_->remain() )
+{
+	if ( remain_ > size )
+		remain_ = size;
+}
+
+long Subset_Reader::remain() const {
+	return remain_;
+}
+
+long Subset_Reader::read_avail( void* p, long s )
+{
+	if ( s > remain_ )
+		s = remain_;
+	remain_ -= s;
+	return in->read_avail( p, s );
+}
+
+// Mem_File_Reader
+
+Mem_File_Reader::Mem_File_Reader( const void* p, long s ) :
+	begin( (const char*) p ),
+	pos( 0 ),
+	size_( s )
+{
+}
+	
+long Mem_File_Reader::size() const {
+	return size_;
+}
+
+long Mem_File_Reader::read_avail( void* p, long s )
+{
+	long r = remain();
+	if ( s > r )
+		s = r;
+	memcpy( p, begin + pos, s );
+	pos += s;
+	return s;
+}
+
+long Mem_File_Reader::tell() const {
+	return pos;
+}
+
+error_t Mem_File_Reader::seek( long n )
+{
+	if ( n > size_ )
+		RAISE_ERROR( "Tried to go past end of file" );
+	pos = n;
+	return NULL;
+}
+
+// Std_File_Reader
+
+Std_File_Reader::Std_File_Reader() : file_( NULL ) {
+}
+
+Std_File_Reader::~Std_File_Reader() {
+	close();
+}
+
+error_t Std_File_Reader::open( const char* path )
+{
+	file_ = vfs_fopen( path, "rb" );
+	if ( !file_ )
+		RAISE_ERROR( "Couldn't open file" );
+	return NULL;
+}
+
+long Std_File_Reader::size() const
+{
+	long pos = tell();
+	vfs_fseek( file_, 0, SEEK_END );
+	long result = tell();
+	vfs_fseek( file_, pos, SEEK_SET );
+	return result;
+}
+
+long Std_File_Reader::read_avail( void* p, long s ) {
+	return (long) vfs_fread( p, 1, s, file_ );
+}
+
+long Std_File_Reader::tell() const {
+	return vfs_ftell( file_ );
+}
+
+error_t Std_File_Reader::seek( long n )
+{
+	if ( vfs_fseek( file_, n, SEEK_SET ) != 0 )
+		RAISE_ERROR( "Error seeking in file" );
+	return NULL;
+}
+
+void Std_File_Reader::close()
+{
+	if ( file_ ) {
+		vfs_fclose( file_ );
+		file_ = NULL;
+	}
+}
+
+// Std_File_Writer
+
+Std_File_Writer::Std_File_Writer() : file_( NULL ) {
+}
+
+Std_File_Writer::~Std_File_Writer() {
+	close();
+}
+
+error_t Std_File_Writer::open( const char* path )
+{
+	file_ = vfs_fopen( path, "wb" );
+	if ( !file_ )
+		RAISE_ERROR( "Couldn't open file for writing" );
+		
+	// to do: increase file buffer size
+	//setvbuf( file_, NULL, _IOFBF, 32 * 1024L );
+	
+	return NULL;
+}
+
+error_t Std_File_Writer::write( const void* p, long s )
+{
+	long result = (long) vfs_fwrite( p, 1, s, file_ );
+	if ( result != s )
+		RAISE_ERROR( "Couldn't write to file" );
+	return NULL;
+}
+
+void Std_File_Writer::close()
+{
+	if ( file_ ) {
+		vfs_fclose( file_ );
+		file_ = NULL;
+	}
+}
+
+// Mem_Writer
+
+Mem_Writer::Mem_Writer( void* p, long s, int b )
+{
+	data_ = (char*) p;
+	size_ = 0;
+	allocated = s;
+	mode = b ? ignore_excess : fixed;
+}
+
+Mem_Writer::Mem_Writer()
+{
+	data_ = NULL;
+	size_ = 0;
+	allocated = 0;
+	mode = expanding;
+}
+
+Mem_Writer::~Mem_Writer()
+{
+	if ( mode == expanding )
+		free( data_ );
+}
+
+error_t Mem_Writer::write( const void* p, long s )
+{
+	long remain = allocated - size_;
+	if ( s > remain )
+	{
+		if ( mode == fixed )
+			RAISE_ERROR( "Tried to write more data than expected" );
+		
+		if ( mode == ignore_excess )
+		{
+			s = remain;
+		}
+		else // expanding
+		{
+			long new_allocated = size_ + s;
+			new_allocated += (new_allocated >> 1) + 2048;
+			void* p = realloc( data_, new_allocated );
+			if ( !p )
+				RAISE_ERROR( "Out of memory" );
+			data_ = (char*) p;
+			allocated = new_allocated;
+		}
+	}
+	
+	assert( size_ + s <= allocated );
+	memcpy( data_ + size_, p, s );
+	size_ += s;
+	
+	return NULL;
+}
+
+// Null_Writer
+
+error_t Null_Writer::write( const void*, long )
+{
+	return NULL;
+}
+