File: substream.h

package info (click to toggle)
scummvm 2.9.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 450,580 kB
  • sloc: cpp: 4,299,825; asm: 28,322; python: 12,901; sh: 11,302; java: 9,289; xml: 7,895; perl: 2,639; ansic: 2,465; yacc: 1,670; javascript: 1,020; makefile: 933; lex: 578; awk: 275; objc: 82; sed: 11; php: 1
file content (135 lines) | stat: -rw-r--r-- 4,716 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
/* ScummVM - Graphic Adventure Engine
 *
 * ScummVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the COPYRIGHT
 * file distributed with this source distribution.
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef COMMON_SUBSTREAM_H
#define COMMON_SUBSTREAM_H

#include "common/mutex.h"
#include "common/ptr.h"
#include "common/stream.h"
#include "common/types.h"

namespace Common {

/**
 * @defgroup common_substream Substreams
 * @ingroup common_stream
 *
 * @brief API for managing readable data substreams.
 *
 * @{
 */

/**
 * SubReadStream provides access to a ReadStream restricted to the range
 * [currentPosition, currentPosition+end).
 *
 * Manipulating the parent stream directly /will/ mess up a substream.
 * Likewise, manipulating two substreams of a parent stream will cause them to
 * step on each others toes.
 */
class SubReadStream : virtual public ReadStream {
protected:
	DisposablePtr<ReadStream> _parentStream;
	uint32 _pos;
	uint32 _end;
	bool _eos;
public:
	SubReadStream(ReadStream *parentStream, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO)
		: _parentStream(parentStream, disposeParentStream),
		  _pos(0),
		  _end(end),
		  _eos(false) {
		assert(parentStream);
	}

	virtual bool eos() const { return _eos || _parentStream->eos(); }
	virtual bool err() const { return _parentStream->err(); }
	virtual void clearErr() { _eos = false; _parentStream->clearErr(); }
	virtual uint32 read(void *dataPtr, uint32 dataSize);
};

/*
 * SeekableSubReadStream provides access to a SeekableReadStream restricted to
 * the range [begin, end).
 * The same caveats apply to SeekableSubReadStream as do to SeekableReadStream.
 *
 * Manipulating the parent stream directly /will/ mess up a substream.
 * @see SubReadStream
 */
class SeekableSubReadStream : public SubReadStream, virtual public SeekableReadStream {
protected:
	SeekableReadStream *_parentStream;
	uint32 _begin;
public:
	SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO);

	virtual int64 pos() const { return _pos - _begin; }
	virtual int64 size() const { return _end - _begin; }

	virtual bool seek(int64 offset, int whence = SEEK_SET);
};

/**
 * A seekable substream that removes the exclusivity demand required by the
 * normal SeekableSubReadStream, at the cost of seek()ing the parent stream
 * before each read().
 *
 * More than one SafeSeekableSubReadStream to the same parent stream can be used
 * at the same time; they won't mess up each other. They will, however,
 * reposition the parent stream, so don't depend on its position to be
 * the same after a read() or seek() on one of its SafeSeekableSubReadStream.
 *
 * Note that this stream is *not* threading safe. Calling read from the audio
 * thread and from the main thread might mess up the data retrieved.
 */
class SafeSeekableSubReadStream : public SeekableSubReadStream {
public:
	SafeSeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO)
		: SeekableSubReadStream(parentStream, begin, end, disposeParentStream) {
	}

	virtual uint32 read(void *dataPtr, uint32 dataSize);
};

/**
 * A special variant of SafeSeekableSubReadStream which locks a mutex during each read.
 * This is necessary if the music is streamed from disk and it could happen
 * that a sound effect or another music track is played from the same read stream
 * while the first music track is updated/read.
 */

class SafeMutexedSeekableSubReadStream : public Common::SafeSeekableSubReadStream {
public:
	SafeMutexedSeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream,
		Common::Mutex &mutex)
		: SafeSeekableSubReadStream(parentStream, begin, end, disposeParentStream), _mutex(mutex) {
	}
	uint32 read(void *dataPtr, uint32 dataSize) override;
protected:
	Common::Mutex &_mutex;
};

/** @} */

} // End of namespace Common

#endif