177 lines
4.8 KiB
C++
177 lines
4.8 KiB
C++
// Copyright (C) 2003 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_SOCKStREAMBUF_CPp_
|
|
#define DLIB_SOCKStREAMBUF_CPp_
|
|
|
|
#include "sockstreambuf.h"
|
|
#include "../assert.h"
|
|
|
|
#include <cstring>
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// output functions
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
sockstreambuf::int_type sockstreambuf::
|
|
overflow (
|
|
int_type c
|
|
)
|
|
{
|
|
if (c != EOF)
|
|
{
|
|
*pptr() = c;
|
|
pbump(1);
|
|
}
|
|
if (flush_out_buffer() == EOF)
|
|
{
|
|
// an error occurred
|
|
return EOF;
|
|
}
|
|
return c;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
std::streamsize sockstreambuf::
|
|
xsputn (
|
|
const char* s,
|
|
std::streamsize num
|
|
)
|
|
{
|
|
// Add a sanity check here
|
|
DLIB_ASSERT(num >= 0,
|
|
"\tstd::streamsize sockstreambuf::xsputn"
|
|
<< "\n\tThe number of bytes to write can't be negative"
|
|
<< "\n\tnum: " << num
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
std::streamsize space_left = static_cast<std::streamsize>(epptr()-pptr());
|
|
if (num <= space_left)
|
|
{
|
|
std::memcpy(pptr(),s,static_cast<size_t>(num));
|
|
pbump(static_cast<int>(num));
|
|
return num;
|
|
}
|
|
else
|
|
{
|
|
std::memcpy(pptr(),s,static_cast<size_t>(space_left));
|
|
s += space_left;
|
|
pbump(space_left);
|
|
std::streamsize num_left = num - space_left;
|
|
|
|
if (flush_out_buffer() == EOF)
|
|
{
|
|
// the write was not successful so return that 0 bytes were written
|
|
return 0;
|
|
}
|
|
|
|
if (num_left < out_buffer_size)
|
|
{
|
|
std::memcpy(pptr(),s,static_cast<size_t>(num_left));
|
|
pbump(num_left);
|
|
return num;
|
|
}
|
|
else
|
|
{
|
|
if (con.write(s,num_left) != num_left)
|
|
{
|
|
// the write was not successful so return that 0 bytes were written
|
|
return 0;
|
|
}
|
|
return num;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
// input functions
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
sockstreambuf::int_type sockstreambuf::
|
|
underflow(
|
|
)
|
|
{
|
|
if (gptr() < egptr())
|
|
{
|
|
return static_cast<unsigned char>(*gptr());
|
|
}
|
|
|
|
int num_put_back = static_cast<int>(gptr() - eback());
|
|
if (num_put_back > max_putback)
|
|
{
|
|
num_put_back = max_putback;
|
|
}
|
|
|
|
// copy the putback characters into the putback end of the in_buffer
|
|
std::memmove(in_buffer+(max_putback-num_put_back), gptr()-num_put_back, num_put_back);
|
|
|
|
if (flushes_output_on_read())
|
|
{
|
|
if (flush_out_buffer() == EOF)
|
|
{
|
|
// an error occurred
|
|
return EOF;
|
|
}
|
|
}
|
|
|
|
int num = con.read(in_buffer+max_putback, in_buffer_size-max_putback);
|
|
if (num <= 0)
|
|
{
|
|
// an error occurred or the connection is over which is EOF
|
|
return EOF;
|
|
}
|
|
|
|
// reset in_buffer pointers
|
|
setg (in_buffer+(max_putback-num_put_back),
|
|
in_buffer+max_putback,
|
|
in_buffer+max_putback+num);
|
|
|
|
return static_cast<unsigned char>(*gptr());
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
std::streamsize sockstreambuf::
|
|
xsgetn (
|
|
char_type* s,
|
|
std::streamsize n
|
|
)
|
|
{
|
|
std::streamsize temp = n;
|
|
while (n > 0)
|
|
{
|
|
int num = static_cast<int>(egptr() - gptr());
|
|
if (num >= n)
|
|
{
|
|
// copy data from our buffer
|
|
std::memcpy(s, gptr(), static_cast<size_t>(n));
|
|
gbump(static_cast<int>(n));
|
|
return temp;
|
|
}
|
|
|
|
// read more data into our buffer
|
|
if (num == 0)
|
|
{
|
|
if (underflow() == EOF)
|
|
break;
|
|
continue;
|
|
}
|
|
|
|
// copy all the data from our buffer
|
|
std::memcpy(s, gptr(), num);
|
|
n -= num;
|
|
gbump(num);
|
|
s += num;
|
|
}
|
|
return temp-n;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
#endif // DLIB_SOCKStREAMBUF_CPp_
|
|
|