1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
// Myio.cpp
// Simple I/O class to demonstrate use of C++ iostream
// facilities in a customised environment
// Written by David L Nugent, June 1993
# include <iostream.h>
# include <string.h>
# include "Myio.h"
# include "Mystream.h"
Myio::Myio (int sz)
: bufsize(sz), bufchars(0), bufidx(0),
bufaddr(new char[bufsize]), mystream(0)
{}
Myio::~Myio (void)
{
delete bufaddr;
delete mystream;
}
iostream &
Myio::stream (void)
{
if (!mystream) // Create a stream if required
mystream = new Mystream(this);
return *mystream;
}
int // Simple write function into a circular buffer
Myio::write (char const * buf, int len)
{
int avail = (bufsize - bufchars); // See how many fit
if (len > avail)
{
len = avail;
stat |= Myio::overflow; // Only partial write
}
else
stat &= ~Myio::overflow;
avail = bufsize - bufidx; // Caculate room at end
if (avail > len)
avail = len;
if (avail)
{
memcpy (bufaddr + bufidx, buf, avail);
bufidx += avail; // Update the put index
buf += avail; // And the input pointer
}
if (bufidx >= bufsize) // Wrap buffer to start
bufidx = 0;
avail = len - avail; // See if there is any more to go
if (avail)
{
memcpy (bufaddr + bufidx, buf, avail);
bufidx += avail; // Update the put index
}
bufchars += len;
return (_pcount = len);
}
int // Simple read function from a circular buffer
Myio::read (char * buf, int len)
{
if (len > bufchars) // Adjust for available bytes
{
len = bufchars;
stat |= Myio::underflow; // Got an underflow (partial read)
}
else
stat &= ~Myio::underflow; // Clear underflow flag
int startidx = bufidx - bufchars; // Determine start get position
if (startidx < 0)
startidx += bufsize; // Adjust for wrap
int avail = bufsize - startidx; // Check room at end of buffer
if (avail > len) // Adjust down if necessary
avail = len;
if (avail) // Copy first section
{
memcpy (buf, bufaddr + startidx, avail);
startidx += avail; // Adjust start index
buf += avail; // Adjust output pointer
}
if (startidx >= bufsize) // Wrap buffer to start
startidx = 0;
avail = len - avail; // See if there is any more to go
if (avail) // If so, copy the rest
memcpy (buf, bufaddr + startidx, avail);
bufchars -= len; // Adjust character count
return (_gcount = len);
}
Myio &
operator<< (Myio & m, char const * ptr)
{
m.write (ptr, strlen (ptr));
return m;
}
int
Myio::dump (void) const
{
if (bufchars)
{
char * tmp = new char[bufchars + 2];
int idx = bufidx - bufchars;
if (idx < 0)
idx += bufsize;
for (int i = 0; i < bufchars; )
{
if (idx >= bufsize)
idx = 0;
tmp[i++] = bufaddr[idx++];
}
if (i)
{
if (tmp[i-1] != '\n') // Terminate with NL
tmp[i++] = '\n';
tmp[i] = 0;
cout << "---\n"
<< tmp
<< "---\n";
}
delete tmp;
}
return bufchars;
}
|