w11 - cpp 0.794
Backend server for Rlink and w11
Loading...
Searching...
No Matches
Rw11VirtStream.cpp
Go to the documentation of this file.
1// $Id: Rw11VirtStream.cpp 1186 2019-07-12 17:49:59Z mueller $
2// SPDX-License-Identifier: GPL-3.0-or-later
3// Copyright 2013-2019 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4//
5// Revision History:
6// Date Rev Version Comment
7// 2019-04-14 1131 1.1.2 add Error(),Eof()
8// 2018-12-19 1090 1.1.1 use RosPrintf(bool)
9// 2018-12-02 1076 1.1 use unique_ptr for New()
10// 2017-04-07 868 1.0.3 Dump(): add detail arg
11// 2017-04-02 864 1.0.2 signal for input streams WProt
12// 2013-05-05 516 1.0.1 Open(): support ?app and ?bck=n options
13// 2013-05-04 515 1.0 Initial version
14// 2013-05-01 513 0.1 First draft
15// ---------------------------------------------------------------------------
16
20#include <memory>
21
22#include "librtools/Rtools.hpp"
25#include "librtools/RosFill.hpp"
27
28#include "Rw11VirtStream.hpp"
29
30using namespace std;
31
37// all method definitions in namespace Retro
38namespace Retro {
39
40//------------------------------------------+-----------------------------------
42
44 : Rw11Virt(punit),
45 fIStream(false),
46 fOStream(false),
47 fFile(0)
48{
49 fStats.Define(kStatNVSRead, "NVSRead", "Read() calls");
50 fStats.Define(kStatNVSReadByt, "NVSReadByt", "bytes read");
51 fStats.Define(kStatNVSWrite, "NVSWrite", "Write() calls");
52 fStats.Define(kStatNVSWriteByt,"NVSWriteByt", "bytes written");
53 fStats.Define(kStatNVSFlush, "NVSFlush", "Flush() calls");
54 fStats.Define(kStatNVSTell, "NVSTell", "Tell() calls");
55 fStats.Define(kStatNVSSeek, "NVSSeek", "Seek() calls");
56}
57
58//------------------------------------------+-----------------------------------
60
62{
63 if (fFile) ::fclose(fFile);
64}
65
66//------------------------------------------+-----------------------------------
68
69bool Rw11VirtStream::Open(const std::string& url, RerrMsg& emsg)
70{
71 RparseUrl opts;
72 if (!opts.Set(fpUnit->AttachOpts(), "|ronly|wonly|", emsg)) return false;
73 fIStream = opts.FindOpt("ronly");
74 fOStream = opts.FindOpt("wonly");
75 if (!(fIStream ^ fOStream))
76 throw Rexception("Rw11VirtStream::Open",
77 "Bad state: neither ronly nor wonly seen");
78
79 if (fOStream) { // handle output streams
80 if (!fUrl.Set(url, "|app|bck=|", emsg)) return false;
81 if (!Rtools::CreateBackupFile(fUrl, emsg)) return false;
82
83 fFile = ::fopen(fUrl.Path().c_str(), fUrl.FindOpt("app") ? "a" : "w");
84
85 } else { // handle input streams
86 fWProt = true;
87 if (!fUrl.Set(url, "", emsg)) return false;
88 fFile = ::fopen(fUrl.Path().c_str(), "r");
89 }
90
91 if (!fFile) {
92 emsg.InitErrno("Rw11VirtStream::Open()",
93 string("fopen() for '") + fUrl.Path() + "' failed: ",
94 errno);
95 return false;
96 }
97
98 return true;
99}
100
101//------------------------------------------+-----------------------------------
103
104int Rw11VirtStream::Read(uint8_t* data, size_t count, RerrMsg& emsg)
105{
106 if (!fIStream)
107 throw Rexception("Rw11VirtStream::Read",
108 "Bad state: Read() called but fIStream=false");
109 if (!fFile)
110 throw Rexception("Rw11VirtStream::Read", "Bad state: file not open");
111
113 size_t irc = ::fread(data, 1, count, fFile);
114 if (irc == 0 && ::ferror(fFile)) {
115 emsg.InitErrno("Rw11VirtStream::Read()", "fread() failed: ", errno);
116 return -1;
117 }
118
119 fStats.Inc(kStatNVSReadByt, double(irc));
120 return int(irc);
121}
122
123//------------------------------------------+-----------------------------------
125
126bool Rw11VirtStream::Write(const uint8_t* data, size_t count, RerrMsg& emsg)
127{
128 if (!fOStream)
129 throw Rexception("Rw11VirtStream::Write",
130 "Bad state: Write() called but fOStream=false");
131 if (!fFile)
132 throw Rexception("Rw11VirtStream::Write", "Bad state: file not open");
133
135 size_t irc = ::fwrite(data, 1, count, fFile);
136 if (irc != count) {
137 emsg.InitErrno("Rw11VirtStream::Write()", "fwrite() failed: ", errno);
138 return false;
139 }
140
141 fStats.Inc(kStatNVSWriteByt, double(count));
142 return true;
143}
144
145//------------------------------------------+-----------------------------------
147
149{
150 if (!fOStream) return true;
151 if (!fFile)
152 throw Rexception("Rw11VirtStream::Write", "Bad state: file not open");
153
155 size_t irc = ::fflush(fFile);
156 if (irc != 0) {
157 emsg.InitErrno("Rw11VirtStream::Flush()", "fflush() failed: ", errno);
158 return false;
159 }
160
161 return true;
162}
163
164//------------------------------------------+-----------------------------------
166
168{
169 if (!fFile)
170 throw Rexception("Rw11VirtStream::Tell", "Bad state: file not open");
171
173 long irc = ::ftell(fFile);
174 if (irc < 0) {
175 emsg.InitErrno("Rw11VirtStream::Tell()", "ftell() failed: ", errno);
176 return -1;
177 }
178
179 return int(irc);
180}
181
182//------------------------------------------+-----------------------------------
184
185bool Rw11VirtStream::Seek(int pos, RerrMsg& emsg)
186{
187 if (!fFile)
188 throw Rexception("Rw11VirtStream::Seek", "Bad state: file not open");
189
191 int whence = SEEK_SET;
192 if (pos < 0) {
193 pos = 0;
194 whence = SEEK_END;
195 }
196 int irc = ::fseek(fFile, pos, whence);
197
198 if (irc < 0) {
199 emsg.InitErrno("Rw11VirtStream::Seek()", "fseek() failed: ", errno);
200 return false;
201 }
202
203 return true;
204}
205
206//------------------------------------------+-----------------------------------
208
210{
211 return fFile ? ::ferror(fFile) : true;
212}
213
214//------------------------------------------+-----------------------------------
216
218{
219 return fFile ? ::feof(fFile) : true;
220}
221
222//------------------------------------------+-----------------------------------
224
225void Rw11VirtStream::Dump(std::ostream& os, int ind, const char* text,
226 int detail) const
227{
228 RosFill bl(ind);
229 os << bl << (text?text:"--") << "Rw11VirtStream @ " << this << endl;
230
231 os << bl << " fIStream: " << RosPrintf(fIStream) << endl;
232 os << bl << " fOStream: " << RosPrintf(fOStream) << endl;
233 os << bl << " fFile: " << fFile << endl;
234 if (fFile) {
235 os << bl << " fFile.tell " << ::ftell(fFile) << endl;
236 os << bl << " fFile.error " << ::ferror(fFile) << endl;
237 os << bl << " fFile.eof " << ::feof(fFile) << endl;
238 }
239
240 Rw11Virt::Dump(os, ind, " ^", detail);
241 return;
242}
243
244//------------------------------------------+-----------------------------------
246
247std::unique_ptr<Rw11VirtStream> Rw11VirtStream::New(const std::string& url,
248 Rw11Unit* punit,
249 RerrMsg& emsg)
250{
251 unique_ptr<Rw11VirtStream> up;
252 up.reset(new Rw11VirtStream(punit));
253 if (!up->Open(url, emsg)) up.reset();
254 return up;
255}
256
257
258} // end namespace Retro
FIXME_docs.
Definition: RerrMsg.hpp:25
void InitErrno(const std::string &meth, const std::string &text, int errnum)
FIXME_docs.
Definition: RerrMsg.cpp:84
FIXME_docs.
Definition: Rexception.hpp:29
I/O appicator to generate fill characters.
Definition: RosFill.hpp:24
FIXME_docs.
Definition: RparseUrl.hpp:27
bool FindOpt(const std::string &name) const
FIXME_docs.
Definition: RparseUrl.cpp:196
bool Set(const std::string &url, const std::string &optlist, RerrMsg &emsg)
FIXME_docs.
Definition: RparseUrl.cpp:55
const std::string & Path() const
FIXME_docs.
Definition: RparseUrl.ipp:45
void Inc(size_t ind, double val=1.)
FIXME_docs.
Definition: Rstats.ipp:29
void Define(size_t ind, const std::string &name, const std::string &text)
FIXME_docs.
Definition: Rstats.cpp:72
FIXME_docs.
Definition: Rw11Unit.hpp:39
const std::string & AttachOpts() const
FIXME_docs.
Definition: Rw11Unit.ipp:48
bool fIStream
is input (read only) stream
bool fOStream
is output (write only) stream
Rw11VirtStream(Rw11Unit *punit)
Default constructor.
bool Write(const uint8_t *data, size_t count, RerrMsg &emsg)
FIXME_docs.
int Read(uint8_t *data, size_t count, RerrMsg &emsg)
FIXME_docs.
int Tell(RerrMsg &emsg)
FIXME_docs.
static std::unique_ptr< Rw11VirtStream > New(const std::string &url, Rw11Unit *punit, RerrMsg &emsg)
FIXME_docs.
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
~Rw11VirtStream()
Destructor.
bool Flush(RerrMsg &emsg)
FIXME_docs.
bool Eof() const
FIXME_docs.
bool Error() const
FIXME_docs.
bool Seek(int pos, RerrMsg &emsg)
FIXME_docs.
virtual bool Open(const std::string &url, RerrMsg &emsg)
FIXME_docs.
FIXME_docs.
Definition: Rw11Virt.hpp:34
RparseUrl fUrl
Definition: Rw11Virt.hpp:66
virtual void Dump(std::ostream &os, int ind=0, const char *text=0, int detail=0) const
FIXME_docs.
Definition: Rw11Virt.cpp:60
Rstats fStats
statistics
Definition: Rw11Virt.hpp:68
Rw11Unit * fpUnit
back ref to unit
Definition: Rw11Virt.hpp:65
bool fWProt
write protected
Definition: Rw11Virt.hpp:67
RosPrintfS< bool > RosPrintf(bool value, const char *form=0, int width=0, int prec=0)
Creates a print object for the formatted output of a bool value.
Definition: RosPrintf.ipp:38
bool CreateBackupFile(const std::string &fname, size_t nbackup, RerrMsg &emsg)
FIXME_docs.
Definition: Rtools.cpp:98
Declaration of class ReventLoop.
Definition: ReventLoop.cpp:47