FBB::SharedStream(3bobcat) | I/O on shared memory | FBB::SharedStream(3bobcat) |
FBB::SharedStream - I/O operations on shared memory
#include <bobcat/sharedstream>
Linking option: -lpthread -lbobcat
This class combines the features of the std::istream and std::ostream classes, operating on shared memory. As with std::fstream objects, a seekp or seekg member call is required to switch from writing to reading or v.v.
As with std::fstream objects, FBB::SharedStream objects do not keep separate offsets for reading and writing: the seek-members always refer to the (single) offset maintained by the FBB::SharedMemory object to which the SharedStream object interfaces.
So, although tellg and tellp return identical values, tellg should not be called after writing to a SharedStream object, and tellp should not be called after reading from a SharedStream object, as calling members related to reading (tellg) after writing and v.v. put the stream in its fail state.
FBB
All constructors, members, operators and manipulators, mentioned in this
man-page, are defined in the namespace FBB.
FBB::SharedBuf (private inheritance),
std::istream,
std::ostream,
FBB::SharedEnum__ (cf. sharedmemory(3bobcat) for a description
of this base class).
The enum SizeUnit defines the following symbolic constants:
#include <iostream> #include <string> #include <ostream> #include <istream> #include <bobcat/exception> #include <bobcat/sharedstream> #include <bobcat/sharedcondition> using namespace std; using namespace FBB; int main() {
SharedStream sharedStream;
int id = -1;
while (true)
{
cout <<
"\n"
" K kill (no lock) existing shared segment\n"
" S show stats of current shared segment\n"
" L <id> Load segment <id>\n"
" C Install a SharedCondition at offset 0\n"
" c create new shared memory (sets id)\n" // " l lock segment id until key pressed\n" // " p <x> c put char c at offset x\n"
" q quit\n" // " r <x> <n> read n chars from offset x\n" // " w <x> args write all args at offset x\n"
" i insert lines (until empty) at the current "
"offset\n"
" x extract lines (until EOF) from the current "
"offset\n"
" X extract the next line from the current "
"offset\n"
" when nodified via ’N’\n"
" N notify a waiting X\n"
" s <x> seek (abs) offset x\n"
"? ";
char ch;
cin >> ch;
ios::off_type offset;
cout << "Requested: " << ch << ’\n’;
sharedStream.clear();
switch (ch)
{
case ’c’:
{
sharedStream.open(1, SharedStream::kB);
id = sharedStream.id();
cout << "id = " << id << ’\n’;
sharedStream.memInfo(cout);
cout << ’\n’;
}
break;
case ’C’:
{
sharedStream.seekp(0);
SharedCondition cond(sharedStream.createSharedCondition());
sharedStream.seekg(cond.width());
break;
}
case ’K’: // delete segment
{
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
cout << "Removing segment id = " << id << ’\n’;
if (ch == ’R’)
sharedStream.remove();
else
sharedStream.kill();
id = -1;
}
break;
case ’L’:
cin >> id;
cout << "Loading segment " << id << ’\n’;
sharedStream.open(id);
sharedStream.memInfo(cout);
cout << ’\n’;
break;
case ’S’:
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
sharedStream.memInfo(cout);
cout << ’\n’;
break;
case ’s’:
{
size_t offset;
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
cin >> offset;
sharedStream.seekg(offset);
sharedStream.seekp(offset);
cout << "tellg: " << sharedStream.tellg() << ", "
"tellp: " << sharedStream.tellp() << ’\n’;
}
break;
case ’i’:
{
string line;
getline(cin, line);
sharedStream.seekp(0, ios::cur);
while (true)
{
cout << "? ";
if (not getline(cin, line) || line.empty())
break;
sharedStream << line << endl;
cout <<
" tellp: " << sharedStream.tellp() << ’\n’;
}
cout << // " tellg: " << sharedStream.tellg() << ", "
" tellp: " << sharedStream.tellp() << ’\n’;
}
break;
case ’x’:
{
string line;
sharedStream.seekg(0, ios::cur);
while (true)
{
cout << ": ";
if (not getline(sharedStream, line))
break;
cout << line << "\n"
" tellg: " << sharedStream.tellg() << ", "
" tellp: " << sharedStream.tellp() << ’\n’;
}
}
break;
case ’X’:
{
SharedCondition cond(sharedStream.attachSharedCondition(0));
string line;
sharedStream.seekg(cond.width());
cond.lock();
while (true)
{
cond.wait();
cout << ": ";
if (not getline(sharedStream, line))
break;
cout << line << "\n"
" tellg: " << sharedStream.tellg() << ", "
" tellp: " << sharedStream.tellp() << ’\n’;
}
cout << "All done\n";
cond.unlock();
}
break;
case ’N’:
{
string line;
getline(cin, line);
SharedCondition cond(sharedStream.attachSharedCondition(0));
while (true)
{
cout << "’enter’ or ’q’? ";
getline(cin, line);
if (line == "q")
break;
cond.lock();
cond.notify();
cond.unlock();
}
}
break;
case ’p’: // put a char behind the last written
{
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
cin >> offset >> ch;
if (!cin)
throw Exception() << "cmd specification error";
sharedStream.seekp(offset);
cout << "Segment id = " << id << " at write offset " <<
sharedStream.tellp() << ’\n’;
sharedStream.put(ch);
}
break;
case ’r’: // put a char behind the last written
{
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
int n;
cin >> offset >> n;
if (!cin)
throw Exception() << "cmd specification error";
char buf[n];
sharedStream.seekg(offset);
cout << "Segment id = " << id << " at offset " <<
sharedStream.tellg() << ", to read " << n << " bytes\n";
n = sharedStream.read(buf, n).gcount();
if (n < 0)
cout << "No data at " << offset << ’\n’;
else
{
cout << "Retrieved " << n << " bytes, containing `";
cout.write(buf, n);
cout << "’\n";
for (auto ch: buf)
cout << static_cast<int>(ch) << ’ ’;
cout << ’\n’;
}
}
break;
case ’w’: // write chars at offset
{
if (id == -1)
{
cout << "No segment loaded\n";
continue;
}
string line;
cin >> offset;
getline(cin, line);
if (!cin)
throw Exception() << "cmd specification error";
streampos pos = sharedStream.seekp(offset).tellp();
cout << "Segment id = " << id << " at offset " <<
pos << ", to write " << line.length() << " bytes\n";
sharedStream.write(line.data(), line.length());
if (!sharedStream)
cout << "No room left to write any bytes\n";
else
cout << "Wrote " << (sharedStream.tellp() - pos) << " bytes\n";
}
break;
case ’q’:
return 0;
default:
cout << "request not implemented: " << ch << ’\n’;
break;
}
} }
bobcat/sharedstream - defines the class interface
bobcat(7), chmod(1), isharedstream(3bobcat), osharedstream(3bobcat), sharedblock(3bobcat), sharedcondition(3bobcat), sharedmemory(3bobcat) sharedmutex(3bobcat), sharedpos(3bobcat), sharedsegment(3bobcat), sharedbuf(3bobcat)
Note that by default exceptions thrown from within a std::stream object are caught by the stream object, setting its ios::failbit flag. To allow exceptions to leave a stream object, its exceptions member can be called, e.g., using:
myStream.exceptions(ios::failbit | ios::badbit | ios::eofbit);
Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.
This is free software, distributed under the terms of the GNU General Public License (GPL).
Frank B. Brokken (f.b.brokken@rug.nl).
2005-2022 | libbobcat-dev_6.02.02 |