File: BufferReader.cc

package info (click to toggle)
smilutils 0.3.0-10
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 3,008 kB
  • ctags: 2,647
  • sloc: cpp: 13,066; sh: 8,861; ansic: 8,309; makefile: 294
file content (136 lines) | stat: -rw-r--r-- 3,031 bytes parent folder | download | duplicates (2)
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
/*
 * BufferReader.cc -- Buffered Input
 * Copyright (C) 2003 Charles Yates <charles.yates@pandora.be>
 *
 * 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 of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
#include <string.h>
#include <iostream>

#include "BufferReader.h"

/** Create a buffer reader of the specified size (in bytes). Note that this
	class is abstract and doesn't do anything without the Read method being
	implemented.
*/

BufferReader::BufferReader( int _size ) :
	size( _size ),
	used( 0 )
{
	buffer = new uint8_t[ _size ];
	pthread_mutex_init( &mutex, NULL );
}

/** Destructor for the read buffer.
*/

BufferReader::~BufferReader( )
{
	delete buffer;
	pthread_mutex_destroy( &mutex );
}

/** Read n bytes from the buffer.
*/

int BufferReader::GetBuffer( uint8_t *data, int length )
{
	int required = length;
	int error = 0;
	
	pthread_mutex_lock( &mutex );

	do	
	{
		// Make sure the buffer is kept full
		if ( used != size )
		{
			int bytes = Read( buffer + used, size - used );
			if ( bytes > 0 )
				used += bytes;
			else
				error = 1;
		}
		
		// Take what's available
		if ( data != NULL )
		{
			if ( required < used )
			{
				memcpy( data, buffer, required );
				memmove( buffer, buffer + required, used - required );
				used -= required;
				required = 0;
			}
			else
			{
				memcpy( data, buffer, used );
				required -= used;
				used = 0;
			}
		}
	}
	while( !error && required != 0 );

	pthread_mutex_unlock( &mutex );
	
	return length - required;
}

/** Get a single byte from the buffer.
*/

int BufferReader::GetBuffer( uint8_t &byte )
{
	return GetBuffer( &byte, 1 );
}

/** Get an unsigned long from the buffer.
*/

int BufferReader::GetBuffer( unsigned long &value )
{
	uint8_t data[ 4 ];
	int error = GetBuffer( data, 4 );
	value = data[ 0 ] | ( data[ 1 ] << 8 ) | ( data[ 2 ] << 16 ) | ( data[ 3 ] << 24 );
	return error;
}

/** Get a short value from the buffer.
*/

int BufferReader::GetBuffer( int16_t &value )
{
	uint8_t data[ 2 ];
	int error = GetBuffer( data, 2 );
	value = data[ 0 ] | ( data[ 1 ] << 8 );
	return error;
}

/** Get an array of shorts from the buffer.
*/

int BufferReader::GetBuffer( int16_t *values, int length )
{
	int index = 0;
	uint8_t *ptr = buffer;
	int error = GetBuffer( buffer, length * 2 );
	for ( index = 0; index < length; ptr += 2 )
		values[ index ++ ] = *ptr | ( *( ptr + 1 ) << 8 );
	return error;
}