Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/octoshock/Stream.h
2 views
1
#ifndef __MDFN_STREAM_H
2
#define __MDFN_STREAM_H
3
4
// TODO/WIP
5
6
// TODO?: BufferedStream, no virtual functions, yes inline functions, constructor takes a Stream* argument.
7
8
#include <errno.h>
9
10
#include <stdio.h> // For SEEK_* defines, which we will use in Stream out of FORCE OF HABIT.
11
#include <string>
12
13
#include "octoshock.h"
14
15
class Stream
16
{
17
public:
18
19
Stream();
20
virtual ~Stream();
21
22
enum
23
{
24
ATTRIBUTE_READABLE = 1U << 0,
25
ATTRIBUTE_WRITEABLE = 1U << 1,
26
ATTRIBUTE_SEEKABLE = 1U << 2,
27
ATTRIBUTE_SLOW_SEEK = 1U << 3,
28
ATTRIBUTE_SLOW_SIZE = 1U << 4
29
};
30
virtual uint64 attributes(void) = 0;
31
32
virtual uint8 *map(void) = 0; // Map the entirety of the stream data into the address space of the process, if possible, and return a pointer.
33
// (the returned pointer must be cached, and returned on any subsequent calls to map() without an unmap()
34
// in-between, to facilitate a sort of "feature-testing", to determine if an alternative like "MemoryStream"
35
// should be used).
36
//
37
// If the mapping fails for whatever reason, return NULL rather than throwing an exception.
38
//
39
40
virtual void unmap(void) = 0; // Unmap the stream data from the address space. (Possibly invalidating the pointer returned from map()).
41
// (must automatically be called, if necessary, from the destructor).
42
//
43
// If the data can't be "unmapped" as such because it was never mmap()'d or similar in the first place(such as with MemoryStream),
44
// then this will be a nop.
45
46
virtual uint64 read(void *data, uint64 count, bool error_on_eos = true) = 0;
47
virtual void write(const void *data, uint64 count) = 0;
48
49
virtual void seek(int64 offset, int whence = SEEK_SET) = 0;
50
inline void rewind(void)
51
{
52
seek(0, SEEK_SET);
53
}
54
virtual int64 tell(void) = 0;
55
virtual int64 size(void) = 0;
56
virtual void close(void) = 0; // Flushes(in the case of writeable streams) and closes the stream.
57
// Necessary since this operation can fail(running out of disk space, for instance),
58
// and throw an exception in the destructor would be a Bad Idea(TM).
59
//
60
// Manually calling this function isn't strictly necessary, but recommended when the
61
// stream is writeable; it will be called automatically from the destructor, with any
62
// exceptions thrown caught and logged.
63
64
//
65
// Utility functions(TODO):
66
//
67
INLINE uint8 get_u8(void)
68
{
69
uint8 ret;
70
71
read(&ret, sizeof(ret));
72
73
return ret;
74
}
75
76
INLINE void put_u8(uint8 c)
77
{
78
write(&c, sizeof(c));
79
}
80
81
82
template<typename T>
83
INLINE T get_NE(void)
84
{
85
T ret;
86
87
read(&ret, sizeof(ret));
88
89
return ret;
90
}
91
92
template<typename T>
93
INLINE void put_NE(T c)
94
{
95
write(&c, sizeof(c));
96
}
97
98
99
template<typename T>
100
INLINE T get_RE(void)
101
{
102
uint8 tmp[sizeof(T)];
103
T ret = 0;
104
105
read(tmp, sizeof(tmp));
106
107
for(unsigned i = 0; i < sizeof(T); i++)
108
ret |= (T)tmp[i] << (i * 8);
109
110
return ret;
111
}
112
113
template<typename T>
114
INLINE void put_RE(T c)
115
{
116
uint8 tmp[sizeof(T)];
117
118
for(unsigned i = 0; i < sizeof(T); i++)
119
tmp[i] = ((uint8 *)&c)[sizeof(T) - 1 - i];
120
121
write(tmp, sizeof(tmp));
122
}
123
124
template<typename T>
125
INLINE T get_LE(void)
126
{
127
#ifdef LSB_FIRST
128
return get_NE<T>();
129
#else
130
return get_RE<T>();
131
#endif
132
}
133
134
template<typename T>
135
INLINE void put_LE(T c)
136
{
137
#ifdef LSB_FIRST
138
return put_NE<T>(c);
139
#else
140
return put_RE<T>(c);
141
#endif
142
}
143
144
template<typename T>
145
INLINE T get_BE(void)
146
{
147
#ifndef LSB_FIRST
148
return get_NE<T>();
149
#else
150
return get_RE<T>();
151
#endif
152
}
153
154
template<typename T>
155
INLINE void put_BE(T c)
156
{
157
#ifndef LSB_FIRST
158
return put_NE<T>(c);
159
#else
160
return put_RE<T>(c);
161
#endif
162
}
163
164
// Reads a line into "str", overwriting its contents; returns the line-end char('\n' or '\r' or '\0'), or 256 on EOF and
165
// data has been read into "str", and -1 on EOF when no data has been read into "str".
166
// The line-end char won't be added to "str".
167
// It's up to the caller to handle extraneous empty lines caused by DOS-format text lines(\r\n).
168
// ("str" is passed by reference for the possibility of improved performance by reusing alloced memory for the std::string, though part
169
// of it would be up to the STL implementation).
170
// Implemented as virtual so that a higher-performance version can be implemented if possible(IE with MemoryStream)
171
virtual int get_line(std::string &str);
172
173
virtual void put_line(const std::string& str);
174
175
virtual void print_format(const char *format, ...);
176
177
#if 0
178
int scanf(const char *format, ...) MDFN_FORMATSTR(gnu_scanf, 2, 3);
179
void put_string(const char *str);
180
void put_string(const std::string &str);
181
#endif
182
};
183
184
// StreamFilter takes ownership of the Stream pointer passed, and will delete it in its destructor.
185
class StreamFilter : public Stream
186
{
187
public:
188
189
StreamFilter();
190
StreamFilter(Stream *target_arg);
191
virtual ~StreamFilter();
192
193
virtual uint64 read(void *data, uint64 count, bool error_on_eos = true) = 0;
194
virtual void write(const void *data, uint64 count) = 0;
195
virtual void seek(int64 offset, int whence) = 0;
196
virtual int64 tell(void) = 0;
197
virtual int64 size(void) = 0;
198
virtual void close(void) = 0;
199
200
virtual Stream *steal(void);
201
202
private:
203
Stream *target_stream;
204
};
205
206
#endif
207
208