SHOGUN
v1.1.0
Main Page
Related Pages
Classes
Files
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Pages
src
shogun
io
IOBuffer.cpp
Go to the documentation of this file.
1
/*
2
Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights
3
embodied in the content of this file are licensed under the BSD
4
(revised) open source license.
5
6
Copyright (c) 2011 Berlin Institute of Technology and Max-Planck-Society.
7
8
This program is free software; you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation; either version 3 of the License, or
11
(at your option) any later version.
12
13
Shogun adjustments (w) 2011 Shashwat Lal Das
14
*/
15
16
#include <string.h>
17
#include <
shogun/io/IOBuffer.h
>
18
19
using namespace
shogun;
20
21
CIOBuffer::CIOBuffer
()
22
{
23
init
();
24
}
25
26
CIOBuffer::CIOBuffer
(
int
fd)
27
{
28
init
();
29
working_file
= fd;
30
}
31
32
CIOBuffer::~CIOBuffer
()
33
{
34
free(
space
.
begin
);
35
}
36
37
void
CIOBuffer::init
()
38
{
39
size_t
s = 1 << 16;
40
space
.
reserve
(s);
41
endloaded
=
space
.
begin
;
42
}
43
44
void
CIOBuffer::use_file
(
int
fd)
45
{
46
working_file
= fd;
47
}
48
49
int
CIOBuffer::open_file
(
const
char
* name,
char
flag)
50
{
51
int
ret=1;
52
switch
(flag)
53
{
54
case
'r'
:
55
working_file
= open(name, O_RDONLY|
O_LARGEFILE
);
56
break
;
57
58
case
'w'
:
59
working_file
= open(name, O_CREAT|O_TRUNC|O_WRONLY, 0666);
60
break
;
61
62
default
:
63
SG_ERROR
(
"Unknown file operation. Something other than 'r'/'w' specified.\n"
);
64
ret = 0;
65
}
66
return
ret;
67
}
68
69
void
CIOBuffer::reset_file
()
70
{
71
lseek(
working_file
, 0, SEEK_SET);
72
endloaded
=
space
.
begin
;
73
space
.
end
=
space
.
begin
;
74
}
75
76
void
CIOBuffer::set
(
char
*p)
77
{
78
space
.
end
= p;
79
}
80
81
ssize_t
CIOBuffer::read_file
(
void
* buf,
size_t
nbytes)
82
{
83
return
read(
working_file
, buf, nbytes);
84
}
85
86
size_t
CIOBuffer::fill
()
87
{
88
if
(
space
.
end_array
-
endloaded
== 0)
89
{
90
size_t
offset =
endloaded
-
space
.
begin
;
91
space
.
reserve
(2 * (
space
.
end_array
-
space
.
begin
));
92
endloaded
=
space
.
begin
+offset;
93
}
94
ssize_t num_read =
read_file
(
endloaded
,
space
.
end_array
-
endloaded
);
95
if
(num_read >= 0)
96
{
97
endloaded
=
endloaded
+num_read;
98
return
num_read;
99
}
100
else
101
return
0;
102
}
103
104
ssize_t
CIOBuffer::write_file
(
const
void
* buf,
size_t
nbytes)
105
{
106
return
write(
working_file
, buf, nbytes);
107
}
108
109
void
CIOBuffer::flush
()
110
{
111
if
(
write_file
(
space
.
begin
,
space
.
index
()) != (
int
)
space
.
index
())
112
SG_ERROR
(
"Error, failed to write example!\n"
);
113
space
.
end
=
space
.
begin
;
114
fsync(
working_file
);
115
}
116
117
bool
CIOBuffer::close_file
()
118
{
119
if
(
working_file
< 0)
120
return
false
;
121
else
122
{
123
int
r = close(
working_file
);
124
if
(r < 0)
125
SG_ERROR
(
"Error closing the file!\n"
);
126
return
true
;
127
}
128
}
129
130
ssize_t
CIOBuffer::readto
(
char
* &pointer,
char
terminal)
131
{
132
//Return a pointer to the bytes before the terminal. Must be less
133
//than the buffer size.
134
pointer =
space
.
end
;
135
while
(pointer !=
endloaded
&& *pointer != terminal)
136
pointer++;
137
if
(pointer !=
endloaded
)
138
{
139
size_t
n = pointer -
space
.
end
;
140
space
.
end
= pointer+1;
141
pointer -= n;
142
return
n;
143
}
144
else
145
{
146
if
(
endloaded
==
space
.
end_array
)
147
{
148
size_t
left =
endloaded
-
space
.
end
;
149
memmove(
space
.
begin
,
space
.
end
, left);
150
space
.
end
=
space
.
begin
;
151
endloaded
=
space
.
begin
+left;
152
pointer =
endloaded
;
153
}
154
if
(
fill
() > 0)
// more bytes are read.
155
return
readto
(pointer,terminal);
156
else
//no more bytes to read, return nothing.
157
return
0;
158
}
159
}
160
161
void
CIOBuffer::buf_write
(
char
* &pointer,
int
n)
162
{
163
if
(
space
.
end
+ n <=
space
.
end_array
)
164
{
165
pointer =
space
.
end
;
166
space
.
end
+= n;
167
}
168
else
// Time to dump the file
169
{
170
if
(
space
.
end
!=
space
.
begin
)
171
flush
();
172
else
// Array is short, so increase size.
173
{
174
space
.
reserve
(2 * (
space
.
end_array
-
space
.
begin
));
175
endloaded
=
space
.
begin
;
176
}
177
buf_write
(pointer,n);
178
}
179
}
180
181
unsigned
int
CIOBuffer::buf_read
(
char
* &pointer,
int
n)
182
{
183
// Return a pointer to the next n bytes.
184
// n must be smaller than the maximum size.
185
if
(
space
.
end
+ n <=
endloaded
)
186
{
187
pointer =
space
.
end
;
188
space
.
end
+= n;
189
return
n;
190
}
191
else
// out of bytes, so refill.
192
{
193
if
(
space
.
end
!=
space
.
begin
)
//There exists room to shift.
194
{
195
// Out of buffer so swap to beginning.
196
int
left =
endloaded
-
space
.
end
;
197
memmove(
space
.
begin
,
space
.
end
, left);
198
space
.
end
=
space
.
begin
;
199
endloaded
=
space
.
begin
+left;
200
}
201
if
(
fill
() > 0)
202
return
buf_read
(pointer,n);
// more bytes are read.
203
else
204
{
205
// No more bytes to read, return all that we have left.
206
pointer =
space
.
end
;
207
space
.
end
=
endloaded
;
208
return
endloaded
- pointer;
209
}
210
}
211
}
SHOGUN
Machine Learning Toolbox - Documentation