summaryrefslogtreecommitdiff
path: root/src/stream.h
blob: abbc9e81a15a4756e28c96e901c94e948544941d (plain)
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef BU_STREAM_H
#define BU_STREAM_H

#include "bu/config.h"

#include <stdint.h>
#include <stdio.h>

#include "bu/string.h"

namespace Bu
{
	/**
	 * The basis for a completely general data transport mechanism.  Anything
	 * that inherits from this should provide at least the basic read and/or
	 * write functions, and very probably the close function.  Any functions
	 * that aren't supported should throw an exception if called.
	 *
	 * The constructor of a child class should pretty much universally be used
	 * to open the stream.  I can't think of anything that should require an
	 * exception.
	 *@ingroup Streams
	 */
	class Stream
	{
	public:
		Stream();
		virtual ~Stream();

		/**
		 * Close the stream.
		 */
		virtual void close() = 0;

		/**
		 * Read data from the stream into a buffer.
		 *@param pBuf (void *) Buffer which will be filled.
		 *@param nBytes (size_t) Max data to read.
		 *@returns (size_t) Amount of data read.
		 */
		virtual size read( void *pBuf, size iBytes ) = 0;

		/**
		 * Attempts to read a complete line from the stream.  This will stop
		 * reading when it has reached the end of the stream, or runs out of
		 * data in a non-blocking stream.
		 *@returns The line read, not including newline character.
		 */
		virtual Bu::String readLine();

		/**
		 * Write data to the stream.
		 *@param pBuf (const void *) The data to be written.
		 *@param nBytes (size_t) Amount of data to write from pBuf.
		 *@returns (size_t) Amount of data actually written.
		 */
		virtual size write( const void *pBuf, size iBytes ) = 0;

		virtual size write( const Bu::String &sBuf );

		/**
		 * Get the current position in the stream.
		 *@returns (long) The current position in the stream.
		 */
		virtual size tell() = 0;

		/**
		 * Seek to a position in the stream relative to the current position.
		 *@param offset (long) Offset from current position to seek to.
		 */
		virtual void seek( size offset ) = 0;

		/**
		 * Set position in the stream relative to the start of the stream.
		 *@param pos (long) The position.
		 */
		virtual void setPos( size pos ) = 0;

		/**
		 * Set position in the stream relative to the end of the stream.
		 *@param pos (long) The position.
		 */
		virtual void setPosEnd( size pos ) = 0;

		/**
		 * Are we at the end of the stream?
		 *@returns (bool) Are we at the end of the stream?
		 */
		virtual bool isEos() = 0;

		/**
		 * Is the stream open?
		 *@returns (bool) Is the stream open?
		 */
		virtual bool isOpen() = 0;

		/**
		 * Flush any data still held in buffers.
		 */
		virtual void flush() = 0;

		/**
		 * In non-blocking streams this indicates if a read operation will
		 * return data at the moment or not.  In blocking streams this should
		 * return the same value as isEos().
		 */
		virtual bool canRead() = 0;

		/**
		 * In non-blocking streams this indicates if a write operation will
		 * actually write one or more bytes.  In some cases writing is not
		 * allowed (e.g. internal buffers are full) temporarilly.  In blocking
		 * streams this should return the same value as isWritable.
		 */
		virtual bool canWrite() = 0;

		/**
		 * Indicates if the stream is capable of read operations.  This does not
		 * indicate if such operations will return useful data, see canRead for
		 * that.
		 */
		virtual bool isReadable() = 0;

		/**
		 * Indicates if the stream is capable of write operations.  This does
		 * not indicate if such operations will succeed or fail, see canWrite
		 * for that.
		 */
		virtual bool isWritable() = 0;

		/**
		 * Indicates if the stream is capable of seek operations.  This is
		 * generally false for non-blocking streams.  Some buffered streams may
		 * support limited in-buffer seeking.
		 */
		virtual bool isSeekable() = 0;

		/**
		 * Are we currently set to block mode?
		 *@returns (bool)
		 */
		virtual bool isBlocking() = 0;

		/**
		 * Set stream to blocking or non-blocking mode.
		 *@param bBlocking (bool) Whether we should block or not.
		 */
		virtual void setBlocking( bool bBlocking=true ) = 0;

		/**
		 * Set the size of the stream, this does not apply to many types of
		 * streams.  For those that it does apply to, data will be added or
		 * removed from the end of the stream, but the content of the added
		 * data is undefined.
		 */
		virtual void setSize( size iSize ) = 0;

		/**
		 * Returns the size of the stream if the stream can have a size.  For
		 * streams that do not (sockets, pipes, etc.) this should throw an
		 * unsupported exception.
		 */
		virtual size getSize() const = 0;

		/**
		 * Returns the block-size of the stream, if it has one.  This should
		 * throw an unsupported exception.  In some cases the block size
		 * returned will not represent quite the same thing, for example,
		 * sockets will return their MTU, while files will return the
		 * filesystem's block size, and memory buffers will throw an exception.
		 */
		virtual size getBlockSize() const = 0;

		/**
		 * If possible, this returns a string that can be used to describe how
		 * to access the open stream.  Not all streams support this, such as
		 * MemBuf, but for files it may give you a path to a file, for a socket
		 * it may give you an ip address, etc.  If it isn't supported, an empty
		 * string may be returned.
		 */
		virtual Bu::String getLocation() const = 0;

	private:

	};
}

#endif