~ubuntu-branches/ubuntu/hardy/arts/hardy

1 by Christopher L Cheney
Import upstream version 1.2.3
1
    /*
2
3
    Copyright (C) 2001 Stefan Westerfeld
4
                       stefan@space.twc.de
5
6
    This library is free software; you can redistribute it and/or
7
    modify it under the terms of the GNU Library General Public
8
    License as published by the Free Software Foundation; either
9
    version 2 of the License, or (at your option) any later version.
10
  
11
    This library is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
    Library General Public License for more details.
15
   
16
    You should have received a copy of the GNU Library General Public License
17
    along with this library; see the file COPYING.LIB.  If not, write to
18
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
    Boston, MA 02111-1307, USA.
20
21
    */
22
23
#include "kmedia2.h"
24
#include "stdsynthmodule.h"
25
#include "debug.h"
26
27
#include <unistd.h>
28
#include <sys/mman.h>
29
#include <stdio.h>
30
#include <unistd.h>
31
#include <fcntl.h>
32
#include <iostream>
1.1.11 by Jonathan Riddell
Import upstream version 1.5.9
33
#include <cstring>
1 by Christopher L Cheney
Import upstream version 1.2.3
34
35
using namespace std;
36
using namespace Arts;
37
38
namespace Arts {
39
class FileInputStream_impl : virtual public FileInputStream_skel,
40
							 virtual public StdSynthModule
41
{
42
protected:
43
	string _filename;
44
	int age, fd;
45
	unsigned int _size, position;
46
	mcopbyte *data;
47
	queue< DataPacket<mcopbyte>* > wqueue;
48
49
public:
50
	static const unsigned int PACKET_COUNT;
51
	static const unsigned int PACKET_SIZE;
52
53
	FileInputStream_impl()
54
	{
55
		fd = -1;
56
		position = 0;
57
		data = 0;
58
		age = 0;
59
		_size = 0;
60
	}
61
	~FileInputStream_impl()
62
	{
63
		arts_assert(wqueue.size() == 0);
64
65
		close();
66
	}
67
68
	void close()
69
	{
70
		if(data != 0)
71
		{
72
			munmap((char*)data, _size);
73
			data = 0;
74
		}
75
76
		if(fd >= 0)
77
		{
78
			::close(fd);
79
			fd = -1;
80
		}
81
	}
82
83
	bool open(const string& filename)
84
	{
85
		close();
86
87
		fd = ::open(filename.c_str(), O_RDONLY);
88
		if(fd < 0)
89
			return false;
90
91
		_size = lseek(fd, 0, SEEK_END);
92
    	lseek(fd, 0, SEEK_SET);
93
94
    	data = (mcopbyte *)mmap(0, _size, PROT_READ, MAP_SHARED, fd, 0);
95
    	if(data == 0)
96
		{
97
			close();
98
			return false;
99
		}
100
101
		position = 0;
102
		if(_filename != filename)
103
		{
104
			_filename = filename;
105
			filename_changed(filename);
106
		}
107
		return true;
108
	}
109
110
	string filename() { return _filename; }
111
	void filename(const string& newfilename) { open(newfilename); }
112
113
	long size()				{ return _size; }
114
	bool eof()
115
	{
116
		return (fd < 0 || position >= _size)
117
			&& (wqueue.size() == PACKET_COUNT);
118
	}
119
	bool seekOk()			{ return true; }
120
121
	long seek(long newPosition)
122
	{
123
		arts_return_val_if_fail(fd < 0, -1);
124
		arts_return_val_if_fail(newPosition < 0, -1);
125
		arts_return_val_if_fail(newPosition > (long)_size, -1);
126
127
		long ageBeforeSeek = age;
128
		position = newPosition;
129
130
		processQueue();
131
		return ageBeforeSeek;
132
	}
133
	
134
	void processQueue()
135
	{
136
		unsigned int qsize = wqueue.size();
137
138
		for(unsigned int i = 0; i < qsize; i++)
139
		{
140
			if(position < _size)
141
			{
142
				DataPacket<mcopbyte> *packet = wqueue.front();
143
				wqueue.pop();
144
145
				packet->size = min(PACKET_SIZE, _size - position);
146
				memcpy(packet->contents, data+position, packet->size);
147
				age += packet->size;
148
				position += packet->size;
149
				packet->send();
150
			}
151
		}
152
	}
153
154
	void request_outdata(DataPacket<mcopbyte> *packet)
155
	{
156
		wqueue.push(packet);
157
		processQueue();
158
	}
159
160
	void streamStart()
161
	{
162
		/*
163
		 * start streaming
164
		 */
165
		outdata.setPull(PACKET_COUNT, PACKET_SIZE);
166
	}
167
168
	void streamEnd()
169
	{
170
		/*
171
		 * end streaming
172
		 */
173
		outdata.endPull();
174
175
		while(!wqueue.empty())
176
		{
177
			DataPacket<mcopbyte> *packet = wqueue.front();
178
			packet->size = 0;
179
			packet->send();
180
			wqueue.pop();
181
		}
182
	}
183
};
184
185
REGISTER_IMPLEMENTATION(FileInputStream_impl);
186
187
const unsigned int
188
FileInputStream_impl::PACKET_COUNT = 8;  
189
190
const unsigned int
191
FileInputStream_impl::PACKET_SIZE = 8192;
192
193
}