Пример #1
0
long sockbuf::howmanyc ()
// return how many chars are available for reading in the input buffer
// and the recvbuf of the socket.
{
    std::streamsize theShowMany = showmanyc();
    assert (theShowMany < INT_MAX);
    return (long)theShowMany + nread ();
}
Пример #2
0
streamsize mem_streambuf::xsgetn( char_type *buf, std::streamsize size ) {
  streamsize const remaining = showmanyc();
  if ( size > remaining )
    size = remaining;
  ::memcpy( buf, gptr(), static_cast<size_t>( size ) );
  gbump( static_cast<int>(size) );
  return size;
}
Пример #3
0
  streamsize
  streambuf::in_avail()
  {
#if defined(OS_INCLUDE_STREAMBUF_BUFFERS)
    if (mgend != 0 && mgnext != 0)
      {
        return mgend - mgnext;
      }
#endif
    return showmanyc();
  }
Пример #4
0
std::streamsize sockbuf::xsgetn (char_type* s, std::streamsize n)
{
    std::streamsize rval = showmanyc ();
    if (rval >= n) {
        memcpy (s, gptr (), (size_t)(n * sizeof (char_type)));
        gbump ((int)n);
        return n;
    }

    memcpy (s, gptr (), (size_t)(rval * sizeof (char_type)));
    gbump ((int)rval);

    if (underflow () != eof)
        return rval + xsgetn (s + rval, n - rval);

    return rval;
}
Пример #5
0
std::streamsize
ProcReader::xsgetn(char_type* ptr, std::streamsize num)
{
	std::streamsize howMany = showmanyc();
	if (num < howMany) {
		memcpy(ptr, gptr(), num * sizeof(char_type));
		gbump(num);
		return num;
	}

	memcpy(ptr, gptr(), howMany * sizeof(char_type));
	gbump(howMany);

	if (traits_type::eof() == underflow())
		return howMany;

	return howMany + xsgetn(ptr + howMany, num - howMany);
}
Пример #6
0
std::streamsize filedescriptor_streambuf::xsgetn(
  char *target, std::streamsize count)
{
  std::streamsize available = showmanyc();

  if(count <= available)
  {
    memcpy(target, gptr(), count * sizeof(char_type));
    gbump(count);

    return count;
  }

  memcpy(target, gptr(), available * sizeof(char_type));
  gbump(available);

  if(traits_type::eof() == underflow())
    return available;

  return (available + xsgetn(target+available, count-available));
}
Пример #7
0
std::streamsize Socket::showmanyc() {
	#ifdef WIN32
	unsigned long result = 0;
	if(ioctlsocket(handle, FIONREAD, &result)) {
	#else
	int result = 0;
	if(ioctl(handle, FIONREAD, &result)) {
	#endif
        disconnect();
		throw Exception(Exception::ERROR_IOCTL);
    }else
        return result;
}

std::streamsize Socket::advanceInputBuffer() {
    if(inputIntermediateSize == 0) //No input buffer
        return 0;

    std::streamsize inAvail;
    if(type == UDP_PEER)
        inAvail = 0;
    else{
        inAvail = egptr()-gptr();
        memmove(eback(), gptr(), inAvail);
    }

    try {
        inAvail += receive(eback()+inAvail, inputIntermediateSize-inAvail);
    } catch(Exception err) {

    }

    setg(eback(), eback(), eback()+inAvail);
    return inAvail;
}

std::streamsize Socket::receive(char_type* buffer, std::streamsize size) {
	if(type == TCP_SERVER)
		throw Exception(Exception::BAD_TYPE);
	if(status != Socket::Status::READY && status != Socket::Status::BUSY)
		return 0;
    size = std::min(size, showmanyc());
    if(size == 0)
		return 0;

    switch(type) {
        case UDP_PEER: {
            struct sockaddr_storage remoteAddr;
			#ifdef WIN32
			int addrSize = sizeof(remoteAddr);
			#else
			unsigned int addrSize = sizeof(remoteAddr);
			#endif
            int result = recvfrom(handle, (char*)buffer, size, 0, reinterpret_cast<struct sockaddr*>(&remoteAddr), &addrSize);

            if(result <= 0) {
                portRemote = 0;
                hostRemote = "";
                throw Exception(Exception::ERROR_READ);
            }else
                readSockaddr(&remoteAddr, hostRemote, portRemote);

            return result;
        }
        case TCP_CLIENT:
        case TCP_SERVERS_CLIENT: {
            int result = recv(handle, (char*)buffer, size, 0);

            if(result <= 0)
				throw Exception(Exception::ERROR_READ);

            return result;
        }
		default:
        case NONE:
        case TCP_SERVER:
            throw Exception(Exception::BAD_TYPE);
    }
}

std::streamsize Socket::send(const char_type* buffer, std::streamsize size) {
	if(type == TCP_SERVER)
		throw Exception(Exception::BAD_TYPE);
	if(status != Socket::Status::READY || size == 0)
		return 0;

    switch(type) {
        case UDP_PEER: {
            AddrinfoContainer info = getSocketInfoFor(hostRemote.c_str(), portRemote, false);

            size_t sentBytes = 0;
            while(sentBytes < (size_t)size) {
                int result = ::sendto(handle, (const char*)buffer + sentBytes, size - sentBytes, 0, info->ai_addr, info->ai_addrlen);
				if(result <= 0) {
					status = BUSY;
	                throw Exception(Exception::ERROR_SEND);
				}
                sentBytes += result;
            }

            return sentBytes;
        }
        case TCP_CLIENT:
        case TCP_SERVERS_CLIENT: {
            size_t sentBytes = 0;
            while(sentBytes < (size_t)size) {
                int result = ::send(handle, (const char*)buffer + sentBytes, size - sentBytes, 0);
				if(result <= 0) {
					status = BUSY;
	                throw Exception(Exception::ERROR_SEND);
				}
                sentBytes += result;
            }
            return sentBytes;
        }
		default:
        case NONE:
        case TCP_SERVER:
            throw Exception(Exception::BAD_TYPE);
    }
}

std::streamsize Socket::redirect(const std::vector<std::shared_ptr<Socket>>& destinations) {
	if(type == TCP_SERVER)
		throw Exception(Exception::BAD_TYPE);

	std::streamsize size = 0;
	while(in_avail()) {
		auto length = egptr()-gptr();
		for(const auto& destination : destinations)
			if(destination->sputn(gptr(), length) < length)
				throw Exception(Exception::ERROR_SEND);
		gbump(length);
		size += length;
		advanceInputBuffer();
	}

	return size;
}

std::streamsize Socket::getInputBufferSize() {
    return inputIntermediateSize;
}

std::streamsize Socket::getOutputBufferSize() {
    return epptr()-pbase();
}

void Socket::setInputBufferSize(std::streamsize n) {
    if(eback()) {
        delete[] eback();
        setg(NULL, NULL, NULL);
    }
    if(n == 0) return;
    if(type == TCP_SERVER)
        throw Exception(Exception::BAD_TYPE);

    char_type* readBuffer = new char_type[n];
    setg(readBuffer, readBuffer, readBuffer);
    inputIntermediateSize = n;
}

void Socket::setOutputBufferSize(std::streamsize n) {
    if(pbase()) {
        delete[] pbase();
        setp(NULL, NULL);
    }
    if(n == 0) return;
    if(type == TCP_SERVER)
        throw Exception(Exception::BAD_TYPE);

    char_type* writeBuffer = new char_type[n];
    setp(writeBuffer, writeBuffer+n);
}

void Socket::setBlockingMode(bool blocking) {
	#ifdef WIN32
	unsigned long flag = !blocking;
	if(ioctlsocket(handle, FIONBIO, &flag) != 0)
	#else
    int flags = fcntl(handle, F_GETFL);
    if(blocking)
        flags &= ~O_NONBLOCK;
    else
        flags |= O_NONBLOCK;
    if(fcntl(handle, F_SETFL, flags) == -1)
	#endif
		throw Exception(Exception::ERROR_IOCTL);
}
Пример #8
0
std::streamsize Socket::showmanyc() {
	#ifdef WIN32
	unsigned long result = -1;
	if(ioctlsocket(handle, FIONREAD, &result)) {
	#else
	int result = -1;
	if(ioctl(handle, FIONREAD, &result)) {
	#endif
        disconnect();
		throw Exception(Exception::ERROR_IOCTL);
    }else
        return result;
}

std::streamsize Socket::advanceInputBuffer() {
    if(inputIntermediateSize == 0) //No input buffer
        return 0;

    std::streamsize inAvail;
    if(type == UDP_PEER)
        inAvail = 0;
    else{
        inAvail = egptr()-gptr();
        memmove(eback(), gptr(), inAvail);
    }

    try {
        inAvail += receive(eback()+inAvail, inputIntermediateSize-inAvail);
    } catch(Exception err) {

    }

    setg(eback(), eback(), eback()+inAvail);
    return inAvail;
}

std::streamsize Socket::receive(char_type* buffer, std::streamsize size) {
    size = std::min(size, showmanyc());
    if(size == 0) return 0;
    
    switch(type) {
        case UDP_PEER: {
            struct sockaddr_storage remoteAddr;
			#ifdef WIN32
			int addrSize = sizeof(remoteAddr);
			#else
			unsigned int addrSize = sizeof(remoteAddr);
			#endif
            int result = recvfrom(handle, (char*)buffer, size, 0, reinterpret_cast<struct sockaddr*>(&remoteAddr), &addrSize);
            
            if(result == -1) {
                portRemote = 0;
                hostRemote = "";
                throw Exception(Exception::ERROR_READ);
            }else
                readSockaddr(&remoteAddr, hostRemote, portRemote);
            
            return result;
        }
        case TCP_CLIENT:
        case TCP_SERVERS_CLIENT: {
            int result = recv(handle, (char*)buffer, size, 0);
            
            if(result == -1)
                throw Exception(Exception::ERROR_READ);
            
            return result;
        }
		default:
        case NONE:
        case TCP_SERVER:
            throw Exception(Exception::BAD_TYPE);
    }
}