Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/psx/mednadisc/Stream.cpp
2 views
1
/* Mednafen - Multi-system Emulator
2
*
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
7
*
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
12
*
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
*/
17
18
#include <stdlib.h>
19
#include <stdarg.h>
20
#include <stdio.h>
21
22
#include "emuware/emuware.h"
23
#include "Stream.h"
24
#include "error.h"
25
26
//work around gettext stuff
27
#define _(X) X
28
29
30
Stream::Stream()
31
{
32
33
}
34
35
Stream::~Stream()
36
{
37
38
}
39
40
uint64 Stream::read_discard(uint64 count)
41
{
42
uint8 buf[1024];
43
uint64 tmp;
44
uint64 ret = 0;
45
46
do
47
{
48
tmp = read(buf, std::min<uint64>(count, sizeof(buf)), false);
49
count -= tmp;
50
ret += tmp;
51
} while(tmp == sizeof(buf));
52
53
return ret;
54
}
55
56
uint64 Stream::alloc_and_read(void** data_out, uint64 size_limit)
57
{
58
uint8 *data_buffer = NULL;
59
uint64 data_buffer_size = 0;
60
uint64 data_buffer_alloced = 0;
61
62
try
63
{
64
if(attributes() & ATTRIBUTE_SLOW_SIZE)
65
{
66
uint64 rti;
67
68
data_buffer_size = 0;
69
data_buffer_alloced = 65536;
70
71
if(!(data_buffer = (uint8*)realloc(data_buffer, data_buffer_alloced)))
72
throw MDFN_Error(ErrnoHolder(errno));
73
74
while((rti = read(data_buffer + data_buffer_size, data_buffer_alloced - data_buffer_size, false)) > 0)
75
{
76
uint8* new_data_buffer;
77
78
data_buffer_size += rti;
79
80
if(data_buffer_size == data_buffer_alloced)
81
{
82
data_buffer_alloced <<= 1;
83
84
if(data_buffer_alloced > size_limit) // So we can test against our size limit without going far far over it in temporary memory allocations.
85
data_buffer_alloced = size_limit + 1;
86
87
if(data_buffer_size > size_limit)
88
throw MDFN_Error(0, _("Size limit of %llu bytes would be exceeded."), (unsigned long long)size_limit);
89
90
if(!(new_data_buffer = (uint8 *)realloc(data_buffer, data_buffer_alloced)))
91
throw MDFN_Error(ErrnoHolder(errno));
92
data_buffer = new_data_buffer;
93
}
94
else // EOS
95
break;
96
}
97
98
if(data_buffer_alloced > data_buffer_size)
99
{
100
uint8 *new_data_buffer;
101
102
new_data_buffer = (uint8*)realloc(data_buffer, data_buffer_size);
103
104
if(new_data_buffer != NULL)
105
{
106
data_buffer = new_data_buffer;
107
data_buffer_alloced = data_buffer_size;
108
}
109
}
110
}
111
else
112
{
113
data_buffer_size = size();
114
data_buffer_alloced = data_buffer_size;
115
116
if(data_buffer_size > size_limit)
117
throw MDFN_Error(0, _("Size limit of %llu bytes would be exceeded."), (unsigned long long)size_limit);
118
119
if(data_buffer_alloced > SIZE_MAX)
120
throw MDFN_Error(ErrnoHolder(ENOMEM));
121
122
if(!(data_buffer = (uint8*)realloc(data_buffer, data_buffer_alloced)))
123
throw MDFN_Error(ErrnoHolder(errno));
124
125
read(data_buffer, data_buffer_size);
126
}
127
}
128
catch(...)
129
{
130
if(data_buffer)
131
{
132
free(data_buffer);
133
data_buffer = NULL;
134
}
135
throw;
136
}
137
138
*data_out = data_buffer;
139
return data_buffer_size;
140
}
141
142
uint8* Stream::map(void) noexcept
143
{
144
return(NULL);
145
}
146
147
uint64 Stream::map_size(void) noexcept
148
{
149
return 0;
150
}
151
152
void Stream::unmap(void) noexcept
153
{
154
155
}
156
157
void Stream::put_line(const std::string& str)
158
{
159
char l = '\n';
160
161
write(&str[0], str.size());
162
write(&l, sizeof(l));
163
}
164
165
166
void Stream::print_format(const char *format, ...)
167
{
168
char *str = NULL;
169
int rc;
170
171
va_list ap;
172
173
int size = 128;
174
for(;;) {
175
va_list ap;
176
va_start(ap, format);
177
str = (char*)malloc(size);
178
size *= 2;
179
int ret = vsprintf(str, format, ap);
180
va_end(ap);
181
if(ret>=0)
182
break;
183
free(str);
184
}
185
186
if(rc < 0)
187
throw MDFN_Error(0, "Error in trio_vasprintf()");
188
else
189
{
190
try // Bleck
191
{
192
write(str, rc);
193
}
194
catch(...)
195
{
196
free(str);
197
throw;
198
}
199
free(str);
200
}
201
}
202
203
int Stream::get_line(std::string &str)
204
{
205
uint8 c;
206
207
str.clear(); // or str.resize(0)??
208
209
while(read(&c, sizeof(c), false) > 0)
210
{
211
if(c == '\r' || c == '\n' || c == 0)
212
return(c);
213
214
str.push_back(c);
215
}
216
217
return(str.length() ? 256 : -1);
218
}
219
220
221