Initial commit
This commit is contained in:
30
common/rdr/CMakeLists.txt
Normal file
30
common/rdr/CMakeLists.txt
Normal file
@@ -0,0 +1,30 @@
|
||||
include_directories(${CMAKE_SOURCE_DIR}/common ${ZLIB_INCLUDE_DIRS})
|
||||
|
||||
add_library(rdr STATIC
|
||||
Exception.cxx
|
||||
FdInStream.cxx
|
||||
FdOutStream.cxx
|
||||
FileInStream.cxx
|
||||
HexInStream.cxx
|
||||
HexOutStream.cxx
|
||||
InStream.cxx
|
||||
RandomStream.cxx
|
||||
TLSException.cxx
|
||||
TLSInStream.cxx
|
||||
TLSOutStream.cxx
|
||||
ZlibInStream.cxx
|
||||
ZlibOutStream.cxx)
|
||||
|
||||
set(RDR_LIBRARIES ${ZLIB_LIBRARIES} os)
|
||||
if(GNUTLS_FOUND)
|
||||
set(RDR_LIBRARIES ${RDR_LIBRARIES} ${GNUTLS_LIBRARIES})
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(RDR_LIBRARIES ${RDR_LIBRARIES} ws2_32)
|
||||
endif()
|
||||
|
||||
target_link_libraries(rdr ${RDR_LIBRARIES})
|
||||
|
||||
if(UNIX)
|
||||
libtool_create_control_file(rdr)
|
||||
endif()
|
||||
99
common/rdr/Exception.cxx
Normal file
99
common/rdr/Exception.cxx
Normal file
@@ -0,0 +1,99 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2004 Red Hat Inc.
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
#include <rdr/TLSException.h>
|
||||
#ifdef _WIN32
|
||||
#include <tchar.h>
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
Exception::Exception(const char *format, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
(void) vsnprintf(str_, len, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
SystemException::SystemException(const char* s, int err_)
|
||||
: Exception("%s", s), err(err_)
|
||||
{
|
||||
strncat(str_, ": ", len-1-strlen(str_));
|
||||
#ifdef _WIN32
|
||||
// Windows error messages are crap, so use unix ones for common errors.
|
||||
const char* msg = 0;
|
||||
switch (err) {
|
||||
case WSAECONNREFUSED: msg = "Connection refused"; break;
|
||||
case WSAETIMEDOUT: msg = "Connection timed out"; break;
|
||||
case WSAECONNRESET: msg = "Connection reset by peer"; break;
|
||||
case WSAECONNABORTED: msg = "Connection aborted"; break;
|
||||
}
|
||||
if (msg) {
|
||||
strncat(str_, msg, len-1-strlen(str_));
|
||||
} else {
|
||||
#ifdef UNICODE
|
||||
WCHAR* tmsg = new WCHAR[len-strlen(str_)];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, tmsg, len-1-strlen(str_), 0);
|
||||
WideCharToMultiByte(CP_ACP, 0, tmsg, wcslen(tmsg)+1,
|
||||
str_+strlen(str_), len-strlen(str_), 0, 0);
|
||||
delete [] tmsg;
|
||||
#else
|
||||
char* currStr = str_+strlen(str_);
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
0, err, 0, currStr, len-1-strlen(str_), 0);
|
||||
#endif
|
||||
int l = strlen(str_);
|
||||
if ((l >= 2) && (str_[l-2] == '\r') && (str_[l-1] == '\n'))
|
||||
str_[l-2] = 0;
|
||||
}
|
||||
|
||||
#else
|
||||
strncat(str_, strerror(err), len-1-strlen(str_));
|
||||
#endif
|
||||
strncat(str_, " (", len-1-strlen(str_));
|
||||
char buf[20];
|
||||
#ifdef WIN32
|
||||
if (err < 0)
|
||||
sprintf(buf, "%x", err);
|
||||
else
|
||||
#endif
|
||||
sprintf(buf,"%d",err);
|
||||
strncat(str_, buf, len-1-strlen(str_));
|
||||
strncat(str_, ")", len-1-strlen(str_));
|
||||
}
|
||||
|
||||
55
common/rdr/Exception.h
Normal file
55
common/rdr/Exception.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2004 Red Hat Inc.
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_EXCEPTION_H__
|
||||
#define __RDR_EXCEPTION_H__
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define __printf_attr(a, b) __attribute__((__format__ (__printf__, a, b)))
|
||||
#else
|
||||
# define __printf_attr(a, b)
|
||||
#endif // __GNUC__
|
||||
|
||||
namespace rdr {
|
||||
|
||||
struct Exception {
|
||||
enum { len = 256 };
|
||||
char str_[len];
|
||||
Exception(const char *format = 0, ...) __printf_attr(2, 3);
|
||||
virtual ~Exception() {}
|
||||
virtual const char* str() const { return str_; }
|
||||
};
|
||||
|
||||
struct SystemException : public Exception {
|
||||
int err;
|
||||
SystemException(const char* s, int err_);
|
||||
};
|
||||
|
||||
struct TimedOut : public Exception {
|
||||
TimedOut() : Exception("Timed out") {}
|
||||
};
|
||||
|
||||
struct EndOfStream : public Exception {
|
||||
EndOfStream() : Exception("End of stream") {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
260
common/rdr/FdInStream.cxx
Normal file
260
common/rdr/FdInStream.cxx
Normal file
@@ -0,0 +1,260 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#define close closesocket
|
||||
#undef errno
|
||||
#define errno WSAGetLastError()
|
||||
#include <os/winerrno.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef vncmin
|
||||
#define vncmin(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef vncmax
|
||||
#define vncmax(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* Old systems have select() in sys/time.h */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/FdInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 8192,
|
||||
MIN_BULK_SIZE = 1024 };
|
||||
|
||||
FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
|
||||
bool closeWhenDone_)
|
||||
: fd(fd_), closeWhenDone(closeWhenDone_),
|
||||
timeoutms(timeoutms_), blockCallback(0),
|
||||
timing(false), timeWaitedIn100us(5), timedKbits(0),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
|
||||
int bufSize_)
|
||||
: fd(fd_), timeoutms(0), blockCallback(blockCallback_),
|
||||
timing(false), timeWaitedIn100us(5), timedKbits(0),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
FdInStream::~FdInStream()
|
||||
{
|
||||
delete [] start;
|
||||
if (closeWhenDone) close(fd);
|
||||
}
|
||||
|
||||
|
||||
void FdInStream::setTimeout(int timeoutms_) {
|
||||
timeoutms = timeoutms_;
|
||||
}
|
||||
|
||||
void FdInStream::setBlockCallback(FdInStreamBlockCallback* blockCallback_)
|
||||
{
|
||||
blockCallback = blockCallback_;
|
||||
timeoutms = 0;
|
||||
}
|
||||
|
||||
int FdInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void FdInStream::readBytes(void* data, int length)
|
||||
{
|
||||
if (length < MIN_BULK_SIZE) {
|
||||
InStream::readBytes(data, length);
|
||||
return;
|
||||
}
|
||||
|
||||
U8* dataPtr = (U8*)data;
|
||||
|
||||
int n = end - ptr;
|
||||
if (n > length) n = length;
|
||||
|
||||
memcpy(dataPtr, ptr, n);
|
||||
dataPtr += n;
|
||||
length -= n;
|
||||
ptr += n;
|
||||
|
||||
while (length > 0) {
|
||||
n = readWithTimeoutOrCallback(dataPtr, length);
|
||||
dataPtr += n;
|
||||
length -= n;
|
||||
offset += n;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FdInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("FdInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
offset += ptr - start;
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
int bytes_to_read;
|
||||
while (end < start + itemSize) {
|
||||
bytes_to_read = start + bufSize - end;
|
||||
if (!timing) {
|
||||
// When not timing, we must be careful not to read too much
|
||||
// extra data into the buffer. Otherwise, the line speed
|
||||
// estimation might stay at zero for a long time: All reads
|
||||
// during timing=1 can be satisfied without calling
|
||||
// readWithTimeoutOrCallback. However, reading only 1 or 2 bytes
|
||||
// bytes is ineffecient.
|
||||
bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8));
|
||||
}
|
||||
int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
|
||||
if (n == 0) return 0;
|
||||
end += n;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
//
|
||||
// readWithTimeoutOrCallback() reads up to the given length in bytes from the
|
||||
// file descriptor into a buffer. If the wait argument is false, then zero is
|
||||
// returned if no bytes can be read without blocking. Otherwise if a
|
||||
// blockCallback is set, it will be called (repeatedly) instead of blocking.
|
||||
// If alternatively there is a timeout set and that timeout expires, it throws
|
||||
// a TimedOut exception. Otherwise it returns the number of bytes read. It
|
||||
// never attempts to recv() unless select() indicates that the fd is readable -
|
||||
// this means it can be used on an fd which has been set non-blocking. It also
|
||||
// has to cope with the annoying possibility of both select() and recv()
|
||||
// returning EINTR.
|
||||
//
|
||||
|
||||
int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait)
|
||||
{
|
||||
struct timeval before, after;
|
||||
if (timing)
|
||||
gettimeofday(&before, 0);
|
||||
|
||||
int n;
|
||||
while (true) {
|
||||
do {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct timeval* tvp = &tv;
|
||||
|
||||
if (!wait) {
|
||||
tv.tv_sec = tv.tv_usec = 0;
|
||||
} else if (timeoutms != -1) {
|
||||
tv.tv_sec = timeoutms / 1000;
|
||||
tv.tv_usec = (timeoutms % 1000) * 1000;
|
||||
} else {
|
||||
tvp = 0;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
n = select(fd+1, &fds, 0, 0, tvp);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n > 0) break;
|
||||
if (n < 0) throw SystemException("select",errno);
|
||||
if (!wait) return 0;
|
||||
if (!blockCallback) throw TimedOut();
|
||||
|
||||
blockCallback->blockCallback();
|
||||
}
|
||||
|
||||
do {
|
||||
n = ::recv(fd, (char*)buf, len, 0);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n < 0) throw SystemException("read",errno);
|
||||
if (n == 0) throw EndOfStream();
|
||||
|
||||
if (timing) {
|
||||
gettimeofday(&after, 0);
|
||||
int newTimeWaited = ((after.tv_sec - before.tv_sec) * 10000 +
|
||||
(after.tv_usec - before.tv_usec) / 100);
|
||||
int newKbits = n * 8 / 1000;
|
||||
|
||||
// limit rate to between 10kbit/s and 40Mbit/s
|
||||
|
||||
if (newTimeWaited > newKbits*1000) newTimeWaited = newKbits*1000;
|
||||
if (newTimeWaited < newKbits/4) newTimeWaited = newKbits/4;
|
||||
|
||||
timeWaitedIn100us += newTimeWaited;
|
||||
timedKbits += newKbits;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
void FdInStream::startTiming()
|
||||
{
|
||||
timing = true;
|
||||
|
||||
// Carry over up to 1s worth of previous rate for smoothing.
|
||||
|
||||
if (timeWaitedIn100us > 10000) {
|
||||
timedKbits = timedKbits * 10000 / timeWaitedIn100us;
|
||||
timeWaitedIn100us = 10000;
|
||||
}
|
||||
}
|
||||
|
||||
void FdInStream::stopTiming()
|
||||
{
|
||||
timing = false;
|
||||
if (timeWaitedIn100us < timedKbits/2)
|
||||
timeWaitedIn100us = timedKbits/2; // upper limit 20Mbit/s
|
||||
}
|
||||
|
||||
unsigned int FdInStream::kbitsPerSecond()
|
||||
{
|
||||
// The following calculation will overflow 32-bit arithmetic if we have
|
||||
// received more than about 50Mbytes (400Mbits) since we started timing, so
|
||||
// it should be OK for a single RFB update.
|
||||
|
||||
return timedKbits * 10000 / timeWaitedIn100us;
|
||||
}
|
||||
78
common/rdr/FdInStream.h
Normal file
78
common/rdr/FdInStream.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// FdInStream streams from a file descriptor.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FDINSTREAM_H__
|
||||
#define __RDR_FDINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FdInStreamBlockCallback {
|
||||
public:
|
||||
virtual void blockCallback() = 0;
|
||||
virtual ~FdInStreamBlockCallback() {}
|
||||
};
|
||||
|
||||
class FdInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
FdInStream(int fd, int timeoutms=-1, int bufSize=0,
|
||||
bool closeWhenDone_=false);
|
||||
FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
|
||||
virtual ~FdInStream();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
void setBlockCallback(FdInStreamBlockCallback* blockCallback);
|
||||
int getFd() { return fd; }
|
||||
int pos();
|
||||
void readBytes(void* data, int length);
|
||||
|
||||
void startTiming();
|
||||
void stopTiming();
|
||||
unsigned int kbitsPerSecond();
|
||||
unsigned int timeWaited() { return timeWaitedIn100us; }
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
|
||||
|
||||
int fd;
|
||||
bool closeWhenDone;
|
||||
int timeoutms;
|
||||
FdInStreamBlockCallback* blockCallback;
|
||||
|
||||
bool timing;
|
||||
unsigned int timeWaitedIn100us;
|
||||
unsigned int timedKbits;
|
||||
|
||||
int bufSize;
|
||||
int offset;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
213
common/rdr/FdOutStream.cxx
Normal file
213
common/rdr/FdOutStream.cxx
Normal file
@@ -0,0 +1,213 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright 2011 Pierre Ossman for Cendio AB
|
||||
* Copyright 2017 Peter Astrand <astrand@cendio.se> for Cendio AB
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#undef errno
|
||||
#define errno WSAGetLastError()
|
||||
#include <os/winerrno.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* Old systems have select() in sys/time.h */
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/FdOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <rfb/util.h>
|
||||
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_)
|
||||
: fd(fd_), blocking(blocking_), timeoutms(timeoutms_),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
ptr = start = sentUpTo = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
|
||||
gettimeofday(&lastWrite, NULL);
|
||||
}
|
||||
|
||||
FdOutStream::~FdOutStream()
|
||||
{
|
||||
try {
|
||||
blocking = true;
|
||||
flush();
|
||||
} catch (Exception&) {
|
||||
}
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void FdOutStream::setTimeout(int timeoutms_) {
|
||||
timeoutms = timeoutms_;
|
||||
}
|
||||
|
||||
void FdOutStream::setBlocking(bool blocking_) {
|
||||
blocking = blocking_;
|
||||
}
|
||||
|
||||
int FdOutStream::length()
|
||||
{
|
||||
return offset + ptr - sentUpTo;
|
||||
}
|
||||
|
||||
int FdOutStream::bufferUsage()
|
||||
{
|
||||
return ptr - sentUpTo;
|
||||
}
|
||||
|
||||
unsigned FdOutStream::getIdleTime()
|
||||
{
|
||||
return rfb::msSince(&lastWrite);
|
||||
}
|
||||
|
||||
void FdOutStream::flush()
|
||||
{
|
||||
while (sentUpTo < ptr) {
|
||||
int n = writeWithTimeout((const void*) sentUpTo,
|
||||
ptr - sentUpTo,
|
||||
blocking? timeoutms : 0);
|
||||
|
||||
// Timeout?
|
||||
if (n == 0) {
|
||||
// If non-blocking then we're done here
|
||||
if (!blocking)
|
||||
break;
|
||||
|
||||
throw TimedOut();
|
||||
}
|
||||
|
||||
sentUpTo += n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
// Managed to flush everything?
|
||||
if (sentUpTo == ptr)
|
||||
ptr = sentUpTo = start;
|
||||
}
|
||||
|
||||
|
||||
int FdOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("FdOutStream overrun: max itemSize exceeded");
|
||||
|
||||
// First try to get rid of the data we have
|
||||
flush();
|
||||
|
||||
// Still not enough space?
|
||||
if (itemSize > end - ptr) {
|
||||
// Can we shuffle things around?
|
||||
// (don't do this if it gains us less than 25%)
|
||||
if ((sentUpTo - start > bufSize / 4) &&
|
||||
(itemSize < bufSize - (ptr - sentUpTo))) {
|
||||
memmove(start, sentUpTo, ptr - sentUpTo);
|
||||
ptr = start + (ptr - sentUpTo);
|
||||
sentUpTo = start;
|
||||
} else {
|
||||
// Have to get rid of more data, so turn off non-blocking
|
||||
// for a bit...
|
||||
bool realBlocking;
|
||||
|
||||
realBlocking = blocking;
|
||||
blocking = true;
|
||||
flush();
|
||||
blocking = realBlocking;
|
||||
}
|
||||
}
|
||||
|
||||
// Can we fit all the items asked for?
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
//
|
||||
// writeWithTimeout() writes up to the given length in bytes from the given
|
||||
// buffer to the file descriptor. If there is a timeout set and that timeout
|
||||
// expires, it throws a TimedOut exception. Otherwise it returns the number of
|
||||
// bytes written. It never attempts to send() unless select() indicates that
|
||||
// the fd is writable - this means it can be used on an fd which has been set
|
||||
// non-blocking. It also has to cope with the annoying possibility of both
|
||||
// select() and send() returning EINTR.
|
||||
//
|
||||
|
||||
int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms)
|
||||
{
|
||||
int n;
|
||||
|
||||
do {
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
struct timeval* tvp = &tv;
|
||||
|
||||
if (timeoutms != -1) {
|
||||
tv.tv_sec = timeoutms / 1000;
|
||||
tv.tv_usec = (timeoutms % 1000) * 1000;
|
||||
} else {
|
||||
tvp = NULL;
|
||||
}
|
||||
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
n = select(fd+1, 0, &fds, 0, tvp);
|
||||
} while (n < 0 && errno == EINTR);
|
||||
|
||||
if (n < 0)
|
||||
throw SystemException("select", errno);
|
||||
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
// select only guarantees that you can write SO_SNDLOWAT without
|
||||
// blocking, which is normally 1. Use MSG_DONTWAIT to avoid
|
||||
// blocking, when possible.
|
||||
#ifndef MSG_DONTWAIT
|
||||
n = ::send(fd, (const char*)data, length, 0);
|
||||
#else
|
||||
n = ::send(fd, (const char*)data, length, MSG_DONTWAIT);
|
||||
#endif
|
||||
} while (n < 0 && (errno == EINTR));
|
||||
|
||||
if (n < 0)
|
||||
throw SystemException("write", errno);
|
||||
|
||||
gettimeofday(&lastWrite, NULL);
|
||||
|
||||
return n;
|
||||
}
|
||||
66
common/rdr/FdOutStream.h
Normal file
66
common/rdr/FdOutStream.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright 2011 Pierre Ossman for Cendio AB
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// FdOutStream streams to a file descriptor.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FDOUTSTREAM_H__
|
||||
#define __RDR_FDOUTSTREAM_H__
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FdOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0);
|
||||
virtual ~FdOutStream();
|
||||
|
||||
void setTimeout(int timeoutms);
|
||||
void setBlocking(bool blocking);
|
||||
int getFd() { return fd; }
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
int bufferUsage();
|
||||
|
||||
unsigned getIdleTime();
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems);
|
||||
int writeWithTimeout(const void* data, int length, int timeoutms);
|
||||
int fd;
|
||||
bool blocking;
|
||||
int timeoutms;
|
||||
int bufSize;
|
||||
int offset;
|
||||
U8* start;
|
||||
U8* sentUpTo;
|
||||
struct timeval lastWrite;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
87
common/rdr/FileInStream.cxx
Normal file
87
common/rdr/FileInStream.cxx
Normal file
@@ -0,0 +1,87 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2013 D. R. Commander. All Rights Reserved.
|
||||
* Copyright 2015 Pierre Ossman for Cendio AB
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
#include <rdr/FileInStream.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
FileInStream::FileInStream(const char *fileName)
|
||||
{
|
||||
file = fopen(fileName, "rb");
|
||||
if (!file)
|
||||
throw SystemException("fopen", errno);
|
||||
ptr = end = b;
|
||||
}
|
||||
|
||||
FileInStream::~FileInStream(void) {
|
||||
if (file) {
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void FileInStream::reset(void) {
|
||||
if (!file)
|
||||
throw Exception("File is not open");
|
||||
if (fseek(file, 0, SEEK_SET) != 0)
|
||||
throw SystemException("fseek", errno);
|
||||
ptr = end = b;
|
||||
}
|
||||
|
||||
int FileInStream::pos()
|
||||
{
|
||||
if (!file)
|
||||
throw Exception("File is not open");
|
||||
|
||||
return ftell(file) + ptr - b;
|
||||
}
|
||||
|
||||
int FileInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > (int)sizeof(b))
|
||||
throw Exception("FileInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(b, ptr, end - ptr);
|
||||
|
||||
end -= ptr - b;
|
||||
ptr = b;
|
||||
|
||||
|
||||
while (end < b + itemSize) {
|
||||
size_t n = fread((U8 *)end, b + sizeof(b) - end, 1, file);
|
||||
if (n == 0) {
|
||||
if (ferror(file))
|
||||
throw SystemException("fread", errno);
|
||||
if (feof(file))
|
||||
throw EndOfStream();
|
||||
return 0;
|
||||
}
|
||||
end += b + sizeof(b) - end;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
50
common/rdr/FileInStream.h
Normal file
50
common/rdr/FileInStream.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2013 D. R. Commander. All Rights Reserved.
|
||||
* Copyright 2015 Pierre Ossman for Cendio AB
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_FILEINSTREAM_H__
|
||||
#define __RDR_FILEINSTREAM_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FileInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
FileInStream(const char *fileName);
|
||||
~FileInStream(void);
|
||||
|
||||
void reset(void);
|
||||
|
||||
int pos();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait = true);
|
||||
|
||||
private:
|
||||
U8 b[131072];
|
||||
FILE *file;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
52
common/rdr/FixedMemOutStream.h
Normal file
52
common/rdr/FixedMemOutStream.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// A FixedMemOutStream writes to a buffer of a fixed length.
|
||||
//
|
||||
|
||||
#ifndef __RDR_FIXEDMEMOUTSTREAM_H__
|
||||
#define __RDR_FIXEDMEMOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class FixedMemOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
FixedMemOutStream(void* buf, int len) {
|
||||
ptr = start = (U8*)buf;
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
int length() { return ptr - start; }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
const void* data() { return (const void*)start; }
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems) { throw EndOfStream(); }
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
117
common/rdr/HexInStream.cxx
Normal file
117
common/rdr/HexInStream.cxx
Normal file
@@ -0,0 +1,117 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/HexInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 16384;
|
||||
|
||||
static inline int min(int a, int b) {return a<b ? a : b;}
|
||||
|
||||
HexInStream::HexInStream(InStream& is, int bufSize_)
|
||||
: bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
}
|
||||
|
||||
HexInStream::~HexInStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
|
||||
bool HexInStream::readHexAndShift(char c, int* v) {
|
||||
c=tolower(c);
|
||||
if ((c >= '0') && (c <= '9'))
|
||||
*v = (*v << 4) + (c - '0');
|
||||
else if ((c >= 'a') && (c <= 'f'))
|
||||
*v = (*v << 4) + (c - 'a' + 10);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
|
||||
int l=strlen(s);
|
||||
if ((l % 2) == 0) {
|
||||
delete [] *data;
|
||||
*data = 0; *length = 0;
|
||||
if (l == 0)
|
||||
return true;
|
||||
*data = new char[l/2];
|
||||
*length = l/2;
|
||||
for(int i=0;i<l;i+=2) {
|
||||
int byte = 0;
|
||||
if (!readHexAndShift(s[i], &byte) ||
|
||||
!readHexAndShift(s[i+1], &byte))
|
||||
goto decodeError;
|
||||
(*data)[i/2] = byte;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
decodeError:
|
||||
delete [] *data;
|
||||
*data = 0;
|
||||
*length = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int HexInStream::pos() {
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
int HexInStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("HexInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
end -= ptr - start;
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < ptr + itemSize) {
|
||||
int n = in_stream.check(2, 1, wait);
|
||||
if (n == 0) return 0;
|
||||
const U8* iptr = in_stream.getptr();
|
||||
const U8* eptr = in_stream.getend();
|
||||
int length = min((eptr - iptr)/2, start + bufSize - end);
|
||||
|
||||
U8* optr = (U8*) end;
|
||||
for (int i=0; i<length; i++) {
|
||||
int v = 0;
|
||||
readHexAndShift(iptr[i*2], &v);
|
||||
readHexAndShift(iptr[i*2+1], &v);
|
||||
optr[i] = v;
|
||||
}
|
||||
|
||||
in_stream.setptr(iptr + length*2);
|
||||
end += length;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
50
common/rdr/HexInStream.h
Normal file
50
common/rdr/HexInStream.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_HEX_INSTREAM_H__
|
||||
#define __RDR_HEX_INSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class HexInStream : public InStream {
|
||||
public:
|
||||
|
||||
HexInStream(InStream& is, int bufSize=0);
|
||||
virtual ~HexInStream();
|
||||
|
||||
int pos();
|
||||
|
||||
static bool readHexAndShift(char c, int* v);
|
||||
static bool hexStrToBin(const char* s, char** data, int* length);
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
int bufSize;
|
||||
U8* start;
|
||||
int offset;
|
||||
|
||||
InStream& in_stream;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
110
common/rdr/HexOutStream.cxx
Normal file
110
common/rdr/HexOutStream.cxx
Normal file
@@ -0,0 +1,110 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/HexOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 16384;
|
||||
|
||||
static inline int min(int a, int b) {return a<b ? a : b;}
|
||||
|
||||
HexOutStream::HexOutStream(OutStream& os, int buflen)
|
||||
: out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
|
||||
{
|
||||
if (bufSize % 2)
|
||||
bufSize--;
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
}
|
||||
|
||||
HexOutStream::~HexOutStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
|
||||
char HexOutStream::intToHex(int i) {
|
||||
if ((i>=0) && (i<=9))
|
||||
return '0'+i;
|
||||
else if ((i>=10) && (i<=15))
|
||||
return 'a'+(i-10);
|
||||
else
|
||||
throw rdr::Exception("intToHex failed");
|
||||
}
|
||||
|
||||
char* HexOutStream::binToHexStr(const char* data, int length) {
|
||||
char* buffer = new char[length*2+1];
|
||||
for (int i=0; i<length; i++) {
|
||||
buffer[i*2] = intToHex((data[i] >> 4) & 15);
|
||||
buffer[i*2+1] = intToHex((data[i] & 15));
|
||||
if (!buffer[i*2] || !buffer[i*2+1]) {
|
||||
delete [] buffer;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
buffer[length*2] = 0;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HexOutStream::writeBuffer() {
|
||||
U8* pos = start;
|
||||
while (pos != ptr) {
|
||||
out_stream.check(2);
|
||||
U8* optr = out_stream.getptr();
|
||||
U8* oend = out_stream.getend();
|
||||
int length = min(ptr-pos, (oend-optr)/2);
|
||||
|
||||
for (int i=0; i<length; i++) {
|
||||
optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
|
||||
optr[i*2+1] = intToHex(pos[i] & 0xf);
|
||||
}
|
||||
|
||||
out_stream.setptr(optr + length*2);
|
||||
pos += length;
|
||||
}
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int HexOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void
|
||||
HexOutStream::flush() {
|
||||
writeBuffer();
|
||||
out_stream.flush();
|
||||
}
|
||||
|
||||
int
|
||||
HexOutStream::overrun(int itemSize, int nItems) {
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("HexOutStream overrun: max itemSize exceeded");
|
||||
|
||||
writeBuffer();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
51
common/rdr/HexOutStream.h
Normal file
51
common/rdr/HexOutStream.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_HEX_OUTSTREAM_H__
|
||||
#define __RDR_HEX_OUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class HexOutStream : public OutStream {
|
||||
public:
|
||||
|
||||
HexOutStream(OutStream& os, int buflen=0);
|
||||
virtual ~HexOutStream();
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
static char intToHex(int i);
|
||||
static char* binToHexStr(const char* data, int length);
|
||||
|
||||
private:
|
||||
void writeBuffer();
|
||||
int overrun(int itemSize, int nItems);
|
||||
|
||||
OutStream& out_stream;
|
||||
|
||||
U8* start;
|
||||
int offset;
|
||||
int bufSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
35
common/rdr/InStream.cxx
Normal file
35
common/rdr/InStream.cxx
Normal file
@@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
U32 InStream::maxStringLength = 65535;
|
||||
|
||||
char* InStream::readString()
|
||||
{
|
||||
U32 len = readU32();
|
||||
if (len > maxStringLength)
|
||||
throw Exception("InStream max string length exceeded");
|
||||
char* str = new char[len+1];
|
||||
readBytes(str, len);
|
||||
str[len] = 0;
|
||||
return str;
|
||||
}
|
||||
147
common/rdr/InStream.h
Normal file
147
common/rdr/InStream.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::InStream marshalls data from a buffer stored in RDR (RFB Data
|
||||
// Representation).
|
||||
//
|
||||
|
||||
#ifndef __RDR_INSTREAM_H__
|
||||
#define __RDR_INSTREAM_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class InStream {
|
||||
|
||||
public:
|
||||
|
||||
virtual ~InStream() {}
|
||||
|
||||
// check() ensures there is buffer data for at least one item of size
|
||||
// itemSize bytes. Returns the number of items in the buffer (up to a
|
||||
// maximum of nItems). If wait is false, then instead of blocking to wait
|
||||
// for the bytes, zero is returned if the bytes are not immediately
|
||||
// available.
|
||||
|
||||
inline int check(int itemSize, int nItems=1, bool wait=true)
|
||||
{
|
||||
if (ptr + itemSize * nItems > end) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems, wait);
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// checkNoWait() tries to make sure that the given number of bytes can
|
||||
// be read without blocking. It returns true if this is the case, false
|
||||
// otherwise. The length must be "small" (less than the buffer size).
|
||||
|
||||
inline bool checkNoWait(int length) { return check(length, 1, false)!=0; }
|
||||
|
||||
// readU/SN() methods read unsigned and signed N-bit integers.
|
||||
|
||||
inline U8 readU8() { check(1); return *ptr++; }
|
||||
inline U16 readU16() { check(2); int b0 = *ptr++; int b1 = *ptr++;
|
||||
return b0 << 8 | b1; }
|
||||
inline U32 readU32() { check(4); int b0 = *ptr++; int b1 = *ptr++;
|
||||
int b2 = *ptr++; int b3 = *ptr++;
|
||||
return b0 << 24 | b1 << 16 | b2 << 8 | b3; }
|
||||
|
||||
inline S8 readS8() { return (S8) readU8(); }
|
||||
inline S16 readS16() { return (S16)readU16(); }
|
||||
inline S32 readS32() { return (S32)readU32(); }
|
||||
|
||||
// readString() reads a string - a U32 length followed by the data.
|
||||
// Returns a null-terminated string - the caller should delete[] it
|
||||
// afterwards.
|
||||
|
||||
char* readString();
|
||||
|
||||
// maxStringLength protects against allocating a huge buffer. Set it
|
||||
// higher if you need longer strings.
|
||||
|
||||
static U32 maxStringLength;
|
||||
|
||||
inline void skip(int bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// readBytes() reads an exact number of bytes.
|
||||
|
||||
void readBytes(void* data, int length) {
|
||||
U8* dataPtr = (U8*)data;
|
||||
U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(dataPtr, ptr, n);
|
||||
ptr += n;
|
||||
dataPtr += n;
|
||||
}
|
||||
}
|
||||
|
||||
// readOpaqueN() reads a quantity without byte-swapping.
|
||||
|
||||
inline U8 readOpaque8() { return readU8(); }
|
||||
inline U16 readOpaque16() { check(2); U16 r; ((U8*)&r)[0] = *ptr++;
|
||||
((U8*)&r)[1] = *ptr++; return r; }
|
||||
inline U32 readOpaque32() { check(4); U32 r; ((U8*)&r)[0] = *ptr++;
|
||||
((U8*)&r)[1] = *ptr++; ((U8*)&r)[2] = *ptr++;
|
||||
((U8*)&r)[3] = *ptr++; return r; }
|
||||
|
||||
// pos() returns the position in the stream.
|
||||
|
||||
virtual int pos() = 0;
|
||||
|
||||
// getptr(), getend() and setptr() are "dirty" methods which allow you to
|
||||
// manipulate the buffer directly. This is useful for a stream which is a
|
||||
// wrapper around an underlying stream.
|
||||
|
||||
inline const U8* getptr() const { return ptr; }
|
||||
inline const U8* getend() const { return end; }
|
||||
inline void setptr(const U8* p) { ptr = p; }
|
||||
|
||||
private:
|
||||
|
||||
// overrun() is implemented by a derived class to cope with buffer overrun.
|
||||
// It ensures there are at least itemSize bytes of buffer data. Returns
|
||||
// the number of items in the buffer (up to a maximum of nItems). itemSize
|
||||
// is supposed to be "small" (a few bytes). If wait is false, then
|
||||
// instead of blocking to wait for the bytes, zero is returned if the bytes
|
||||
// are not immediately available.
|
||||
|
||||
virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
InStream() {}
|
||||
const U8* ptr;
|
||||
const U8* end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
63
common/rdr/MemInStream.h
Normal file
63
common/rdr/MemInStream.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::MemInStream is an InStream which streams from a given memory buffer.
|
||||
// If the deleteWhenDone parameter is true then the buffer will be delete[]d in
|
||||
// the destructor. Note that it is delete[]d as a U8* - strictly speaking this
|
||||
// means it ought to be new[]ed as a U8* as well, but on most platforms this
|
||||
// doesn't matter.
|
||||
//
|
||||
|
||||
#ifndef __RDR_MEMINSTREAM_H__
|
||||
#define __RDR_MEMINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class MemInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
MemInStream(const void* data, int len, bool deleteWhenDone_=false)
|
||||
: start((const U8*)data), deleteWhenDone(deleteWhenDone_)
|
||||
{
|
||||
ptr = start;
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
virtual ~MemInStream() {
|
||||
if (deleteWhenDone)
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
int pos() { return ptr - start; }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); }
|
||||
const U8* start;
|
||||
bool deleteWhenDone;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
83
common/rdr/MemOutStream.h
Normal file
83
common/rdr/MemOutStream.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// A MemOutStream grows as needed when data is written to it.
|
||||
//
|
||||
|
||||
#ifndef __RDR_MEMOUTSTREAM_H__
|
||||
#define __RDR_MEMOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class MemOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
MemOutStream(int len=1024) {
|
||||
start = ptr = new U8[len];
|
||||
end = start + len;
|
||||
}
|
||||
|
||||
virtual ~MemOutStream() {
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void writeBytes(const void* data, int length) {
|
||||
check(length);
|
||||
memcpy(ptr, data, length);
|
||||
ptr += length;
|
||||
}
|
||||
|
||||
int length() { return ptr - start; }
|
||||
void clear() { ptr = start; };
|
||||
void clearAndZero() { memset(start, 0, ptr-start); clear(); }
|
||||
void reposition(int pos) { ptr = start + pos; }
|
||||
|
||||
// data() returns a pointer to the buffer.
|
||||
|
||||
const void* data() { return (const void*)start; }
|
||||
|
||||
protected:
|
||||
|
||||
// overrun() either doubles the buffer or adds enough space for nItems of
|
||||
// size itemSize bytes.
|
||||
|
||||
int overrun(int itemSize, int nItems) {
|
||||
int len = ptr - start + itemSize * nItems;
|
||||
if (len < (end - start) * 2)
|
||||
len = (end - start) * 2;
|
||||
|
||||
U8* newStart = new U8[len];
|
||||
memcpy(newStart, start, ptr - start);
|
||||
ptr = newStart + (ptr - start);
|
||||
delete [] start;
|
||||
start = newStart;
|
||||
end = newStart + len;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
U8* start;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
158
common/rdr/OutStream.h
Normal file
158
common/rdr/OutStream.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// rdr::OutStream marshalls data into a buffer stored in RDR (RFB Data
|
||||
// Representation).
|
||||
//
|
||||
|
||||
#ifndef __RDR_OUTSTREAM_H__
|
||||
#define __RDR_OUTSTREAM_H__
|
||||
|
||||
#include <rdr/types.h>
|
||||
#include <rdr/InStream.h>
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class OutStream {
|
||||
|
||||
protected:
|
||||
|
||||
OutStream() {}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~OutStream() {}
|
||||
|
||||
// check() ensures there is buffer space for at least one item of size
|
||||
// itemSize bytes. Returns the number of items which fit (up to a maximum
|
||||
// of nItems).
|
||||
|
||||
inline int check(int itemSize, int nItems=1)
|
||||
{
|
||||
if (ptr + itemSize * nItems > end) {
|
||||
if (ptr + itemSize > end)
|
||||
return overrun(itemSize, nItems);
|
||||
|
||||
nItems = (end - ptr) / itemSize;
|
||||
}
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// writeU/SN() methods write unsigned and signed N-bit integers.
|
||||
|
||||
inline void writeU8( U8 u) { check(1); *ptr++ = u; }
|
||||
inline void writeU16(U16 u) { check(2); *ptr++ = u >> 8; *ptr++ = (U8)u; }
|
||||
inline void writeU32(U32 u) { check(4); *ptr++ = u >> 24; *ptr++ = u >> 16;
|
||||
*ptr++ = u >> 8; *ptr++ = u; }
|
||||
|
||||
inline void writeS8( S8 s) { writeU8((U8)s); }
|
||||
inline void writeS16(S16 s) { writeU16((U16)s); }
|
||||
inline void writeS32(S32 s) { writeU32((U32)s); }
|
||||
|
||||
// writeString() writes a string - a U32 length followed by the data. The
|
||||
// given string should be null-terminated (but the terminating null is not
|
||||
// written to the stream).
|
||||
|
||||
inline void writeString(const char* str) {
|
||||
U32 len = strlen(str);
|
||||
writeU32(len);
|
||||
writeBytes(str, len);
|
||||
}
|
||||
|
||||
inline void pad(int bytes) {
|
||||
while (bytes-- > 0) writeU8(0);
|
||||
}
|
||||
|
||||
inline void skip(int bytes) {
|
||||
while (bytes > 0) {
|
||||
int n = check(1, bytes);
|
||||
ptr += n;
|
||||
bytes -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// writeBytes() writes an exact number of bytes.
|
||||
|
||||
void writeBytes(const void* data, int length) {
|
||||
const U8* dataPtr = (const U8*)data;
|
||||
const U8* dataEnd = dataPtr + length;
|
||||
while (dataPtr < dataEnd) {
|
||||
int n = check(1, dataEnd - dataPtr);
|
||||
memcpy(ptr, dataPtr, n);
|
||||
ptr += n;
|
||||
dataPtr += n;
|
||||
}
|
||||
}
|
||||
|
||||
// copyBytes() efficiently transfers data between streams
|
||||
|
||||
void copyBytes(InStream* is, int length) {
|
||||
while (length > 0) {
|
||||
int n = check(1, length);
|
||||
is->readBytes(ptr, n);
|
||||
ptr += n;
|
||||
length -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// writeOpaqueN() writes a quantity without byte-swapping.
|
||||
|
||||
inline void writeOpaque8( U8 u) { writeU8(u); }
|
||||
inline void writeOpaque16(U16 u) { check(2); *ptr++ = ((U8*)&u)[0];
|
||||
*ptr++ = ((U8*)&u)[1]; }
|
||||
inline void writeOpaque32(U32 u) { check(4); *ptr++ = ((U8*)&u)[0];
|
||||
*ptr++ = ((U8*)&u)[1];
|
||||
*ptr++ = ((U8*)&u)[2];
|
||||
*ptr++ = ((U8*)&u)[3]; }
|
||||
|
||||
// length() returns the length of the stream.
|
||||
|
||||
virtual int length() = 0;
|
||||
|
||||
// flush() requests that the stream be flushed.
|
||||
|
||||
virtual void flush() {}
|
||||
|
||||
// getptr(), getend() and setptr() are "dirty" methods which allow you to
|
||||
// manipulate the buffer directly. This is useful for a stream which is a
|
||||
// wrapper around an underlying stream.
|
||||
|
||||
inline U8* getptr() { return ptr; }
|
||||
inline U8* getend() { return end; }
|
||||
inline void setptr(U8* p) { ptr = p; }
|
||||
|
||||
private:
|
||||
|
||||
// overrun() is implemented by a derived class to cope with buffer overrun.
|
||||
// It ensures there are at least itemSize bytes of buffer space. Returns
|
||||
// the number of items which fit (up to a maximum of nItems). itemSize is
|
||||
// supposed to be "small" (a few bytes).
|
||||
|
||||
virtual int overrun(int itemSize, int nItems) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
U8* ptr;
|
||||
U8* end;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
130
common/rdr/RandomStream.cxx
Normal file
130
common/rdr/RandomStream.cxx
Normal file
@@ -0,0 +1,130 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <rdr/RandomStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#else
|
||||
#define getpid() GetCurrentProcessId()
|
||||
#ifndef RFB_HAVE_WINCRYPT
|
||||
#pragma message(" NOTE: Not building WinCrypt-based RandomStream")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
const int DEFAULT_BUF_LEN = 256;
|
||||
|
||||
unsigned int RandomStream::seed;
|
||||
|
||||
RandomStream::RandomStream()
|
||||
: offset(0)
|
||||
{
|
||||
ptr = end = start = new U8[DEFAULT_BUF_LEN];
|
||||
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
provider = 0;
|
||||
if (!CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, 0)) {
|
||||
if (GetLastError() == (DWORD)NTE_BAD_KEYSET) {
|
||||
if (!CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
|
||||
fprintf(stderr, "RandomStream: unable to create keyset\n");
|
||||
provider = 0;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "RandomStream: unable to acquire context\n");
|
||||
provider = 0;
|
||||
}
|
||||
}
|
||||
if (!provider) {
|
||||
#else
|
||||
#ifndef WIN32
|
||||
fp = fopen("/dev/urandom", "r");
|
||||
if (!fp)
|
||||
fp = fopen("/dev/random", "r");
|
||||
if (!fp) {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#endif
|
||||
fprintf(stderr,"RandomStream: warning: no OS supplied random source - using rand()\n");
|
||||
seed += (unsigned int) time(0) + getpid() + getpid() * 987654 + rand();
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
||||
RandomStream::~RandomStream() {
|
||||
delete [] start;
|
||||
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
if (provider)
|
||||
CryptReleaseContext(provider, 0);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
if (fp) fclose(fp);
|
||||
#endif
|
||||
}
|
||||
|
||||
int RandomStream::pos() {
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
int RandomStream::overrun(int itemSize, int nItems, bool wait) {
|
||||
if (itemSize > DEFAULT_BUF_LEN)
|
||||
throw Exception("RandomStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
end -= ptr - start;
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
|
||||
int length = start + DEFAULT_BUF_LEN - end;
|
||||
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
if (provider) {
|
||||
if (!CryptGenRandom(provider, length, (U8*)end))
|
||||
throw rdr::SystemException("unable to CryptGenRandom", GetLastError());
|
||||
end += length;
|
||||
} else {
|
||||
#else
|
||||
#ifndef WIN32
|
||||
if (fp) {
|
||||
int n = fread((U8*)end, length, 1, fp);
|
||||
if (n != 1)
|
||||
throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
|
||||
errno);
|
||||
end += length;
|
||||
} else {
|
||||
#else
|
||||
{
|
||||
#endif
|
||||
#endif
|
||||
for (int i=0; i<length; i++)
|
||||
*(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
63
common/rdr/RandomStream.h
Normal file
63
common/rdr/RandomStream.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_RANDOMSTREAM_H__
|
||||
#define __RDR_RANDOMSTREAM_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
#ifdef WINCRYPT32API
|
||||
#define RFB_HAVE_WINCRYPT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class RandomStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
RandomStream();
|
||||
virtual ~RandomStream();
|
||||
|
||||
int pos();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
|
||||
private:
|
||||
U8* start;
|
||||
int offset;
|
||||
|
||||
static unsigned int seed;
|
||||
#ifdef RFB_HAVE_WINCRYPT
|
||||
HCRYPTPROV provider;
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
FILE* fp;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
102
common/rdr/SubstitutingInStream.h
Normal file
102
common/rdr/SubstitutingInStream.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_SUBSTITUTINGINSTREAM_H__
|
||||
#define __RDR_SUBSTITUTINGINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class Substitutor {
|
||||
public:
|
||||
virtual char* substitute(const char* varName) = 0;
|
||||
};
|
||||
|
||||
class SubstitutingInStream : public InStream {
|
||||
public:
|
||||
SubstitutingInStream(InStream* underlying_, Substitutor* s,
|
||||
int maxVarNameLen_)
|
||||
: underlying(underlying_), dollar(0), substitutor(s), subst(0),
|
||||
maxVarNameLen(maxVarNameLen_)
|
||||
{
|
||||
ptr = end = underlying->getptr();
|
||||
varName = new char[maxVarNameLen+1];
|
||||
}
|
||||
~SubstitutingInStream() {
|
||||
delete underlying;
|
||||
delete [] varName;
|
||||
delete [] subst;
|
||||
}
|
||||
|
||||
int pos() { return underlying->pos(); }
|
||||
|
||||
virtual int overrun(int itemSize, int nItems, bool wait=true) {
|
||||
if (itemSize != 1)
|
||||
throw new rdr::Exception("SubstitutingInStream: itemSize must be 1");
|
||||
|
||||
if (subst) {
|
||||
delete [] subst;
|
||||
subst = 0;
|
||||
} else {
|
||||
underlying->setptr(ptr);
|
||||
}
|
||||
|
||||
underlying->check(1);
|
||||
ptr = underlying->getptr();
|
||||
end = underlying->getend();
|
||||
dollar = (const U8*)memchr(ptr, '$', end-ptr);
|
||||
if (dollar) {
|
||||
if (dollar == ptr) {
|
||||
try {
|
||||
int i = 0;
|
||||
while (i < maxVarNameLen) {
|
||||
varName[i++] = underlying->readS8();
|
||||
varName[i] = 0;
|
||||
subst = substitutor->substitute(varName);
|
||||
if (subst) {
|
||||
ptr = (U8*)subst;
|
||||
end = (U8*)subst + strlen(subst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (EndOfStream&) {
|
||||
}
|
||||
|
||||
if (!subst)
|
||||
dollar = (const U8*)memchr(ptr+1, '$', end-ptr-1);
|
||||
}
|
||||
if (!subst && dollar) end = dollar;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
InStream* underlying;
|
||||
const U8* dollar;
|
||||
Substitutor* substitutor;
|
||||
char* varName;
|
||||
char* subst;
|
||||
int maxVarNameLen;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
41
common/rdr/TLSException.cxx
Normal file
41
common/rdr/TLSException.cxx
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Red Hat Inc.
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/TLSException.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#endif
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
TLSException::TLSException(const char* s, int err_)
|
||||
: Exception("%s: %s (%d)", s, gnutls_strerror(err_), err_), err(err_)
|
||||
{
|
||||
}
|
||||
#endif /* HAVE_GNUTLS */
|
||||
|
||||
35
common/rdr/TLSException.h
Normal file
35
common/rdr/TLSException.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Red Hat Inc.
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_TLSEXCEPTION_H__
|
||||
#define __RDR_TLSEXCEPTION_H__
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
struct TLSException : public Exception {
|
||||
int err;
|
||||
TLSException(const char* s, int err_);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
125
common/rdr/TLSInStream.cxx
Normal file
125
common/rdr/TLSInStream.cxx
Normal file
@@ -0,0 +1,125 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2005 Martin Koegler
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
#include <rdr/TLSException.h>
|
||||
#include <rdr/TLSInStream.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ssize_t TLSInStream::pull(gnutls_transport_ptr_t str, void* data, size_t size)
|
||||
{
|
||||
TLSInStream* self= (TLSInStream*) str;
|
||||
InStream *in = self->in;
|
||||
|
||||
try {
|
||||
if (!in->check(1, 1, false)) {
|
||||
gnutls_transport_set_errno(self->session, EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in->getend() - in->getptr() < (ptrdiff_t)size)
|
||||
size = in->getend() - in->getptr();
|
||||
|
||||
in->readBytes(data, size);
|
||||
|
||||
} catch (Exception& e) {
|
||||
gnutls_transport_set_errno(self->session, EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
TLSInStream::TLSInStream(InStream* _in, gnutls_session_t _session)
|
||||
: session(_session), in(_in), bufSize(DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
gnutls_transport_ptr_t recv, send;
|
||||
|
||||
ptr = end = start = new U8[bufSize];
|
||||
|
||||
gnutls_transport_set_pull_function(session, pull);
|
||||
gnutls_transport_get_ptr2(session, &recv, &send);
|
||||
gnutls_transport_set_ptr2(session, this, send);
|
||||
}
|
||||
|
||||
TLSInStream::~TLSInStream()
|
||||
{
|
||||
gnutls_transport_set_pull_function(session, NULL);
|
||||
|
||||
delete[] start;
|
||||
}
|
||||
|
||||
int TLSInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
int TLSInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("TLSInStream overrun: max itemSize exceeded");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
offset += ptr - start;
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end < start + itemSize) {
|
||||
int n = readTLS((U8*) end, start + bufSize - end, wait);
|
||||
if (!wait && n == 0)
|
||||
return 0;
|
||||
end += n;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
int TLSInStream::readTLS(U8* buf, int len, bool wait)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = in->check(1, 1, wait);
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
n = gnutls_record_recv(session, (void *) buf, len);
|
||||
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
|
||||
return 0;
|
||||
|
||||
if (n < 0) throw TLSException("readTLS", n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
55
common/rdr/TLSInStream.h
Normal file
55
common/rdr/TLSInStream.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Copyright (C) 2005 Martin Koegler
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_TLSINSTREAM_H__
|
||||
#define __RDR_TLSINSTREAM_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class TLSInStream : public InStream {
|
||||
public:
|
||||
TLSInStream(InStream* in, gnutls_session_t session);
|
||||
virtual ~TLSInStream();
|
||||
|
||||
int pos();
|
||||
|
||||
private:
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
int readTLS(U8* buf, int len, bool wait);
|
||||
static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size);
|
||||
|
||||
gnutls_session_t session;
|
||||
InStream* in;
|
||||
int bufSize;
|
||||
int offset;
|
||||
U8* start;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
123
common/rdr/TLSOutStream.cxx
Normal file
123
common/rdr/TLSOutStream.cxx
Normal file
@@ -0,0 +1,123 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2005 Martin Koegler
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <rdr/Exception.h>
|
||||
#include <rdr/TLSException.h>
|
||||
#include <rdr/TLSOutStream.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ssize_t TLSOutStream::push(gnutls_transport_ptr_t str, const void* data,
|
||||
size_t size)
|
||||
{
|
||||
TLSOutStream* self= (TLSOutStream*) str;
|
||||
OutStream *out = self->out;
|
||||
|
||||
try {
|
||||
out->writeBytes(data, size);
|
||||
out->flush();
|
||||
} catch (Exception& e) {
|
||||
gnutls_transport_set_errno(self->session, EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
TLSOutStream::TLSOutStream(OutStream* _out, gnutls_session_t _session)
|
||||
: session(_session), out(_out), bufSize(DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
gnutls_transport_ptr_t recv, send;
|
||||
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
|
||||
gnutls_transport_set_push_function(session, push);
|
||||
gnutls_transport_get_ptr2(session, &recv, &send);
|
||||
gnutls_transport_set_ptr2(session, recv, this);
|
||||
}
|
||||
|
||||
TLSOutStream::~TLSOutStream()
|
||||
{
|
||||
#if 0
|
||||
try {
|
||||
// flush();
|
||||
} catch (Exception&) {
|
||||
}
|
||||
#endif
|
||||
gnutls_transport_set_push_function(session, NULL);
|
||||
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
int TLSOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void TLSOutStream::flush()
|
||||
{
|
||||
U8* sentUpTo = start;
|
||||
while (sentUpTo < ptr) {
|
||||
int n = writeTLS(sentUpTo, ptr - sentUpTo);
|
||||
sentUpTo += n;
|
||||
offset += n;
|
||||
}
|
||||
|
||||
ptr = start;
|
||||
out->flush();
|
||||
}
|
||||
|
||||
int TLSOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("TLSOutStream overrun: max itemSize exceeded");
|
||||
|
||||
flush();
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
int TLSOutStream::writeTLS(const U8* data, int length)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gnutls_record_send(session, data, length);
|
||||
if (n == GNUTLS_E_INTERRUPTED || n == GNUTLS_E_AGAIN)
|
||||
return 0;
|
||||
|
||||
if (n < 0)
|
||||
throw TLSException("writeTLS", n);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
57
common/rdr/TLSOutStream.h
Normal file
57
common/rdr/TLSOutStream.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* Copyright (C) 2005 Martin Koegler
|
||||
* Copyright (C) 2010 TigerVNC Team
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_TLSOUTSTREAM_H__
|
||||
#define __RDR_TLSOUTSTREAM_H__
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GNUTLS
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class TLSOutStream : public OutStream {
|
||||
public:
|
||||
TLSOutStream(OutStream* out, gnutls_session_t session);
|
||||
virtual ~TLSOutStream();
|
||||
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
protected:
|
||||
int overrun(int itemSize, int nItems);
|
||||
|
||||
private:
|
||||
int writeTLS(const U8* data, int length);
|
||||
static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size);
|
||||
|
||||
gnutls_session_t session;
|
||||
OutStream* out;
|
||||
int bufSize;
|
||||
U8* start;
|
||||
int offset;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
149
common/rdr/ZlibInStream.cxx
Normal file
149
common/rdr/ZlibInStream.cxx
Normal file
@@ -0,0 +1,149 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <rdr/ZlibInStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
#include <zlib.h>
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ZlibInStream::ZlibInStream(int bufSize_)
|
||||
: underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
|
||||
zs(NULL), bytesIn(0)
|
||||
{
|
||||
ptr = end = start = new U8[bufSize];
|
||||
init();
|
||||
}
|
||||
|
||||
ZlibInStream::~ZlibInStream()
|
||||
{
|
||||
deinit();
|
||||
delete [] start;
|
||||
}
|
||||
|
||||
void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
|
||||
{
|
||||
underlying = is;
|
||||
bytesIn = bytesIn_;
|
||||
ptr = end = start;
|
||||
}
|
||||
|
||||
int ZlibInStream::pos()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void ZlibInStream::removeUnderlying()
|
||||
{
|
||||
ptr = end = start;
|
||||
if (!underlying) return;
|
||||
|
||||
while (bytesIn > 0) {
|
||||
decompress(true);
|
||||
end = start; // throw away any data
|
||||
}
|
||||
underlying = 0;
|
||||
}
|
||||
|
||||
void ZlibInStream::reset()
|
||||
{
|
||||
deinit();
|
||||
init();
|
||||
}
|
||||
|
||||
void ZlibInStream::init()
|
||||
{
|
||||
assert(zs == NULL);
|
||||
|
||||
zs = new z_stream;
|
||||
zs->zalloc = Z_NULL;
|
||||
zs->zfree = Z_NULL;
|
||||
zs->opaque = Z_NULL;
|
||||
zs->next_in = Z_NULL;
|
||||
zs->avail_in = 0;
|
||||
if (inflateInit(zs) != Z_OK) {
|
||||
delete zs;
|
||||
zs = NULL;
|
||||
throw Exception("ZlibInStream: inflateInit failed");
|
||||
}
|
||||
}
|
||||
|
||||
void ZlibInStream::deinit()
|
||||
{
|
||||
assert(zs != NULL);
|
||||
removeUnderlying();
|
||||
inflateEnd(zs);
|
||||
delete zs;
|
||||
zs = NULL;
|
||||
}
|
||||
|
||||
int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
|
||||
{
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("ZlibInStream overrun: max itemSize exceeded");
|
||||
if (!underlying)
|
||||
throw Exception("ZlibInStream overrun: no underlying stream");
|
||||
|
||||
if (end - ptr != 0)
|
||||
memmove(start, ptr, end - ptr);
|
||||
|
||||
offset += ptr - start;
|
||||
end -= ptr - start;
|
||||
ptr = start;
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
if (!decompress(wait))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
// decompress() calls the decompressor once. Note that this won't necessarily
|
||||
// generate any output data - it may just consume some input data. Returns
|
||||
// false if wait is false and we would block on the underlying stream.
|
||||
|
||||
bool ZlibInStream::decompress(bool wait)
|
||||
{
|
||||
zs->next_out = (U8*)end;
|
||||
zs->avail_out = start + bufSize - end;
|
||||
|
||||
int n = underlying->check(1, 1, wait);
|
||||
if (n == 0) return false;
|
||||
zs->next_in = (U8*)underlying->getptr();
|
||||
zs->avail_in = underlying->getend() - underlying->getptr();
|
||||
if ((int)zs->avail_in > bytesIn)
|
||||
zs->avail_in = bytesIn;
|
||||
|
||||
int rc = inflate(zs, Z_SYNC_FLUSH);
|
||||
if (rc != Z_OK) {
|
||||
throw Exception("ZlibInStream: inflate failed");
|
||||
}
|
||||
|
||||
bytesIn -= zs->next_in - underlying->getptr();
|
||||
end = zs->next_out;
|
||||
underlying->setptr(zs->next_in);
|
||||
return true;
|
||||
}
|
||||
63
common/rdr/ZlibInStream.h
Normal file
63
common/rdr/ZlibInStream.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// ZlibInStream streams from a compressed data stream ("underlying"),
|
||||
// decompressing with zlib on the fly.
|
||||
//
|
||||
|
||||
#ifndef __RDR_ZLIBINSTREAM_H__
|
||||
#define __RDR_ZLIBINSTREAM_H__
|
||||
|
||||
#include <rdr/InStream.h>
|
||||
|
||||
struct z_stream_s;
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class ZlibInStream : public InStream {
|
||||
|
||||
public:
|
||||
|
||||
ZlibInStream(int bufSize=0);
|
||||
virtual ~ZlibInStream();
|
||||
|
||||
void setUnderlying(InStream* is, int bytesIn);
|
||||
void removeUnderlying();
|
||||
int pos();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
int overrun(int itemSize, int nItems, bool wait);
|
||||
bool decompress(bool wait);
|
||||
|
||||
InStream* underlying;
|
||||
int bufSize;
|
||||
int offset;
|
||||
z_stream_s* zs;
|
||||
int bytesIn;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
201
common/rdr/ZlibOutStream.cxx
Normal file
201
common/rdr/ZlibOutStream.cxx
Normal file
@@ -0,0 +1,201 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <rdr/ZlibOutStream.h>
|
||||
#include <rdr/Exception.h>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#undef ZLIBOUT_DEBUG
|
||||
|
||||
using namespace rdr;
|
||||
|
||||
enum { DEFAULT_BUF_SIZE = 16384 };
|
||||
|
||||
ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
|
||||
: underlying(os), compressionLevel(compressLevel), newLevel(compressLevel),
|
||||
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
|
||||
{
|
||||
zs = new z_stream;
|
||||
zs->zalloc = Z_NULL;
|
||||
zs->zfree = Z_NULL;
|
||||
zs->opaque = Z_NULL;
|
||||
zs->next_in = Z_NULL;
|
||||
zs->avail_in = 0;
|
||||
if (deflateInit(zs, compressLevel) != Z_OK) {
|
||||
delete zs;
|
||||
throw Exception("ZlibOutStream: deflateInit failed");
|
||||
}
|
||||
ptr = start = new U8[bufSize];
|
||||
end = start + bufSize;
|
||||
}
|
||||
|
||||
ZlibOutStream::~ZlibOutStream()
|
||||
{
|
||||
try {
|
||||
flush();
|
||||
} catch (Exception&) {
|
||||
}
|
||||
delete [] start;
|
||||
deflateEnd(zs);
|
||||
delete zs;
|
||||
}
|
||||
|
||||
void ZlibOutStream::setUnderlying(OutStream* os)
|
||||
{
|
||||
underlying = os;
|
||||
}
|
||||
|
||||
void ZlibOutStream::setCompressionLevel(int level)
|
||||
{
|
||||
if (level < -1 || level > 9)
|
||||
level = -1; // Z_DEFAULT_COMPRESSION
|
||||
|
||||
newLevel = level;
|
||||
}
|
||||
|
||||
int ZlibOutStream::length()
|
||||
{
|
||||
return offset + ptr - start;
|
||||
}
|
||||
|
||||
void ZlibOutStream::flush()
|
||||
{
|
||||
checkCompressionLevel();
|
||||
|
||||
zs->next_in = start;
|
||||
zs->avail_in = ptr - start;
|
||||
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos flush: avail_in %d\n",zs->avail_in);
|
||||
#endif
|
||||
|
||||
// Force out everything from the zlib encoder
|
||||
deflate(Z_SYNC_FLUSH);
|
||||
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
}
|
||||
|
||||
int ZlibOutStream::overrun(int itemSize, int nItems)
|
||||
{
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos overrun\n");
|
||||
#endif
|
||||
|
||||
if (itemSize > bufSize)
|
||||
throw Exception("ZlibOutStream overrun: max itemSize exceeded");
|
||||
|
||||
checkCompressionLevel();
|
||||
|
||||
while (end - ptr < itemSize) {
|
||||
zs->next_in = start;
|
||||
zs->avail_in = ptr - start;
|
||||
|
||||
deflate(Z_NO_FLUSH);
|
||||
|
||||
// output buffer not full
|
||||
|
||||
if (zs->avail_in == 0) {
|
||||
offset += ptr - start;
|
||||
ptr = start;
|
||||
} else {
|
||||
// but didn't consume all the data? try shifting what's left to the
|
||||
// start of the buffer.
|
||||
fprintf(stderr,"z out buf not full, but in data not consumed\n");
|
||||
memmove(start, zs->next_in, ptr - zs->next_in);
|
||||
offset += zs->next_in - start;
|
||||
ptr -= zs->next_in - start;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSize * nItems > end - ptr)
|
||||
nItems = (end - ptr) / itemSize;
|
||||
|
||||
return nItems;
|
||||
}
|
||||
|
||||
void ZlibOutStream::deflate(int flush)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!underlying)
|
||||
throw Exception("ZlibOutStream: underlying OutStream has not been set");
|
||||
|
||||
if ((flush == Z_NO_FLUSH) && (zs->avail_in == 0))
|
||||
return;
|
||||
|
||||
do {
|
||||
underlying->check(1);
|
||||
zs->next_out = underlying->getptr();
|
||||
zs->avail_out = underlying->getend() - underlying->getptr();
|
||||
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos: calling deflate, avail_in %d, avail_out %d\n",
|
||||
zs->avail_in,zs->avail_out);
|
||||
#endif
|
||||
|
||||
rc = ::deflate(zs, flush);
|
||||
if (rc != Z_OK) {
|
||||
// Silly zlib returns an error if you try to flush something twice
|
||||
if ((rc == Z_BUF_ERROR) && (flush != Z_NO_FLUSH))
|
||||
break;
|
||||
|
||||
throw Exception("ZlibOutStream: deflate failed");
|
||||
}
|
||||
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos: after deflate: %d bytes\n",
|
||||
zs->next_out-underlying->getptr());
|
||||
#endif
|
||||
|
||||
underlying->setptr(zs->next_out);
|
||||
} while (zs->avail_out == 0);
|
||||
}
|
||||
|
||||
void ZlibOutStream::checkCompressionLevel()
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (newLevel != compressionLevel) {
|
||||
#ifdef ZLIBOUT_DEBUG
|
||||
fprintf(stderr,"zos change: avail_in %d\n",zs->avail_in);
|
||||
#endif
|
||||
|
||||
// zlib is just horribly stupid. It does an implicit flush on
|
||||
// parameter changes, but the flush it does is not one that forces
|
||||
// out all the data. And since you cannot flush things again, we
|
||||
// cannot force out our data after the parameter change. Hence we
|
||||
// need to do a more proper flush here first.
|
||||
deflate(Z_SYNC_FLUSH);
|
||||
|
||||
rc = deflateParams (zs, newLevel, Z_DEFAULT_STRATEGY);
|
||||
if (rc != Z_OK) {
|
||||
// The implicit flush can result in this error, caused by the
|
||||
// explicit flush we did above. It should be safe to ignore though
|
||||
// as the first flush should have left things in a stable state...
|
||||
if (rc != Z_BUF_ERROR)
|
||||
throw Exception("ZlibOutStream: deflateParams failed");
|
||||
}
|
||||
|
||||
compressionLevel = newLevel;
|
||||
}
|
||||
}
|
||||
63
common/rdr/ZlibOutStream.h
Normal file
63
common/rdr/ZlibOutStream.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
* Copyright (C) 2011 D. R. Commander. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
//
|
||||
// ZlibOutStream streams to a compressed data stream (underlying), compressing
|
||||
// with zlib on the fly.
|
||||
//
|
||||
|
||||
#ifndef __RDR_ZLIBOUTSTREAM_H__
|
||||
#define __RDR_ZLIBOUTSTREAM_H__
|
||||
|
||||
#include <rdr/OutStream.h>
|
||||
|
||||
struct z_stream_s;
|
||||
|
||||
namespace rdr {
|
||||
|
||||
class ZlibOutStream : public OutStream {
|
||||
|
||||
public:
|
||||
|
||||
ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
|
||||
virtual ~ZlibOutStream();
|
||||
|
||||
void setUnderlying(OutStream* os);
|
||||
void setCompressionLevel(int level=-1);
|
||||
void flush();
|
||||
int length();
|
||||
|
||||
private:
|
||||
|
||||
int overrun(int itemSize, int nItems);
|
||||
void deflate(int flush);
|
||||
void checkCompressionLevel();
|
||||
|
||||
OutStream* underlying;
|
||||
int compressionLevel;
|
||||
int newLevel;
|
||||
int bufSize;
|
||||
int offset;
|
||||
z_stream_s* zs;
|
||||
U8* start;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
77
common/rdr/types.h
Normal file
77
common/rdr/types.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
|
||||
*
|
||||
* This is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef __RDR_TYPES_H__
|
||||
#define __RDR_TYPES_H__
|
||||
|
||||
namespace rdr {
|
||||
|
||||
typedef unsigned char U8;
|
||||
typedef unsigned short U16;
|
||||
typedef unsigned int U32;
|
||||
typedef unsigned long long U64;
|
||||
typedef signed char S8;
|
||||
typedef signed short S16;
|
||||
typedef signed int S32;
|
||||
|
||||
class U8Array {
|
||||
public:
|
||||
U8Array() : buf(0) {}
|
||||
U8Array(U8* a) : buf(a) {} // note: assumes ownership
|
||||
U8Array(int len) : buf(new U8[len]) {}
|
||||
~U8Array() { delete [] buf; }
|
||||
|
||||
// Get the buffer pointer & clear it (i.e. caller takes ownership)
|
||||
U8* takeBuf() { U8* tmp = buf; buf = 0; return tmp; }
|
||||
|
||||
U8* buf;
|
||||
};
|
||||
|
||||
class U16Array {
|
||||
public:
|
||||
U16Array() : buf(0) {}
|
||||
U16Array(U16* a) : buf(a) {} // note: assumes ownership
|
||||
U16Array(int len) : buf(new U16[len]) {}
|
||||
~U16Array() { delete [] buf; }
|
||||
U16* takeBuf() { U16* tmp = buf; buf = 0; return tmp; }
|
||||
U16* buf;
|
||||
};
|
||||
|
||||
class U32Array {
|
||||
public:
|
||||
U32Array() : buf(0) {}
|
||||
U32Array(U32* a) : buf(a) {} // note: assumes ownership
|
||||
U32Array(int len) : buf(new U32[len]) {}
|
||||
~U32Array() { delete [] buf; }
|
||||
U32* takeBuf() { U32* tmp = buf; buf = 0; return tmp; }
|
||||
U32* buf;
|
||||
};
|
||||
|
||||
class S32Array {
|
||||
public:
|
||||
S32Array() : buf(0) {}
|
||||
S32Array(S32* a) : buf(a) {} // note: assumes ownership
|
||||
S32Array(int len) : buf(new S32[len]) {}
|
||||
~S32Array() { delete [] buf; }
|
||||
S32* takeBuf() { S32* tmp = buf; buf = 0; return tmp; }
|
||||
S32* buf;
|
||||
};
|
||||
|
||||
} // end of namespace rdr
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user