/usr/include/assa-3.5/assa/Streambuf.h is in libassa-3.5-5-dev 3.5.1-6.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 | // -*- c++ -*-
//------------------------------------------------------------------------------
// Streambuf.h
//------------------------------------------------------------------------------
// Copyright (c) 1999 by Vladislav Grinchenko
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//------------------------------------------------------------------------------
// Created: 12/02/1999
//------------------------------------------------------------------------------
#ifndef STREAM_BUF_H
#define STREAM_BUF_H
#include <stdio.h> // EOF
#include "assa/Assure.h" // trace() & Assert family
namespace ASSA {
/** @file Streambuf.h
Streambuf class is based on Standard C++ iostream streambuf class.
*/
/**
* io_ptrs structure.
*/
class io_ptrs
{
public:
char* m_read_base;
char* m_read_ptr;
char* m_read_end;
char* m_write_base;
char* m_write_ptr;
char* m_write_end;
char* m_buf_base;
char* m_buf_end;
enum { USER_BUF = 1, UNBUFFERED = 2, EOF_SEEN = 4, ERR_SEEN = 8 };
int m_flags;
char m_shortbuf[1];
io_ptrs () : m_read_base (0), m_read_ptr (0), m_read_end (0),
m_write_base (0), m_write_ptr (0), m_write_end (0),
m_buf_base (0), m_buf_end (0), m_flags (0)
{
m_shortbuf [0] = 0;
}
void dump () const;
};
/**
* Streambuf class.
*
* Streambuf class is based on Standard C++ iostream streambuf class.
*
* Extending std::streambuf is always pain due to the obscurity and
* complexity of its interface, and in general, lack of the source code
* needed to efficiently understand its implementation.
*
* I wrote my own Streambuf that implements a subset of
* std::streambuf functions - a bare minimum to get by
* for Socket buffering.
*
* The buffer of a Streambuf may be considered to have three
* parts: the get area, the put area, and the reserve area
* (which is the same as the buffer area).
*
* The get area contains the characters immediately available for input.
*
* The put area holds characters stored for output but not yet consumed
* by (flushed to) their ultimate destination. The get
* and put areas may be disjoint or may overlap (in my implementation
* they are two disjoined buffers). The reserve
* area is the entire buffer, overlapped by the get and put
* areas (in my implementation, reserve area covers get area only).
* The get and put areas may expand into the remainder
* of the reserve area. In the course of input and output
* operations, the sizes of the get and put areas expand and
* shrink, always bounded by the total buffer size.
*/
class Streambuf : public io_ptrs
{
public:
// Old comment:
//
// "Maximum frame size that can be transmitted unfragmented by TCP
// with MTU 1500 (1500-20-60). TCP frame can have options
// (up to 60 bytes) which, if ignored, might cause fragmentation.
// Also, the length of the IP packet must be evenly divisible by 8."
//
// On 100Mb networks, the reasonable buffer size seems to be 64K.
/** Size of the internal input/output buffer. You can use this
* constant to do application code read/writes to the socket.
*/
static const int MAXTCPFRAMESZ = 65536; // 64K
virtual ~Streambuf ();
/** Set buffer.
* @return setbuf(s_, n_)
*/
Streambuf* pubsetbuf (char* s_, int n_);
/**
* @see sync
* @return sync()
*/
int pubsync ();
/** This function returns the number of characters
immediately available in the get area. It is certain that i
characters may be fetched without error, and without
accessing any external device.
*/
int in_avail ();
/** This function moves the get pointer forward one
position, then returns the character after the get
pointer's new position. If the get pointer is at the
end of the sequence before or after the call to this
function (no character is available), this function
returns EOF. Example: Suppose the input buffer looks
like this: abc|def
where `|' marks the position of the get pointer. This
function will advance the get pointer and return `e'.
*/
int snextc ();
/** This function should probably have been called
``sgetc''. It moves the get pointer forward one posi-
tion and returns the character it moved past. If the
get pointer is currently at the end of the sequence,
this function returns EOF.
*/
int sbumpc ();
/** This function returns the character after the get
pointer, or EOF if the get pointer is at the end of the
sequence. Despite its name, this function does NOT
move the get pointer.
*/
int sgetc ();
/** This function gets the next len_ characters following
the get pointer, copying them to the char array pointed
to by b_; it advances the get pointer past the last
character fetched. If fewer than len characters are
left, it gets as many as are available.
@return the number of characters fetched.
*/
int sgetn (char* b_, int len_);
/** This function stores c just after the put pointer, and
advances the pointer one position, possibly extending
the sequence. It returns c, or EOF on error. What
constitutes an error depends on the actual derived
buffer class.
*/
int sputc (char c_);
/** From the location pointed to by ptr, stores exactly len
characters after the put pointer, advancing the put
pointer just past the last character. It returns the
number of characters stored, which ought to be len.
Fewer than len characters stored indicates some sort of
error.
*/
int sputn (char* b_, int len_);
/** If i_ is non-zero, then all IO operations are buffered.
If i_ is zero, then unbuffered IO is performed (one
character at a time.
*/
void unbuffered (int i_);
/** @return true if unbuffered, false otherwise
*/
int unbuffered ();
protected:
/** The default constructor is protected for class Streambuf
to asssure that only objects for classes derived from this
class may be constructed.
*/
Streambuf ();
Streambuf (const Streambuf&);
Streambuf& operator= (const Streambuf&);
/** Returns the lowest possible value for gptr() - the
beginning of the get area.
*/
char* base () const;
/** Returns a pointer to the beginning of the get area, and
thus to the next character to be fetched (if there are
any). The characters immediately available are from
gptr() through egptr()-1. If egptr()<=gptr(), no char-
acters are available.
*/
char* gptr () const;
/** Returns a pointer just past the end of the get area,
the maximum possible value for gptr().
*/
char* egptr () const;
/** Set get area pointers.
*/
void setg (char* gbeg_, char* gnext_, char* gend_);
/** Returns a pointer to the beginning fo the space available
for the put area, the lowest possible value for pptr().
The area from pbase() through pptr()-1 represents characters
which have been stored int the buffer but not yet consumed.
*/
char* pbase () const;
/** Returns a pointer to the beginning of the put area, and
thus to the location of the next character that is
stored (if possible).
*/
char* pptr () const;
/** Returns a pointer just past the end of the put area,
the maximum possible value for pptr(). The space from
pptr() through epptr() is immediately available for
storing characters without a flush operation.
*/
char* epptr () const;
/** Set put area pointers.
*/
void setp (char* pbeg_, char* pend_);
/** Advances the next pointer for the output sequence by n_.
*/
void pbump (int n_);
/** Establish the reserve area (buffer). Set base() to b_,
ebuf() to eb_. If del_ is non-zero, the buffer will be
deleted whenever base() is changed by another call to
setb(), or when Streambuf destructor is invoked. If del_
is zero, the buffer will not be deleted automatically.
@param b_ pointer to the buffer's first byte
@param eb_ pointer to the byte one past the buffer's last byte
@param del_ 0 - external memory management,
1 - delete on swap/destruction
*/
void setb (char* b_, char* eb_, int del_);
void init ();
protected:
/** Performs an operation that is defined separately for
each class derived from Streambuf.
Default behavior is to set internal buffer to p_.
If p_ is NULL or len_ is 0, then unbuffered I/O (one byte
at a time) is assumed.
@param p_ buffer to use
@param len_ length of the buffer
*/
virtual Streambuf* setbuf (char* p_, int len_);
/** This function synchronizes the streambuf with its
actual stream of characters. The derived class version
should flush any characters in the put area to their
final destination, and if possible give back any
characters in the input buffer to their source. It should
return EOF on any error, zero on success. The default
behavior of the base class version is to return zero if
there are no pending input or output characters
(in_avail() and out_waiting() are both zero), and
return EOF otherwise.
*/
virtual int sync ();
/** The morphemes of showmanyc are "es-how-many-see",
not "show-man-ic".
Return an estimate of the number of characters available in
the sequence, or -1. If it returns a positive value,
then successive calls to underflow() will not return
EOF until at least that number of characters have been supplied.
If showmanyc() returns -1, then calls to underflow() or
uflow() will fail. The intention is not only that these calls
will not return EOF, but that they will return ``immediately.''
*/
virtual int showmanyc ();
/** Assigns up to len_ characters to successive elements of the
array whose first element is designated by b_. The characters
assigned are read from the input sequence as if by repeated calls
to sbumpc(). Assigning stops when either len_ characters have
been assigned or a call to sbumpc() would return EOF.
@return The number of characters assigned.
*/
virtual int xsgetn (char* b_, int len_);
/** This function is called to supply characters for input
(from some source) when the get area is empty, although
it may be called at other times. If the get area is
not empty, it should just return the first character
(without advancing the get pointer). If the get area
is empty, it should establish a new get area, aquire
new input, and return the first character, if any. If
no input characters are available, it should leave an
empty get area and return EOF. The default behavior of
the base class version is undefined, so each derived
class must define its own underflow.
*/
virtual int underflow ();
/** Reads the characters from the input sequence, if possible,
and moves the stream position past it, as follows:
1) If the input sequence has a read position available
the function signals success by returning (unsigned char)*gnext++.
2) Otherwise, if the function can read the character x
directly from the associated input sequence, it signals succes by
returning (unsigned char) x. If the function makes a read
position available, it also assigns x to *gnext.
The default behavior is to call underflow () and, if that
function returns EOF or fails to make a read position
available, return EOF. Otherwise, the function signals
success by returning (unsigned char)*gnext++.
*/
virtual int uflow ();
/** Writes up to len_ characters to the output sequence as if
by repeated calls to sputc (c). The characters written
are obtained from successive elements of the array whose
first element is designated by b_. Writing stops when
either len_ characters have been written or a call to
sputc(c) would return EOF.
@return The number of characters written.
*/
virtual int xsputn (const char* b_, int len_);
/** This function is called to consume characters (flush
them to output), typically when the put area is full
and an attempt is made to store another character. If
c is not EOF, overflow must either store or consume the
character, following those already in the put area. It
returns EOF on error, any other value on success.
The default behavior of the base class version is
undefined, so each derived class must define its own
overflow. The normal action for a derived class version is
to consume the characters in the put area (those
between pbase() and pptr()), call setp() to set up a
new put area, then store c (using sputc()) if it is not
EOF.
*/
virtual int overflow (int c = EOF);
/** This function is called by allocate when unbuffered()
is zero and base() is zero. It attempts to make a
buffer of suitable size available. On success it must
call setb to establish the reserve area, then return a
value greater than zero. On failure it returns EOF.
The default behavior is to allocate a buffer using new.
*/
virtual int doallocate ();
};
inline Streambuf*
Streambuf::
pubsetbuf (char* s_, int n_)
{
trace_with_mask("Streambuf::pubsetbuf",STRMBUFTRACE);
return setbuf (s_, n_);
}
inline int
Streambuf::
pubsync ()
{
trace_with_mask("Streambuf::pubsync",STRMBUFTRACE);
return sync ();
}
inline int
Streambuf::
in_avail ()
{
trace_with_mask("Streambuf::in_avail",STRMBUFTRACE);
return m_read_end - m_read_ptr;
}
inline int
Streambuf::
unbuffered ()
{
trace_with_mask("Streambuf::unbuffered",STRMBUFTRACE);
return m_flags & UNBUFFERED ? 1 : 0;
}
inline void
Streambuf::
unbuffered (int i_)
{
trace_with_mask("Streambuf::unbuffered",STRMBUFTRACE);
if (i_)
m_flags |= UNBUFFERED; // set
else
m_flags &= ~ UNBUFFERED; // unset
}
inline
Streambuf::
Streambuf ()
{
trace_with_mask("Streambuf::Streambuf",STRMBUFTRACE);
init ();
}
inline void
Streambuf::
init ()
{
trace_with_mask("Streambuf::init", STRMBUFTRACE);
m_read_base = m_read_ptr = m_read_end = 0;
m_write_base = m_write_ptr = m_write_end = 0;
m_buf_base = m_buf_end = 0;
m_flags = 0;
m_shortbuf[0] = 0;
}
inline
Streambuf::
~Streambuf ()
{
trace_with_mask("Streambuf::~Streambuf",STRMBUFTRACE);
if (!(m_flags & USER_BUF)) {
delete [] m_buf_base;
m_buf_base = m_buf_end = 0;
}
}
inline char*
Streambuf::
base () const
{
trace_with_mask("Streambuf::base",STRMBUFTRACE);
return m_read_base;
}
inline char*
Streambuf::
gptr () const
{
trace_with_mask("Streambuf::gptr",STRMBUFTRACE);
return m_read_ptr;
}
inline char*
Streambuf::
egptr () const
{
trace_with_mask("Streambuf::egptr",STRMBUFTRACE);
return m_read_end;
}
inline char*
Streambuf::
pbase () const
{
trace_with_mask("Streambuf::pbase",STRMBUFTRACE);
return m_write_base;
}
inline char*
Streambuf::
pptr () const
{
trace_with_mask("Streambuf::pptr",STRMBUFTRACE);
return m_write_ptr;
}
inline char*
Streambuf::
epptr () const
{
trace_with_mask("Streambuf::epptr",STRMBUFTRACE);
return m_write_end;
}
inline void
Streambuf::
pbump (int n_)
{
trace_with_mask("Streambuf::pbump",STRMBUFTRACE);
m_write_ptr += n_;
}
inline int
Streambuf::
sync ()
{
trace_with_mask("Streambuf::sync",STRMBUFTRACE);
return 0;
}
inline int
Streambuf::
showmanyc ()
{
trace_with_mask("Streambuf::showmanyc",STRMBUFTRACE);
return -1;
}
inline int
Streambuf::
sbumpc ()
{
trace_with_mask("Streambuf::sbumpc",STRMBUFTRACE);
return (m_read_ptr >= m_read_end ? uflow ()
: *(unsigned char *) m_read_ptr++);
}
inline int
Streambuf::
sgetc ()
{
trace_with_mask("Streambuf::sgetc",STRMBUFTRACE);
return (m_read_ptr >= m_read_end && underflow () == EOF
? EOF : *(unsigned char*) m_read_ptr);
}
inline int
Streambuf::
sgetn (char* data_, int len_)
{
trace_with_mask("Streambuf::sgetn",STRMBUFTRACE);
return xsgetn (data_, len_);
}
inline int
Streambuf::
sputc (char c_)
{
trace_with_mask("Streambuf::sputc",STRMBUFTRACE);
return (m_write_ptr >= m_write_end
? overflow (c_)
: (unsigned char) (*m_write_ptr++ = c_));
}
inline int
Streambuf::
sputn (char* b_, int len_)
{
trace_with_mask("Streambuf::sputn",STRMBUFTRACE);
return xsputn (b_, len_);
}
inline void
Streambuf::
setp (char* pbeg_, char* pend_)
{
trace_with_mask("Streambuf::setp",STRMBUFTRACE);
m_write_base = m_write_ptr = pbeg_;
m_write_end = pend_;
}
inline int
Streambuf::
underflow ()
{
trace_with_mask("Streambuf::underflow",STRMBUFTRACE);
return (EOF);
}
inline int
Streambuf::
overflow (int /* c_ */)
{
trace_with_mask("Streambuf::overflow",STRMBUFTRACE);
return (EOF);
}
} // end namespace ASSA
#endif /* STREAM_BUF_H */
|