Commit 3e924126 authored by Reinhard Tartler's avatar Reinhard Tartler

Imported nxcomp-3.1.0-4.tar.gz

Summary: Imported nxcomp-3.1.0-4.tar.gz Keywords: Imported nxcomp-3.1.0-4.tar.gz into Git repository
parent a840692e
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "Control.h"
#include "ActionCache.h"
ActionCache::ActionCache()
{
for (int i = 0; i < 256; i++)
{
base_[i] = new IntCache(8);
}
slot_ = 0;
last_ = 0;
}
ActionCache::~ActionCache()
{
for (int i = 0; i < 256; i++)
{
delete base_[i];
}
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ActionCache_H
#define ActionCache_H
#include "IntCache.h"
class ActionCache
{
friend class EncodeBuffer;
friend class DecodeBuffer;
public:
ActionCache();
~ActionCache();
private:
IntCache *base_[256];
unsigned int slot_;
unsigned short last_;
};
#endif /* ActionCache_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ActionCacheCompat_H
#define ActionCacheCompat_H
#include "CharCache.h"
class ActionCacheCompat
{
friend class EncodeBuffer;
friend class DecodeBuffer;
public:
ActionCacheCompat()
{
slot_ = 0;
}
~ActionCacheCompat()
{
}
private:
CharCache base_[4];
unsigned char slot_;
};
#endif /* ActionCacheCompat_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "Misc.h"
#include "Agent.h"
#include "Proxy.h"
extern Proxy *proxy;
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
Agent::Agent(int fd[2])
{
remoteFd_ = fd[0];
localFd_ = fd[1];
transport_ = new AgentTransport(localFd_);
if (transport_ == NULL)
{
#ifdef PANIC
*logofs << "Agent: PANIC! Can't create the memory-to-memory transport "
<< "for FD#" << localFd_ << ".\n" << logofs_flush;
#endif
cerr << "Error" << ": Can't create the memory-to-memory transport "
<< "for FD#" << localFd_ << ".\n";
HandleCleanup();
}
FD_ZERO(&saveRead_);
FD_ZERO(&saveWrite_);
canRead_ = 0;
#ifdef DEBUG
*logofs << "Agent: Created agent object at " << this
<< ".\n" << logofs_flush;
#endif
}
Agent::~Agent()
{
delete transport_;
#ifdef DEBUG
*logofs << "Agent: Deleted agent object at " << this
<< ".\n" << logofs_flush;
#endif
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef Agent_H
#define Agent_H
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/select.h>
#include "Misc.h"
#include "Transport.h"
#include "Proxy.h"
extern Proxy *proxy;
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
class Agent
{
public:
//
// Must be created by passing the fake descriptor that
// will be used for simulating socket communication
// betwen the agent and the proxy. I/O will take place
// by copying data to the agent's read and write buf-
// fers.
//
Agent(int fd[2]);
~Agent();
AgentTransport *getTransport() const
{
return transport_;
}
void saveReadMask(fd_set *readSet)
{
saveRead_ = *readSet;
}
void saveWriteMask(fd_set *writeSet)
{
saveWrite_ = *writeSet;
}
void clearReadMask(fd_set *readSet)
{
FD_CLR(remoteFd_, readSet);
FD_CLR(localFd_, readSet);
}
void clearWriteMask(fd_set *writeSet)
{
FD_CLR(remoteFd_, writeSet);
FD_CLR(localFd_, writeSet);
}
void setLocalRead(fd_set *readSet, int *result)
{
(*result)++;
FD_SET(localFd_, readSet);
}
void setRemoteRead(fd_set *readSet, int *result)
{
(*result)++;
FD_SET(remoteFd_, readSet);
}
void setRemoteWrite(fd_set *writeSet, int *result)
{
(*result)++;
FD_SET(remoteFd_, writeSet);
}
fd_set *getSavedReadMask()
{
return &saveRead_;
}
fd_set *getSavedWriteMask()
{
return &saveWrite_;
}
int getRemoteFd() const
{
return remoteFd_;
}
int getLocalFd() const
{
return localFd_;
}
int getProxyFd() const
{
return proxy -> getFd();
}
int isValid() const
{
return (transport_ != NULL);
}
int localReadable()
{
return (transport_ -> readable() != 0);
}
//
// Check if we can process more data from
// the agent descriptor and cache the result
// to avoid multiple calls. This must be
// always called before querying the other
// functions.
//
void saveChannelState()
{
canRead_ = (proxy != NULL ? proxy -> canRead(localFd_) : 0);
}
int remoteCanRead(const fd_set * const readSet)
{
#if defined(TEST) || defined(INFO)
*logofs << "Agent: remoteCanRead() is " <<
(FD_ISSET(remoteFd_, readSet) && transport_ -> dequeuable() != 0)
<< " with FD_ISSET() " << (int) FD_ISSET(remoteFd_, readSet)
<< " and dequeuable " << transport_ -> dequeuable()
<< ".\n" << logofs_flush;
#endif
return (FD_ISSET(remoteFd_, readSet) &&
transport_ -> dequeuable() != 0);
}
int remoteCanWrite(const fd_set * const writeSet)
{
#if defined(TEST) || defined(INFO)
*logofs << "Agent: remoteCanWrite() is " <<
(FD_ISSET(remoteFd_, writeSet) && transport_ ->
queuable() != 0 && canRead_ == 1) << " with FD_ISSET() "
<< (int) FD_ISSET(remoteFd_, writeSet) << " queueable "
<< transport_ -> queuable() << " channel can read "
<< canRead_ << ".\n" << logofs_flush;
#endif
return (FD_ISSET(remoteFd_, writeSet) &&
transport_ -> queuable() != 0 &&
canRead_ == 1);
}
int localCanRead()
{
#if defined(TEST) || defined(INFO)
*logofs << "Agent: localCanRead() is " <<
(transport_ -> readable() != 0 && canRead_ == 1)
<< " with readable " << transport_ -> readable()
<< " channel can read " << canRead_ << ".\n"
<< logofs_flush;
#endif
return (transport_ -> readable() != 0 &&
canRead_ == 1);
}
int proxyCanRead()
{
#if defined(TEST) || defined(INFO)
*logofs << "Agent: proxyCanRead() is " << proxy -> canRead()
<< ".\n" << logofs_flush;
#endif
return (proxy -> canRead());
}
int proxyCanRead(const fd_set * const readSet)
{
#if defined(TEST) || defined(INFO)
*logofs << "Agent: proxyCanRead() is "
<< ((int) FD_ISSET(proxy -> getFd(), readSet)
<< ".\n" << logofs_flush;
#endif
return (FD_ISSET(proxy -> getFd(), readSet));
}
int enqueueData(const char *data, const int size) const
{
return transport_ -> enqueue(data, size);
}
int dequeueData(char *data, int size) const
{
return transport_ -> dequeue(data, size);
}
int dequeuableData() const
{
return transport_ -> dequeuable();
}
private:
int remoteFd_;
int localFd_;
fd_set saveRead_;
fd_set saveWrite_;
int canRead_;
AgentTransport *transport_;
};
#endif /* Agent_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "Misc.h"
#include "Unpack.h"
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size,
unsigned char *dst_data, int dst_size)
{
if (*src_data == 0)
{
if (dst_size != src_size - 1)
{
#ifdef TEST
*logofs << "UnpackAlpha: PANIC! Invalid destination size "
<< dst_size << " with source " << src_size
<< ".\n" << logofs_flush;
#endif
return -1;
}
#ifdef TEST
*logofs << "UnpackAlpha: Expanding " << src_size - 1
<< " bytes of plain alpha data.\n" << logofs_flush;
#endif
memcpy(dst_data, src_data + 1, src_size - 1);
return 1;
}
unsigned int check_size = dst_size;
int result = ZDecompress(&unpackStream, dst_data, &check_size,
src_data + 1, src_size - 1);
if (result != Z_OK)
{
#ifdef PANIC
*logofs << "UnpackAlpha: PANIC! Failure decompressing alpha data. "
<< "Error is '" << zError(result) << "'.\n"
<< logofs_flush;
#endif
cerr << "Error" << ": Failure decompressing alpha data. "
<< "Error is '" << zError(result) << "'.\n";
return -1;
}
else if (check_size != (unsigned int) dst_size)
{
#ifdef PANIC
*logofs << "UnpackAlpha: PANIC! Size mismatch in alpha data. "
<< "Resulting size is " << check_size << " with "
<< "expected size " << dst_size << ".\n"
<< logofs_flush;
#endif
cerr << "Error" << ": Size mismatch in alpha data. "
<< "Resulting size is " << check_size << " with "
<< "expected size " << dst_size << ".\n";
return -1;
}
#ifdef TEST
*logofs << "UnpackAlpha: Decompressed " << src_size - 1
<< " bytes to " << dst_size << " bytes of alpha data.\n"
<< logofs_flush;
#endif
return 1;
}
int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data,
int dst_size, int big_endian)
{
unsigned int count = dst_size >> 2;
unsigned int i;
int shift;
if (count != alpha -> entries)
{
#ifdef WARNING
*logofs << "UnpackAlpha: WARNING! Not applying the alpha with "
<< count << " elements needed and " << alpha -> entries
<< " available.\n" << logofs_flush;
#endif
return 0;
}
shift = (big_endian == 1 ? 0 : 3);
for (i = 0; i < count; i++)
{
*(dst_data + shift) = *(alpha -> data + i);
dst_data += 4;
}
return 1;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef Alpha_H
#define Alpha_H
int UnpackAlpha(unsigned char method, unsigned char *src_data, int src_size,
unsigned char *dst_data, int dst_size);
int UnpackAlpha(T_alpha *alpha, unsigned char *dst_data,
int dst_size, int big_endian);
#endif /* Aplha_H */
This diff is collapsed. Click to expand it.
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef Auth_H
#define Auth_H
#include "Timestamp.h"
//
// Handle the forwarding of authorization credentials
// to the X server by replacing the fake cookie with
// the real cookie as it is read from the auth file.
// At the moment only the MIT-MAGIC-COOKIE-1 cookies
// are recognized. The implementation is based on the
// corresponding code found in the SSH client.
//
class Auth
{
public:
//
// Must be created by passing the fake cookie that
// will be forwarded by the remote end and with the
// real X display that is going to be used for the
// session.
//
Auth(char *display, char *cookie);
~Auth();
int isValid()
{
return (isTimestamp(last_) == 1 && fakeCookie_ != NULL &&
*fakeCookie_ != '\0' && realCookie_ != NULL &&
*realCookie_ != '\0' && fakeData_ != NULL &&
realData_ != NULL && dataSize_ != 0);
}
//
// Method called in the channel class to find if the
// provided cookie matches the fake one. If the data
// matches, the fake cookie is replaced with the real
// one.
//
int checkCookie(unsigned char *buffer);
protected:
//
// Update the real cookie for the display. If called
// a further time, check if the auth file is changed
// and get the new cookie.
//
int updateCookie();
//
// Find out which authorization file is to be used
// and query the cookie for the current display.
//
int getCookie();
//
// Extract the binary data from the cookies so that
// data can be directly compared at the time it is
// taken from the X request.
//
int validateCookie();
//
// Generate a fake random cookie and copy it to the
// provided string.
//
void generateCookie(char *cookie);
private:
char *display_;
char *file_;
T_timestamp last_;
char *fakeCookie_;
char *realCookie_;
char *fakeData_;
char *realData_;
int dataSize_;
};
#endif /* Auth_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "Misc.h"
#include "Bitmap.h"
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
int UnpackBitmap(T_geometry *geometry, unsigned char method, unsigned char *src_data,
int src_size, int dst_bpp, int dst_width, int dst_height,
unsigned char *dst_data, int dst_size)
{
if (dst_bpp != 32)
{
#ifdef TEST
*logofs << "UnpackBitmap: Nothing to do with "
<< "image of " << dst_bpp << " bits per plane "
<< "and size " << src_size << ".\n"
<< logofs_flush;
#endif
if (src_size != dst_size)
{
#ifdef PANIC
*logofs << "UnpackBitmap: PANIC! Size mismatch with "
<< src_size << " bytes in the source and "
<< dst_size << " in the destination.\n"
<< logofs_flush;
#endif
return -1;
}
memcpy(dst_data, src_data, src_size);
return 1;
}
else if (src_size != dst_width * dst_height * 3 ||
dst_size != dst_width * dst_height * 4)
{
#ifdef PANIC
*logofs << "UnpackBitmap: PANIC! Size mismatch with "
<< src_size << " bytes in the source and "
<< dst_size << " in the destination.\n"
<< logofs_flush;
#endif
return -1;
}
/*
* Insert the 4th byte in the bitmap.
*/
unsigned char *next_src = src_data;
unsigned char *next_dst = dst_data;
if (geometry -> image_byte_order == LSBFirst)
{
while (next_src < src_data + src_size)
{
*next_dst++ = *next_src++;
*next_dst++ = *next_src++;
*next_dst++ = *next_src++;
next_dst++;
}
}
else
{
while (next_src < src_data + src_size)
{
next_dst++;
*next_dst++ = *next_src++;
*next_dst++ = *next_src++;
*next_dst++ = *next_src++;
}
}
#ifdef TEST
*logofs << "UnpackBitmap: Unpacked " << src_size
<< " bytes to a buffer of " << dst_size
<< " with " << dst_bpp << " bits per plane.\n"
<< logofs_flush;
#endif
return 1;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef Bitmap_H
#define Bitmap_H
#include "Unpack.h"
int UnpackBitmap(T_geometry *geometry, unsigned char method,
unsigned char *src_data, int src_size, int dst_bpp,
int dst_width, int dst_height, unsigned char *dst_data,
int dst_size);
#endif /* Bitmap_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include <string.h>
#include "BlockCache.h"
int BlockCache::compare(unsigned int size, const unsigned char *data,
int overwrite)
{
int match = 0;
if (size == size_)
{
match = 1;
for (unsigned int i = 0; i < size_; i++)
if (data[i] != buffer_[i])
{
match = 0;
break;
}
}
if (!match && overwrite)
set(size, data);
return match;
}
void BlockCache::set(unsigned int size, const unsigned char *data)
{
if (size_ < size)
{
delete[]buffer_;
buffer_ = new unsigned char[size];
}
size_ = size;
memcpy(buffer_, data, size);
checksum_ = checksum(size, data);
}
unsigned int BlockCache::checksum(unsigned int size, const unsigned char *data)
{
unsigned int sum = 0;
unsigned int shift = 0;
const unsigned char *next = data;
for (unsigned int i = 0; i < size; i++)
{
unsigned int value = (unsigned int) *next++;
sum += (value << shift);
shift++;
if (shift == 8)
shift = 0;
}
return sum;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef BlockCache_H
#define BlockCache_H
// Cache to hold an arbitrary-length block of bytes
class BlockCache
{
public:
BlockCache():buffer_(0), size_(0), checksum_(0)
{
}
~BlockCache()
{
delete[]buffer_;
}
int compare(unsigned int size, const unsigned char *data,
int overwrite = 1);
void set(unsigned int size, const unsigned char *data);
unsigned int getLength() const
{
return size_;
}
unsigned int getChecksum() const
{
return checksum_;
}
const unsigned char *getData() const
{
return buffer_;
}
static unsigned int checksum(unsigned int size, const unsigned char *data);
private:
unsigned char *buffer_;
unsigned int size_;
unsigned int checksum_;
};
#endif /* BlockCache_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include <iostream.h>
#include "BlockCacheSet.h"
BlockCacheSet::BlockCacheSet(unsigned int numCaches):
caches_(new BlockCache *[numCaches]), size_(numCaches),
length_(0)
{
for (unsigned int i = 0; i < numCaches; i++)
caches_[i] = new BlockCache();
}
BlockCacheSet::~BlockCacheSet()
{
//
// TODO: There is still a strange segfault occurring
// at random time under Cygwin, when proxy is being
// shutdown. Problem appeared just after upgrading
// to the latest version of the Cygwin DLL. A stack
// trace, obtained at the last minute, reveals that
// failure happens in this destructor.
//
#ifndef __CYGWIN32__
for (unsigned int i = 0; i < size_; i++)
delete caches_[i];
delete[]caches_;
#endif /* ifdef __CYGWIN32__ */
}
int
BlockCacheSet::lookup(unsigned int dataLength, const unsigned char *data,
unsigned int &index)
{
unsigned int checksum = BlockCache::checksum(dataLength, data);
for (unsigned int i = 0; i < length_; i++)
if ((caches_[i]->getChecksum() == checksum) &&
(caches_[i]->compare(dataLength, data, 0)))
{
// match
index = i;
if (i)
{
BlockCache *save = caches_[i];
unsigned int target = (i >> 1);
do
{
caches_[i] = caches_[i - 1];
i--;
}
while (i > target);
caches_[target] = save;
}
return 1;
}
// no match
unsigned int insertionPoint = (length_ >> 1);
unsigned int start;
if (length_ >= size_)
start = size_ - 1;
else
{
start = length_;
length_++;
}
BlockCache *save = caches_[start];
for (unsigned int k = start; k > insertionPoint; k--)
caches_[k] = caches_[k - 1];
caches_[insertionPoint] = save;
save->set(dataLength, data);
return 0;
}
void
BlockCacheSet::get(unsigned index, unsigned int &size,
const unsigned char *&data)
{
size = caches_[index]->getLength();
data = caches_[index]->getData();
if (index)
{
BlockCache *save = caches_[index];
unsigned int target = (index >> 1);
do
{
caches_[index] = caches_[index - 1];
index--;
}
while (index > target);
caches_[target] = save;
}
}
void
BlockCacheSet::set(unsigned int dataLength, const unsigned char *data)
{
unsigned int insertionPoint = (length_ >> 1);
unsigned int start;
if (length_ >= size_)
start = size_ - 1;
else
{
start = length_;
length_++;
}
BlockCache *save = caches_[start];
for (unsigned int k = start; k > insertionPoint; k--)
caches_[k] = caches_[k - 1];
caches_[insertionPoint] = save;
save->set(dataLength, data);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef BlockCacheSet_H
#define BlockCacheSet_H
#include "BlockCache.h"
class BlockCacheSet
{
public:
BlockCacheSet(unsigned int numCaches);
~BlockCacheSet();
int lookup(unsigned int size, const unsigned char *data,
unsigned int &index);
void get(unsigned int index, unsigned int &size, const unsigned char *&data);
void set(unsigned int size, const unsigned char *data);
private:
BlockCache ** caches_;
unsigned int size_;
unsigned int length_;
};
#endif /* BlockCacheSet_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ChangeGC.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Here are the methods to handle messages' content.
//
int ChangeGCStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangeGCMessage *changeGC = (ChangeGCMessage *) message;
//
// Here is the fingerprint.
//
changeGC -> gcontext = GetULONG(buffer + 4, bigEndian);
changeGC -> value_mask = GetULONG(buffer + 8, bigEndian);
//
// Clear the unused bytes carried in the
// payload to increase the effectiveness
// of the caching algorithm.
//
if ((int) size > dataOffset)
{
#ifdef DEBUG
*logofs << name() << ": Removing unused bytes from the "
<< "data payload.\n" << logofs_flush;
#endif
changeGC -> value_mask &= (1 << 23) - 1;
unsigned int mask = 0x1;
unsigned char *source = (unsigned char *) buffer + CHANGEGC_DATA_OFFSET;
unsigned long value = 0;
for (unsigned int i = 0; i < 23; i++)
{
if (changeGC -> value_mask & mask)
{
value = GetULONG(source, bigEndian);
value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i]));
PutULONG(value, source, bigEndian);
source += 4;
}
mask <<= 1;
}
}
#ifdef DEBUG
*logofs << name() << ": Parsed Identity for message at "
<< this << ".\n" << logofs_flush;
#endif
return 1;
}
int ChangeGCStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangeGCMessage *changeGC = (ChangeGCMessage *) message;
//
// Fill all the message's fields.
//
PutULONG(changeGC -> gcontext, buffer + 4, bigEndian);
PutULONG(changeGC -> value_mask, buffer + 8, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at "
<< this << ".\n" << logofs_flush;
#endif
return 1;
}
void ChangeGCStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
ChangeGCMessage *changeGC = (ChangeGCMessage *) message;
*logofs << name() << ": Identity gcontext " << changeGC -> gcontext
<< ", mask " << changeGC -> value_mask << ", size "
<< changeGC -> size_ << ".\n" << logofs_flush;
#endif
}
void ChangeGCStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
/*
md5_append(md5_state_, buffer + 4, 8);
*/
md5_append(md5_state_, buffer + 8, 4);
}
void ChangeGCStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const
{
ChangeGCMessage *changeGC = (ChangeGCMessage *) message;
ChangeGCMessage *cachedChangeGC = (ChangeGCMessage *) cachedMessage;
ClientCache *clientCache = (ClientCache *) channelCache;
#ifdef TEST
*logofs << name() << ": Encoding value " << changeGC -> gcontext
<< " as gcontext field.\n" << logofs_flush;
#endif
encodeBuffer.encodeXidValue(changeGC -> gcontext, clientCache -> gcCache);
cachedChangeGC -> gcontext = changeGC -> gcontext;
}
void ChangeGCStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const
{
ChangeGCMessage *changeGC = (ChangeGCMessage *) message;
ClientCache *clientCache = (ClientCache *) channelCache;
unsigned int value;
decodeBuffer.decodeXidValue(value, clientCache -> gcCache);
changeGC -> gcontext = value;
#ifdef DEBUG
*logofs << name() << ": Decoded value " << changeGC -> gcontext
<< " as gcontext field.\n" << logofs_flush;
#endif
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ChangeGC_H
#define ChangeGC_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define CHANGEGC_ENABLE_CACHE 1
#define CHANGEGC_ENABLE_DATA 0
#define CHANGEGC_ENABLE_SPLIT 0
#define CHANGEGC_ENABLE_COMPRESS 0
#define CHANGEGC_DATA_LIMIT 144
#define CHANGEGC_DATA_OFFSET 12
#define CHANGEGC_CACHE_SLOTS 3000
#define CHANGEGC_CACHE_THRESHOLD 3
#define CHANGEGC_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class ChangeGCMessage : public Message
{
friend class ChangeGCStore;
public:
ChangeGCMessage()
{
}
~ChangeGCMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned int gcontext;
unsigned int value_mask;
};
class ChangeGCStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
ChangeGCStore() : MessageStore()
{
enableCache = CHANGEGC_ENABLE_CACHE;
enableData = CHANGEGC_ENABLE_DATA;
enableSplit = CHANGEGC_ENABLE_SPLIT;
enableCompress = CHANGEGC_ENABLE_COMPRESS;
dataLimit = CHANGEGC_DATA_LIMIT;
dataOffset = CHANGEGC_DATA_OFFSET;
cacheSlots = CHANGEGC_CACHE_SLOTS;
cacheThreshold = CHANGEGC_CACHE_THRESHOLD;
cacheLowerThreshold = CHANGEGC_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~ChangeGCStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "ChangeGC";
}
virtual unsigned char opcode() const
{
return X_ChangeGC;
}
virtual unsigned int storage() const
{
return sizeof(ChangeGCMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new ChangeGCMessage();
}
virtual Message *create(const Message &message) const
{
return new ChangeGCMessage((const ChangeGCMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (ChangeGCMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const;
virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const;
};
#endif /* ChangeGC_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ChangeGCCompat.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Here are the methods to handle messages' content.
//
int ChangeGCCompatStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangeGCCompatMessage *changeGC = (ChangeGCCompatMessage *) message;
//
// Here is the fingerprint.
//
changeGC -> gcontext = GetULONG(buffer + 4, bigEndian);
changeGC -> value_mask = GetULONG(buffer + 8, bigEndian);
//
// Clear the unused bytes carried in the
// payload to increase the effectiveness
// of the caching algorithm.
//
if ((int) size > dataOffset)
{
#ifdef DEBUG
*logofs << name() << ": Removing unused bytes from the "
<< "data payload.\n" << logofs_flush;
#endif
changeGC -> value_mask &= (1 << 23) - 1;
unsigned int mask = 0x1;
unsigned char *source = (unsigned char *) buffer + CHANGEGC_DATA_OFFSET;
unsigned long value = 0;
for (unsigned int i = 0; i < 23; i++)
{
if (changeGC -> value_mask & mask)
{
value = GetULONG(source, bigEndian);
value &= (0xffffffff >> (32 - CREATEGC_FIELD_WIDTH[i]));
PutULONG(value, source, bigEndian);
source += 4;
}
mask <<= 1;
}
}
#ifdef DEBUG
*logofs << name() << ": Parsed Identity for message at "
<< this << ".\n" << logofs_flush;
#endif
return 1;
}
int ChangeGCCompatStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangeGCCompatMessage *changeGC = (ChangeGCCompatMessage *) message;
//
// Fill all the message's fields.
//
PutULONG(changeGC -> gcontext, buffer + 4, bigEndian);
PutULONG(changeGC -> value_mask, buffer + 8, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at "
<< this << ".\n" << logofs_flush;
#endif
return 1;
}
void ChangeGCCompatStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
ChangeGCCompatMessage *changeGC = (ChangeGCCompatMessage *) message;
*logofs << name() << ": Identity gcontext " << changeGC -> gcontext
<< ", mask " << changeGC -> value_mask << ", size "
<< changeGC -> size_ << ".\n" << logofs_flush;
#endif
}
void ChangeGCCompatStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
md5_append(md5_state_, buffer + 4, 8);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ChangeGCCompat_H
#define ChangeGCCompat_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define CHANGEGC_ENABLE_CACHE 1
#define CHANGEGC_ENABLE_DATA 0
#define CHANGEGC_ENABLE_SPLIT 0
#define CHANGEGC_ENABLE_COMPRESS 0
#define CHANGEGC_DATA_LIMIT 144
#define CHANGEGC_DATA_OFFSET 12
#define CHANGEGC_CACHE_SLOTS 3000
#define CHANGEGC_CACHE_THRESHOLD 3
#define CHANGEGC_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class ChangeGCCompatMessage : public Message
{
friend class ChangeGCCompatStore;
public:
ChangeGCCompatMessage()
{
}
~ChangeGCCompatMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned int gcontext;
unsigned int value_mask;
};
class ChangeGCCompatStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
ChangeGCCompatStore() : MessageStore()
{
enableCache = CHANGEGC_ENABLE_CACHE;
enableData = CHANGEGC_ENABLE_DATA;
enableSplit = CHANGEGC_ENABLE_SPLIT;
enableCompress = CHANGEGC_ENABLE_COMPRESS;
dataLimit = CHANGEGC_DATA_LIMIT;
dataOffset = CHANGEGC_DATA_OFFSET;
cacheSlots = CHANGEGC_CACHE_SLOTS;
cacheThreshold = CHANGEGC_CACHE_THRESHOLD;
cacheLowerThreshold = CHANGEGC_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~ChangeGCCompatStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "ChangeGCCompat";
}
virtual unsigned char opcode() const
{
return X_ChangeGC;
}
virtual unsigned int storage() const
{
return sizeof(ChangeGCCompatMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new ChangeGCCompatMessage();
}
virtual Message *create(const Message &message) const
{
return new ChangeGCCompatMessage((const ChangeGCCompatMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (ChangeGCCompatMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
};
#endif /* ChangeGCCompat_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ChangeProperty.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Here are the methods to handle messages' content.
//
int ChangePropertyStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message;
changeProperty -> mode = *(buffer + 1);
changeProperty -> format = *(buffer + 16);
changeProperty -> window = GetULONG(buffer + 4, bigEndian);
changeProperty -> property = GetULONG(buffer + 8, bigEndian);
changeProperty -> type = GetULONG(buffer + 12, bigEndian);
changeProperty -> length = GetULONG(buffer + 20, bigEndian);
//
// Cleanup the padding bytes.
//
unsigned int uiFormat;
unsigned int uiLengthInBytes;
if ((int) size > CHANGEPROPERTY_DATA_OFFSET)
{
uiFormat = *(buffer + 16);
uiLengthInBytes = changeProperty -> length;
#ifdef DEBUG
*logofs << name() << ": length " << uiLengthInBytes
<< ", format " << uiFormat << ", size "
<< size << ".\n" << logofs_flush;
#endif
if (uiFormat == 16)
{
uiLengthInBytes <<= 1;
}
else if (uiFormat == 32)
{
uiLengthInBytes <<= 2;
}
unsigned char *end = ((unsigned char *) buffer) + size;
unsigned char *pad = ((unsigned char *) buffer) + CHANGEPROPERTY_DATA_OFFSET + uiLengthInBytes;
CleanData((unsigned char *) pad, end - pad);
}
#ifdef DEBUG
*logofs << name() << ": Parsed identity for message at "
<< message << ".\n" << logofs_flush;
#endif
return 1;
}
int ChangePropertyStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message;
*(buffer + 1) = changeProperty -> mode;
*(buffer + 16) = changeProperty -> format;
PutULONG(changeProperty -> window, buffer + 4, bigEndian);
PutULONG(changeProperty -> property, buffer + 8, bigEndian);
PutULONG(changeProperty -> type, buffer + 12, bigEndian);
PutULONG(changeProperty -> length, buffer + 20, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at "
<< this << ".\n" << logofs_flush;
#endif
return 1;
}
void ChangePropertyStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message;
*logofs << name() << ": Identity mode " << (unsigned int) changeProperty -> mode << ", format "
<< (unsigned int) changeProperty -> format << ", window " << changeProperty -> window
<< ", property " << changeProperty -> property << ", type " << changeProperty -> type
<< ", length " << changeProperty -> length << ", size " << changeProperty -> size_
<< ".\n" << logofs_flush;
#endif
}
void ChangePropertyStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
md5_append(md5_state_, buffer + 1, 1);
md5_append(md5_state_, buffer + 16, 1);
md5_append(md5_state_, buffer + 8, 4);
md5_append(md5_state_, buffer + 12, 4);
md5_append(md5_state_, buffer + 20, 4);
}
void ChangePropertyStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const
{
ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message;
ChangePropertyMessage *cachedChangeProperty = (ChangePropertyMessage *) cachedMessage;
ClientCache *clientCache = (ClientCache *) channelCache;
#ifdef TEST
*logofs << name() << ": Encoding value " << changeProperty -> window
<< " as window field.\n" << logofs_flush;
#endif
encodeBuffer.encodeXidValue(changeProperty -> window, clientCache -> windowCache);
cachedChangeProperty -> window = changeProperty -> window;
}
void ChangePropertyStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const
{
ChangePropertyMessage *changeProperty = (ChangePropertyMessage *) message;
ClientCache *clientCache = (ClientCache *) channelCache;
unsigned int value;
decodeBuffer.decodeXidValue(value, clientCache -> windowCache);
changeProperty -> window = value;
#ifdef DEBUG
*logofs << name() << ": Decoded value " << changeProperty -> window
<< " as window field.\n" << logofs_flush;
#endif
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ChangeProperty_H
#define ChangeProperty_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define CHANGEPROPERTY_ENABLE_CACHE 1
#define CHANGEPROPERTY_ENABLE_DATA 0
#define CHANGEPROPERTY_ENABLE_SPLIT 0
#define CHANGEPROPERTY_ENABLE_COMPRESS 0
#define CHANGEPROPERTY_DATA_LIMIT 28688
#define CHANGEPROPERTY_DATA_OFFSET 24
#define CHANGEPROPERTY_CACHE_SLOTS 2000
#define CHANGEPROPERTY_CACHE_THRESHOLD 2
#define CHANGEPROPERTY_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class ChangePropertyMessage : public Message
{
friend class ChangePropertyStore;
public:
ChangePropertyMessage()
{
}
~ChangePropertyMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned char mode;
unsigned char format;
unsigned int window;
unsigned int property;
unsigned int type;
unsigned int length;
};
class ChangePropertyStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
ChangePropertyStore() : MessageStore()
{
enableCache = CHANGEPROPERTY_ENABLE_CACHE;
enableData = CHANGEPROPERTY_ENABLE_DATA;
enableSplit = CHANGEPROPERTY_ENABLE_SPLIT;
enableCompress = CHANGEPROPERTY_ENABLE_COMPRESS;
dataLimit = CHANGEPROPERTY_DATA_LIMIT;
dataOffset = CHANGEPROPERTY_DATA_OFFSET;
cacheSlots = CHANGEPROPERTY_CACHE_SLOTS;
cacheThreshold = CHANGEPROPERTY_CACHE_THRESHOLD;
cacheLowerThreshold = CHANGEPROPERTY_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~ChangePropertyStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "ChangeProperty";
}
virtual unsigned char opcode() const
{
return X_ChangeProperty;
}
virtual unsigned int storage() const
{
return sizeof(ChangePropertyMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new ChangePropertyMessage();
}
virtual Message *create(const Message &message) const
{
return new ChangePropertyMessage((const ChangePropertyMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (ChangePropertyMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const;
virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
};
#endif /* ChangeProperty_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ChannelCache.h"
const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7] =
{
16, // x
16, // y
16, // width
16, // height
16, // border width
29, // sibling window
3 // stack mode
};
const unsigned int CREATEGC_FIELD_WIDTH[23] =
{
4, // function
32, // plane mask
32, // foreground
32, // background
16, // line width
2, // line style
2, // cap style
2, // join style
2, // fill style
1, // fill rule
29, // tile
29, // stipple
16, // tile/stipple x origin
16, // tile/stipple y origin
29, // font
1, // subwindow mode
1, // graphics exposures
16, // clip x origin
16, // clip y origin
29, // clip mask
16, // card offset
8, // dashes
1 // arc mode
};
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ChannelCache_H
#define ChannelCache_H
//
// Elements in array of caches used in TextCompressor.
//
const unsigned int CLIENT_TEXT_CACHE_SIZE = 9999;
const unsigned int SERVER_TEXT_CACHE_SIZE = 9999;
//
// Sizes of optional fields for ConfigureWindow
// request.
//
extern const unsigned int CONFIGUREWINDOW_FIELD_WIDTH[7];
//
// Sizes of optional fields for CreateGC request.
//
extern const unsigned int CREATEGC_FIELD_WIDTH[23];
//
// This is just needed to provide a pointer
// to the base cache class in encoding and
// decoding procedures of message stores.
//
class ChannelCache
{
public:
ChannelCache()
{
}
~ChannelCache()
{
}
};
#endif /* ChannelCache_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ChannelStore_H
#define ChannelStore_H
//
// One message store for each opcode.
//
#define CHANNEL_STORE_OPCODE_LIMIT 256
//
// One split store for each resource.
//
#define CHANNEL_STORE_RESOURCE_LIMIT 256
class ChannelStore
{
public:
ChannelStore()
{
}
virtual ~ChannelStore()
{
}
};
#endif /* ChannelStore_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "CharCache.h"
int CharCache::lookup(unsigned char value, unsigned int &index)
{
for (unsigned int i = 0; i < length_; i++)
if (value == buffer_[i])
{
index = i;
if (i)
{
unsigned int target = (i >> 1);
do
{
buffer_[i] = buffer_[i - 1];
i--;
}
while (i > target);
buffer_[target] = value;
}
return 1;
}
insert(value);
return 0;
}
void CharCache::insert(unsigned char value)
{
unsigned int insertionPoint = 0;
if (2 >= length_)
insertionPoint = length_;
else
insertionPoint = 2;
unsigned int start;
if (length_ >= 7)
start = 7 - 1;
else
{
start = length_;
length_++;
}
for (unsigned int k = start; k > insertionPoint; k--)
buffer_[k] = buffer_[k - 1];
buffer_[insertionPoint] = value;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef CharCache_H
#define CharCache_H
//
// CharCache is a counterpart of IntCache that is
// optimized for use in compressing text composed
// of 8-bit characters.
//
class CharCache
{
public:
CharCache() : length_(0)
{
}
~CharCache()
{
}
unsigned int getSize() const
{
return (unsigned int) length_;
}
int lookup(unsigned char value, unsigned int &index);
//
// This can be inlined as it is only
// called by decodeCachedValue().
//
unsigned int get(unsigned int index)
{
unsigned char result = buffer_[index];
if (index != 0)
{
unsigned int i = index;
unsigned int target = (i >> 1);
do
{
buffer_[i] = buffer_[i - 1];
i--;
}
while (i > target);
buffer_[target] = result;
}
return (unsigned int) result;
}
void insert(unsigned char value);
private:
unsigned char length_;
unsigned char buffer_[7];
};
#endif /* CharCache_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ClearArea.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Here are the methods to handle messages' content.
//
int ClearAreaStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ClearAreaMessage *clearArea = (ClearAreaMessage *) message;
//
// Here is the fingerprint.
//
clearArea -> exposures = *(buffer + 1);
clearArea -> window = GetULONG(buffer + 4, bigEndian);
clearArea -> x = GetUINT(buffer + 8, bigEndian);
clearArea -> y = GetUINT(buffer + 10, bigEndian);
clearArea -> width = GetUINT(buffer + 12, bigEndian);
clearArea -> height = GetUINT(buffer + 14, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
int ClearAreaStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ClearAreaMessage *clearArea = (ClearAreaMessage *) message;
//
// Fill all the message's fields.
//
*(buffer + 1) = clearArea -> exposures;
PutULONG(clearArea -> window, buffer + 4, bigEndian);
PutUINT(clearArea -> x, buffer + 8, bigEndian);
PutUINT(clearArea -> y, buffer + 10, bigEndian);
PutUINT(clearArea -> width, buffer + 12, bigEndian);
PutUINT(clearArea -> height, buffer + 14, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
void ClearAreaStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
ClearAreaMessage *clearArea = (ClearAreaMessage *) message;
*logofs << name() << ": Identity exposures " << clearArea -> (unsigned int) exposures
<< ", window " << clearArea -> window << ", x " << clearArea -> x
<< ", y " << clearArea -> y << ", width " << clearArea -> width
<< ", height " << clearArea -> height << ", size " << clearArea -> size_
<< ".\n";
#endif
}
void ClearAreaStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
md5_append(md5_state_, buffer + 1, 1);
md5_append(md5_state_, buffer + 4, 4);
md5_append(md5_state_, buffer + 8, 2);
md5_append(md5_state_, buffer + 10, 2);
md5_append(md5_state_, buffer + 12, 2);
md5_append(md5_state_, buffer + 14, 2);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ClearArea_H
#define ClearArea_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define CLEARAREA_ENABLE_CACHE 1
#define CLEARAREA_ENABLE_DATA 0
#define CLEARAREA_ENABLE_SPLIT 0
#define CLEARAREA_ENABLE_COMPRESS 0
#define CLEARAREA_DATA_LIMIT 0
#define CLEARAREA_DATA_OFFSET 16
#define CLEARAREA_CACHE_SLOTS 3000
#define CLEARAREA_CACHE_THRESHOLD 5
#define CLEARAREA_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class ClearAreaMessage : public Message
{
friend class ClearAreaStore;
public:
ClearAreaMessage()
{
}
~ClearAreaMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned char exposures;
unsigned int window;
unsigned short x;
unsigned short y;
unsigned short width;
unsigned short height;
};
class ClearAreaStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
ClearAreaStore() : MessageStore()
{
enableCache = CLEARAREA_ENABLE_CACHE;
enableData = CLEARAREA_ENABLE_DATA;
enableSplit = CLEARAREA_ENABLE_SPLIT;
enableCompress = CLEARAREA_ENABLE_COMPRESS;
dataLimit = CLEARAREA_DATA_LIMIT;
dataOffset = CLEARAREA_DATA_OFFSET;
cacheSlots = CLEARAREA_CACHE_SLOTS;
cacheThreshold = CLEARAREA_CACHE_THRESHOLD;
cacheLowerThreshold = CLEARAREA_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~ClearAreaStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "ClearArea";
}
virtual unsigned char opcode() const
{
return X_ClearArea;
}
virtual unsigned int storage() const
{
return sizeof(ClearAreaMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new ClearAreaMessage();
}
virtual Message *create(const Message &message) const
{
return new ClearAreaMessage((const ClearAreaMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (ClearAreaMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
};
#endif /* ClearArea_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ClientCache.h"
ClientCache::ClientCache() :
freeGCCache(16), freeDrawableCache(16), freeWindowCache(16),
cursorCache(16), colormapCache(16), visualCache(16), lastFont(0),
changePropertyPropertyCache(16), changePropertyTypeCache(16),
changePropertyData32Cache(16),
changePropertyTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
configureWindowBitmaskCache(4),
convertSelectionRequestorCache(16),
convertSelectionLastTimestamp(0),
copyPlaneBitPlaneCache(8),
createGCBitmaskCache(8),
createPixmapIdCache(16), createPixmapLastId(0),
createPixmapXCache(8), createPixmapYCache(8),
createWindowBitmaskCache(8),
fillPolyNumPointsCache(8), fillPolyIndex(0),
getSelectionOwnerSelectionCache(8),
grabButtonEventMaskCache(8), grabButtonConfineCache(8),
grabButtonModifierCache(8),
grabKeyboardLastTimestamp(0),
imageTextLengthCache(8),
imageTextLastX(0), imageTextLastY(0),
imageTextCacheX(8), imageTextCacheY(8),
imageTextTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
internAtomTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
openFontTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
polySegmentCacheX(8), polySegmentCacheY(8), polySegmentCacheIndex(0),
polyTextLastX(0), polyTextLastY(0), polyTextCacheX(8),
polyTextCacheY(8), polyTextFontCache(8),
polyTextTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
putImageWidthCache(8), putImageHeightCache(8), putImageLastX(0),
putImageLastY(0), putImageXCache(8), putImageYCache(8),
getImagePlaneMaskCache(8),
queryColorsLastPixel(0),
setClipRectanglesXCache(8), setClipRectanglesYCache(8),
setDashesLengthCache(8), setDashesOffsetCache(8),
setSelectionOwnerCache(8), setSelectionOwnerTimestampCache(8),
translateCoordsSrcCache(8), translateCoordsDstCache(8),
translateCoordsXCache(8), translateCoordsYCache(8),
sendEventMaskCache(16), sendEventLastSequence(0),
sendEventIntDataCache(16),
putPackedImageSrcLengthCache(16), putPackedImageDstLengthCache(16),
//
// RenderExtension requests.
//
renderFreePictureCache(16),
renderGlyphSetCache(16),
renderFreeGlyphSetCache(16),
renderIdCache(8),
renderLengthCache(16), renderFormatCache(16),
renderValueMaskCache(8), renderNumGlyphsCache(8),
renderXCache(16), renderYCache(16),
renderLastX(0), renderLastY(0),
renderWidthCache(16), renderHeightCache(16),
renderLastId(0),
renderTextCompressor(textCache, CLIENT_TEXT_CACHE_SIZE),
renderGlyphXCache(16), renderGlyphYCache(16),
renderGlyphX(0), renderGlyphY(0),
renderLastCompositeGlyphsData(0),
setCacheParametersCache(8),
lastIdCache(16), lastId(0)
{
unsigned int i;
for (i = 0; i < 3; i++)
{
allocColorRGBCache[i] = new IntCache(8);
convertSelectionAtomCache[i] = new IntCache(8);
}
for (i = 0; i < 4; i++)
{
clearAreaGeomCache[i] = new IntCache(8);
}
for (i = 0; i < 7; i++)
{
configureWindowAttrCache[i] = new IntCache(8);
}
for (i = 0; i < 6; i++)
{
copyAreaGeomCache[i] = new IntCache(8);
copyPlaneGeomCache[i] = new IntCache(8);
}
for (i = 0; i < 23; i++)
{
if (CREATEGC_FIELD_WIDTH[i] > 16)
{
createGCAttrCache[i] = new IntCache(16);
}
else
{
createGCAttrCache[i] = new IntCache(CREATEGC_FIELD_WIDTH[i]);
}
}
for (i = 0; i < 6; i++)
{
createWindowGeomCache[i] = new IntCache(8);
}
for (i = 0; i < 15; i++)
{
createWindowAttrCache[i] = new IntCache(8);
}
for (i = 0; i < 10; i++)
{
fillPolyXRelCache[i] = new IntCache(8);
fillPolyXAbsCache[i] = new IntCache(8);
fillPolyYRelCache[i] = new IntCache(8);
fillPolyYAbsCache[i] = new IntCache(8);
}
for (i = 0; i < 8; i++)
{
fillPolyRecentX[i] = 0;
fillPolyRecentY[i] = 0;
}
for (i = 0; i < 4; i++)
{
polyFillRectangleCacheX[i] = new IntCache(8);
polyFillRectangleCacheY[i] = new IntCache(8);
polyFillRectangleCacheWidth[i] = new IntCache(8);
polyFillRectangleCacheHeight[i] = new IntCache(8);
}
for (i = 0; i < 2; i++)
{
polyLineCacheX[i] = new IntCache(8);
polyLineCacheY[i] = new IntCache(8);
}
for (i = 0; i < 2; i++)
{
polyPointCacheX[i] = new IntCache(8);
polyPointCacheY[i] = new IntCache(8);
}
for (i = 0; i < 4; i++)
{
polyRectangleGeomCache[i] = new IntCache(8);
}
for (i = 0; i < 2; i++)
{
polySegmentLastX[i] = 0;
polySegmentLastY[i] = 0;
}
for (i = 0; i < 4; i++)
{
setClipRectanglesGeomCache[i] = new IntCache(8);
}
for (i = 0; i < 2; i++)
{
polyFillArcCacheX[i] = new IntCache(8);
polyFillArcCacheY[i] = new IntCache(8);
polyFillArcCacheWidth[i] = new IntCache(8);
polyFillArcCacheHeight[i] = new IntCache(8);
polyFillArcCacheAngle1[i] = new IntCache(8);
polyFillArcCacheAngle2[i] = new IntCache(8);
}
for (i = 0; i < 2; i++)
{
polyArcCacheX[i] = new IntCache(8);
polyArcCacheY[i] = new IntCache(8);
polyArcCacheWidth[i] = new IntCache(8);
polyArcCacheHeight[i] = new IntCache(8);
polyArcCacheAngle1[i] = new IntCache(8);
polyArcCacheAngle2[i] = new IntCache(8);
}
for (i = 0; i < 8; i++)
{
shapeDataCache[i] = new IntCache(8);
}
for (i = 0; i < 8; i++)
{
genericRequestDataCache[i] = new IntCache(8);
}
for (i = 0; i < 16; i++)
{
renderDataCache[i] = new IntCache(16);
}
for (i = 0; i < 16; i++)
{
renderCompositeGlyphsDataCache[i] = new IntCache(16);
}
for (i = 0; i < 3; i++)
{
renderCompositeDataCache[i] = new IntCache(16);
}
}
ClientCache::~ClientCache()
{
unsigned int i;
for (i = 0; i < 3; i++)
{
delete allocColorRGBCache[i];
delete convertSelectionAtomCache[i];
}
for (i = 0; i < 4; i++)
{
delete clearAreaGeomCache[i];
}
for (i = 0; i < 7; i++)
{
delete configureWindowAttrCache[i];
}
for (i = 0; i < 6; i++)
{
delete copyAreaGeomCache[i];
delete copyPlaneGeomCache[i];
}
for (i = 0; i < 23; i++)
{
delete createGCAttrCache[i];
}
for (i = 0; i < 6; i++)
{
delete createWindowGeomCache[i];
}
for (i = 0; i < 15; i++)
{
delete createWindowAttrCache[i];
}
for (i = 0; i < 10; i++)
{
delete fillPolyXRelCache[i];
delete fillPolyXAbsCache[i];
delete fillPolyYRelCache[i];
delete fillPolyYAbsCache[i];
}
for (i = 0; i < 4; i++)
{
delete polyFillRectangleCacheX[i];
delete polyFillRectangleCacheY[i];
delete polyFillRectangleCacheWidth[i];
delete polyFillRectangleCacheHeight[i];
}
for (i = 0; i < 2; i++)
{
delete polyLineCacheX[i];
delete polyLineCacheY[i];
}
for (i = 0; i < 2; i++)
{
delete polyPointCacheX[i];
delete polyPointCacheY[i];
}
for (i = 0; i < 4; i++)
{
delete polyRectangleGeomCache[i];
}
for (i = 0; i < 4; i++)
{
delete setClipRectanglesGeomCache[i];
}
for (i = 0; i < 2; i++)
{
delete polyFillArcCacheX[i];
delete polyFillArcCacheY[i];
delete polyFillArcCacheWidth[i];
delete polyFillArcCacheHeight[i];
delete polyFillArcCacheAngle1[i];
delete polyFillArcCacheAngle2[i];
}
for (i = 0; i < 2; i++)
{
delete polyArcCacheX[i];
delete polyArcCacheY[i];
delete polyArcCacheWidth[i];
delete polyArcCacheHeight[i];
delete polyArcCacheAngle1[i];
delete polyArcCacheAngle2[i];
}
for (i = 0; i < 8; i++)
{
delete shapeDataCache[i];
}
for (i = 0; i < 8; i++)
{
delete genericRequestDataCache[i];
}
for (i = 0; i < 16; i++)
{
delete renderDataCache[i];
}
for (i = 0; i < 16; i++)
{
delete renderCompositeGlyphsDataCache[i];
}
for (i = 0; i < 3; i++)
{
delete renderCompositeDataCache[i];
}
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ClientCache_H
#define ClientCache_H
#include "Misc.h"
#include "IntCache.h"
#include "CharCache.h"
#include "OpcodeCache.h"
#include "XidCache.h"
#include "FreeCache.h"
#include "TextCompressor.h"
#include "ChannelCache.h"
class ClientCache : public ChannelCache
{
public:
ClientCache();
~ClientCache();
//
// Opcode prediction caches.
//
OpcodeCache opcodeCache;
//
// GC and drawables caches.
//
XidCache gcCache;
FreeCache freeGCCache;
XidCache drawableCache;
FreeCache freeDrawableCache;
XidCache windowCache;
FreeCache freeWindowCache;
//
// General-purpose caches.
//
CharCache textCache[CLIENT_TEXT_CACHE_SIZE];
IntCache cursorCache;
IntCache colormapCache;
IntCache visualCache;
CharCache depthCache;
CharCache resourceCache;
CharCache methodCache;
unsigned int lastFont;
//
// AllocColor request.
//
IntCache *allocColorRGBCache[3];
//
// ChangeProperty request.
//
CharCache changePropertyFormatCache;
IntCache changePropertyPropertyCache;
IntCache changePropertyTypeCache;
IntCache changePropertyData32Cache;
TextCompressor changePropertyTextCompressor;
//
// ClearArea request.
//
IntCache *clearAreaGeomCache[4];
//
// ConfigureWindow request.
//
IntCache configureWindowBitmaskCache;
IntCache *configureWindowAttrCache[7];
//
// ConvertSelection request.
//
IntCache convertSelectionRequestorCache;
IntCache* convertSelectionAtomCache[3];
unsigned int convertSelectionLastTimestamp;
//
// CopyArea request.
//
IntCache *copyAreaGeomCache[6];
//
// CopyPlane request.
//
IntCache *copyPlaneGeomCache[6];
IntCache copyPlaneBitPlaneCache;
//
// CreateGC request.
//
IntCache createGCBitmaskCache;
IntCache *createGCAttrCache[23];
//
// CreatePixmap request.
//
IntCache createPixmapIdCache;
unsigned int createPixmapLastId;
IntCache createPixmapXCache;
IntCache createPixmapYCache;
//
// CreateWindow request.
//
IntCache *createWindowGeomCache[6];
IntCache createWindowBitmaskCache;
IntCache *createWindowAttrCache[15];
//
// FillPoly request.
//
IntCache fillPolyNumPointsCache;
IntCache *fillPolyXRelCache[10];
IntCache *fillPolyXAbsCache[10];
IntCache *fillPolyYRelCache[10];
IntCache *fillPolyYAbsCache[10];
unsigned int fillPolyRecentX[8];
unsigned int fillPolyRecentY[8];
unsigned int fillPolyIndex;
//
// GetSelectionOwner request.
//
IntCache getSelectionOwnerSelectionCache;
//
// GrabButton request (also used for GrabPointer).
//
IntCache grabButtonEventMaskCache;
IntCache grabButtonConfineCache;
CharCache grabButtonButtonCache;
IntCache grabButtonModifierCache;
//
// GrabKeyboard request.
//
unsigned int grabKeyboardLastTimestamp;
//
// ImageText8/16 request.
//
IntCache imageTextLengthCache;
unsigned int imageTextLastX;
unsigned int imageTextLastY;
IntCache imageTextCacheX;
IntCache imageTextCacheY;
TextCompressor imageTextTextCompressor;
//
// InternAtom request.
//
TextCompressor internAtomTextCompressor;
//
// OpenFont request.
//
TextCompressor openFontTextCompressor;
//
// PolyFillRectangle request.
//
IntCache *polyFillRectangleCacheX[4];
IntCache *polyFillRectangleCacheY[4];
IntCache *polyFillRectangleCacheWidth[4];
IntCache *polyFillRectangleCacheHeight[4];
//
// PolyLine request.
//
IntCache *polyLineCacheX[2];
IntCache *polyLineCacheY[2];
//
// PolyPoint request.
//
IntCache *polyPointCacheX[2];
IntCache *polyPointCacheY[2];
//
// PolyRectangle request.
//
IntCache *polyRectangleGeomCache[4];
//
// PolySegment request.
//
IntCache polySegmentCacheX;
IntCache polySegmentCacheY;
unsigned int polySegmentLastX[2];
unsigned int polySegmentLastY[2];
unsigned int polySegmentCacheIndex;
//
// PolyText8/16 request.
//
unsigned int polyTextLastX;
unsigned int polyTextLastY;
IntCache polyTextCacheX;
IntCache polyTextCacheY;
IntCache polyTextFontCache;
CharCache polyTextDeltaCache;
TextCompressor polyTextTextCompressor;
//
// PutImage request.
//
IntCache putImageWidthCache;
IntCache putImageHeightCache;
unsigned int putImageLastX;
unsigned int putImageLastY;
IntCache putImageXCache;
IntCache putImageYCache;
CharCache putImageLeftPadCache;
//
// GetImage request.
//
IntCache getImagePlaneMaskCache;
//
// QueryColors request.
//
unsigned int queryColorsLastPixel;
//
// SetClipRectangles request.
//
IntCache setClipRectanglesXCache;
IntCache setClipRectanglesYCache;
IntCache *setClipRectanglesGeomCache[4];
//
// SetDashes request.
//
IntCache setDashesLengthCache;
IntCache setDashesOffsetCache;
CharCache setDashesDashCache_[2];
//
// SetSelectionOwner request.
//
IntCache setSelectionOwnerCache;
IntCache setSelectionOwnerTimestampCache;
//
// TranslateCoords request.
//
IntCache translateCoordsSrcCache;
IntCache translateCoordsDstCache;
IntCache translateCoordsXCache;
IntCache translateCoordsYCache;
//
// SendEvent request.
//
IntCache sendEventMaskCache;
CharCache sendEventCodeCache;
CharCache sendEventByteDataCache;
unsigned int sendEventLastSequence;
IntCache sendEventIntDataCache;
CharCache sendEventEventCache;
//
// PolyFillArc request.
//
IntCache *polyFillArcCacheX[2];
IntCache *polyFillArcCacheY[2];
IntCache *polyFillArcCacheWidth[2];
IntCache *polyFillArcCacheHeight[2];
IntCache *polyFillArcCacheAngle1[2];
IntCache *polyFillArcCacheAngle2[2];
//
// PolyArc request.
//
IntCache *polyArcCacheX[2];
IntCache *polyArcCacheY[2];
IntCache *polyArcCacheWidth[2];
IntCache *polyArcCacheHeight[2];
IntCache *polyArcCacheAngle1[2];
IntCache *polyArcCacheAngle2[2];
//
// PutPackedImage request.
//
IntCache putPackedImageSrcLengthCache;
IntCache putPackedImageDstLengthCache;
//
// Shape extension requests.
//
CharCache shapeOpcodeCache;
IntCache *shapeDataCache[8];
//
// Generic requests.
//
CharCache genericRequestOpcodeCache;
IntCache *genericRequestDataCache[8];
//
// Render extension requests.
//
OpcodeCache renderOpcodeCache;
CharCache renderOpCache;
XidCache renderSrcPictureCache;
XidCache renderMaskPictureCache;
XidCache renderDstPictureCache;
FreeCache renderFreePictureCache;
IntCache renderGlyphSetCache;
FreeCache renderFreeGlyphSetCache;
IntCache renderIdCache;
IntCache renderLengthCache;
IntCache renderFormatCache;
IntCache renderValueMaskCache;
IntCache renderNumGlyphsCache;
IntCache renderXCache;
IntCache renderYCache;
unsigned int renderLastX;
unsigned int renderLastY;
IntCache renderWidthCache;
IntCache renderHeightCache;
unsigned int renderLastId;
IntCache *renderDataCache[16];
TextCompressor renderTextCompressor;
IntCache renderGlyphXCache;
IntCache renderGlyphYCache;
unsigned int renderGlyphX;
unsigned int renderGlyphY;
IntCache *renderCompositeGlyphsDataCache[16];
unsigned int renderLastCompositeGlyphsData;
IntCache *renderCompositeDataCache[3];
//
// SetCacheParameters request.
//
IntCache setCacheParametersCache;
//
// Encode new XID values based
// on the last value encoded.
//
IntCache lastIdCache;
unsigned int lastId;
};
#endif /* ClientCache_H */
This source diff could not be displayed because it is too large. You can view the blob instead.
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ClientProxy_H
#define ClientProxy_H
#include "Proxy.h"
//
// Set the verbosity level.
//
#undef TEST
#undef DEBUG
class ClientProxy : public Proxy
{
public:
ClientProxy(int proxyFD);
virtual ~ClientProxy();
virtual void handleDisplayConfiguration(const char *xServerDisplay, int xServerAddrFamily,
sockaddr *xServerAddr, unsigned int xServerAddrLength);
virtual void handlePortConfiguration(int cupsServerPort, int smbServerPort, int mediaServerPort,
int httpServerPort, const char *fontServerPort);
protected:
//
// Create a new channel.
//
virtual int handleNewConnection(T_channel_type type, int clientFd);
virtual int handleNewConnectionFromProxy(T_channel_type type, int channelId);
virtual int handleNewAgentConnection(Agent *agent);
virtual int handleNewXConnection(int clientFd);
virtual int handleNewXConnectionFromProxy(int channelId);
//
// Implement persistence according
// to our proxy mode.
//
virtual int handleLoad(T_load_type type);
virtual int handleSave();
virtual int handleAsyncEvents();
virtual int handleLoadFromProxy();
virtual int handleSaveFromProxy();
virtual int handleSaveAllStores(ostream *cachefs, md5_state_t *md5StateStream,
md5_state_t *md5StateClient) const;
virtual int handleLoadAllStores(istream *cachefs, md5_state_t *md5StateStream) const;
//
// Utility function used to realize
// a new connection.
//
protected:
virtual int checkLocalChannelMap(int channelId)
{
if (control -> isProtoStep7() == 1)
{
return ((channelId & control -> ChannelMask) != 0);
}
else
{
return 1;
}
}
//
// Ports where to forward extended services'
// TCP connections.
//
private:
char *fontServerPort_;
};
#endif /* ClientProxy_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ClientReadBuffer.h"
#include "ClientChannel.h"
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
unsigned int ClientReadBuffer::suggestedLength(unsigned int pendingLength)
{
//
// Even if the pending data is not
// enough to make a complete message,
// resize the buffer to accomodate
// it all.
//
unsigned int readLength = pendingLength;
if (pendingLength < remaining_)
{
readLength = remaining_;
}
return readLength;
}
int ClientReadBuffer::locateMessage(const unsigned char *start,
const unsigned char *end,
unsigned int &controlLength,
unsigned int &dataLength,
unsigned int &trailerLength)
{
unsigned int size = end - start;
#ifdef TEST
*logofs << "ClientReadBuffer: Locating message for FD#"
<< transport_ -> fd() << " with " << size
<< " bytes.\n" << logofs_flush;
#endif
if (firstMessage_)
{
if (size < 12)
{
remaining_ = 12 - size;
#ifdef TEST
*logofs << "ClientReadBuffer: No message was located "
<< "with remaining " << remaining_ << ".\n"
<< logofs_flush;
#endif
return 0;
}
if (*start == 0x42)
{
bigEndian_ = 1;
}
else
{
bigEndian_ = 0;
}
channel_ -> setBigEndian(bigEndian_);
dataLength = 12 + RoundUp4(GetUINT(start + 6, bigEndian_)) +
RoundUp4(GetUINT(start + 8, bigEndian_));
//
// Send the data immediately if this is unlikely
// to be a X connection attempt.
//
if (dataLength > 4096)
{
#ifdef WARNING
*logofs << "ClientReadBuffer: WARNING! Flushing suspicious X "
<< "connection with first request of " << dataLength
<< " bytes.\n" << logofs_flush;
#endif
dataLength = size;
}
}
else
{
if (size < 4)
{
remaining_ = 4 - size;
#ifdef TEST
*logofs << "ClientReadBuffer: No message was located "
<< "with remaining " << remaining_ << ".\n"
<< logofs_flush;
#endif
return 0;
}
dataLength = (GetUINT(start + 2, bigEndian_) << 2);
if (dataLength < 4)
{
#ifdef TEST
*logofs << "ClientReadBuffer: WARNING! Assuming length 4 "
<< "for suspicious message of length " << dataLength
<< ".\n" << logofs_flush;
#endif
dataLength = 4;
}
}
#ifdef TEST
*logofs << "ClientReadBuffer: Length of the next message is "
<< dataLength << ".\n" << logofs_flush;
#endif
if (size < dataLength)
{
remaining_ = dataLength - size;
#ifdef TEST
*logofs << "ClientReadBuffer: No message was located "
<< "with remaining " << remaining_ << ".\n"
<< logofs_flush;
#endif
return 0;
}
firstMessage_ = 0;
controlLength = 0;
trailerLength = 0;
remaining_ = 0;
#ifdef TEST
*logofs << "ClientReadBuffer: Located message with "
<< "remaining " << remaining_ << ".\n"
<< logofs_flush;
#endif
return 1;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ClientReadBuffer_H
#define ClientReadBuffer_H
#include "Control.h"
#include "ReadBuffer.h"
class ClientChannel;
class ClientReadBuffer : public ReadBuffer
{
public:
ClientReadBuffer(Transport *transport, ClientChannel *channel)
: ReadBuffer(transport), firstMessage_(1), channel_(channel)
{
}
virtual ~ClientReadBuffer()
{
}
protected:
virtual unsigned int suggestedLength(unsigned int pendingLength);
virtual int locateMessage(const unsigned char *start,
const unsigned char *end,
unsigned int &controlLength,
unsigned int &dataLength,
unsigned int &trailerLength);
int bigEndian_;
int firstMessage_;
ClientChannel *channel_;
};
#endif /* ClientReadBuffer_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ClientStore.h"
//
// Cached request classes.
//
#include "ChangeProperty.h"
#include "SendEvent.h"
#include "CreateGC.h"
#include "ChangeGC.h"
#include "CreatePixmap.h"
#include "SetClipRectangles.h"
#include "CopyArea.h"
#include "PolyLine.h"
#include "PolySegment.h"
#include "PolyFillRectangle.h"
#include "PutImage.h"
#include "TranslateCoords.h"
#include "GetImage.h"
#include "ClearArea.h"
#include "ConfigureWindow.h"
#include "ShapeExtension.h"
#include "RenderExtension.h"
#include "PolyText8.h"
#include "PolyText16.h"
#include "ImageText8.h"
#include "ImageText16.h"
#include "PolyPoint.h"
#include "PolyFillArc.h"
#include "PolyArc.h"
#include "FillPoly.h"
#include "InternAtom.h"
#include "GetProperty.h"
#include "SetUnpackGeometry.h"
#include "SetUnpackColormap.h"
#include "SetUnpackAlpha.h"
#include "PutPackedImage.h"
#include "GenericRequest.h"
#include "ChangeGCCompat.h"
#include "CreatePixmapCompat.h"
#include "SetUnpackColormapCompat.h"
#include "SetUnpackAlphaCompat.h"
//
// Set the verbosity level.
//
#define WARNING
#define PANIC
#undef TEST
ClientStore::ClientStore(StaticCompressor *compressor)
: compressor_(compressor)
{
if (logofs == NULL)
{
logofs = &cout;
}
for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++)
{
requests_[i] = NULL;
}
requests_[X_ChangeProperty] = new ChangePropertyStore();
requests_[X_SendEvent] = new SendEventStore();
requests_[X_CreateGC] = new CreateGCStore();
requests_[X_SetClipRectangles] = new SetClipRectanglesStore();
requests_[X_CopyArea] = new CopyAreaStore();
requests_[X_PolyLine] = new PolyLineStore();
requests_[X_PolySegment] = new PolySegmentStore();
requests_[X_PolyFillRectangle] = new PolyFillRectangleStore();
requests_[X_PutImage] = new PutImageStore(compressor);
requests_[X_TranslateCoords] = new TranslateCoordsStore();
requests_[X_GetImage] = new GetImageStore();
requests_[X_ClearArea] = new ClearAreaStore();
requests_[X_ConfigureWindow] = new ConfigureWindowStore();
requests_[X_PolyText8] = new PolyText8Store();
requests_[X_PolyText16] = new PolyText16Store();
requests_[X_ImageText8] = new ImageText8Store();
requests_[X_ImageText16] = new ImageText16Store();
requests_[X_PolyPoint] = new PolyPointStore();
requests_[X_PolyFillArc] = new PolyFillArcStore();
requests_[X_PolyArc] = new PolyArcStore();
requests_[X_FillPoly] = new FillPolyStore();
requests_[X_InternAtom] = new InternAtomStore();
requests_[X_GetProperty] = new GetPropertyStore();
requests_[X_NXInternalShapeExtension] = new ShapeExtensionStore(compressor);
requests_[X_NXInternalGenericRequest] = new GenericRequestStore(compressor);
requests_[X_NXInternalRenderExtension] = new RenderExtensionStore(compressor);
requests_[X_NXSetUnpackGeometry] = new SetUnpackGeometryStore(compressor);
requests_[X_NXPutPackedImage] = new PutPackedImageStore(compressor);
if (control -> isProtoStep7() == 1)
{
requests_[X_ChangeGC] = new ChangeGCStore();
requests_[X_CreatePixmap] = new CreatePixmapStore();
requests_[X_NXSetUnpackColormap] = new SetUnpackColormapStore(compressor);
requests_[X_NXSetUnpackAlpha] = new SetUnpackAlphaStore(compressor);
}
else
{
requests_[X_ChangeGC] = new ChangeGCCompatStore();
requests_[X_CreatePixmap] = new CreatePixmapCompatStore();
requests_[X_NXSetUnpackColormap] = new SetUnpackColormapCompatStore(compressor);
requests_[X_NXSetUnpackAlpha] = new SetUnpackAlphaCompatStore(compressor);
}
for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++)
{
splits_[i] = NULL;
}
commits_ = new CommitStore(compressor);
}
ClientStore::~ClientStore()
{
if (logofs == NULL)
{
logofs = &cout;
}
for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++)
{
delete requests_[i];
}
for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++)
{
delete splits_[i];
}
delete commits_;
}
int ClientStore::saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream,
md5_state_t *md5StateClient, T_checksum_action checksumAction,
T_data_action dataAction) const
{
for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++)
{
if (requests_[i] != NULL &&
requests_[i] -> saveStore(cachefs, md5StateStream, md5StateClient,
checksumAction, dataAction,
storeBigEndian()) < 0)
{
#ifdef WARNING
*logofs << "ClientStore: WARNING! Error saving request store "
<< "for OPCODE#" << (unsigned int) i << ".\n"
<< logofs_flush;
#endif
cerr << "Warning" << ": Error saving request store "
<< "for opcode '" << (unsigned int) i << "'.\n";
return -1;
}
}
return 1;
}
int ClientStore::loadRequestStores(istream *cachefs, md5_state_t *md5StateStream,
T_checksum_action checksumAction, T_data_action dataAction) const
{
for (int i = 0; i < CHANNEL_STORE_OPCODE_LIMIT; i++)
{
if (requests_[i] != NULL &&
requests_[i] -> loadStore(cachefs, md5StateStream,
checksumAction, dataAction,
storeBigEndian()) < 0)
{
#ifdef WARNING
*logofs << "ClientStore: WARNING! Error loading request store "
<< "for OPCODE#" << (unsigned int) i << ".\n"
<< logofs_flush;
#endif
return -1;
}
}
return 1;
}
void ClientStore::dumpSplitStores() const
{
for (int i = 0; i < CHANNEL_STORE_RESOURCE_LIMIT; i++)
{
if (splits_[i] != NULL)
{
splits_[i] -> dump();
}
}
if ((getSplitTotalSize() != 0 && getSplitTotalStorageSize() == 0) ||
(getSplitTotalSize() == 0 && getSplitTotalStorageSize() != 0))
{
#ifdef PANIC
*logofs << "ClientStore: PANIC! Inconsistency detected "
<< "while handling the split stores.\n"
<< logofs_flush;
#endif
HandleCleanup();
}
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ClientStore_H
#define ClientStore_H
#include "Message.h"
#include "Split.h"
#include "ChannelStore.h"
class StaticCompressor;
class ClientStore : public ChannelStore
{
public:
ClientStore(StaticCompressor *compressor);
virtual ~ClientStore();
//
// Get the store based on the index.
//
MessageStore *getRequestStore(unsigned char opcode) const
{
return requests_[opcode];
}
SplitStore *getSplitStore(int resource) const
{
return splits_[resource];
}
int getSplitTotalSize() const
{
return SplitStore::getTotalSize();
}
int getSplitTotalStorageSize() const
{
return SplitStore::getTotalStorageSize();
}
CommitStore *getCommitStore() const
{
return commits_;
}
int getCommitSize() const
{
return commits_ -> getSize();
}
void dumpSplitStore(int resource) const
{
splits_[resource] -> dump();
}
void dumpCommitStore() const
{
commits_ -> dump();
}
void dumpSplitStores() const;
SplitStore *createSplitStore(int resource)
{
splits_[resource] = new SplitStore(compressor_, commits_, resource);
return splits_[resource];
}
void destroySplitStore(int resource)
{
delete splits_[resource];
splits_[resource] = NULL;
}
//
// Actually save the message store
// to disk according to proxy mode.
//
int saveRequestStores(ostream *cachefs, md5_state_t *md5StateStream,
md5_state_t *md5StateClient, T_checksum_action checksumAction,
T_data_action dataAction) const;
int loadRequestStores(istream *cachefs, md5_state_t *md5StateStream,
T_checksum_action checksumAction, T_data_action dataAction) const;
private:
//
// A client store contains requests.
//
MessageStore *requests_[CHANNEL_STORE_OPCODE_LIMIT];
//
// Client messages being split.
//
SplitStore *splits_[CHANNEL_STORE_RESOURCE_LIMIT];
//
// Messages having been recomposed.
//
CommitStore *commits_;
//
// Passed forward to the other stores.
//
StaticCompressor *compressor_;
};
#endif /* ClientStore_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "Misc.h"
#include "Unpack.h"
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size,
unsigned char *dst_data, int dst_size)
{
if (*src_data == 0)
{
if (dst_size != src_size - 1)
{
#ifdef TEST
*logofs << "UnpackColormap: PANIC! Invalid destination size "
<< dst_size << " with source " << src_size
<< ".\n" << logofs_flush;
#endif
return -1;
}
#ifdef TEST
*logofs << "UnpackColormap: Expanding " << src_size - 1
<< " bytes of plain colormap data.\n" << logofs_flush;
#endif
memcpy(dst_data, src_data + 1, src_size - 1);
return 1;
}
unsigned int check_size = dst_size;
int result = ZDecompress(&unpackStream, dst_data, &check_size,
src_data + 1, src_size - 1);
if (result != Z_OK)
{
#ifdef PANIC
*logofs << "UnpackColormap: PANIC! Failure decompressing colormap data. "
<< "Error is '" << zError(result) << "'.\n"
<< logofs_flush;
#endif
cerr << "Error" << ": Failure decompressing colormap data. "
<< "Error is '" << zError(result) << "'.\n";
return -1;
}
else if (check_size != (unsigned int) dst_size)
{
#ifdef PANIC
*logofs << "UnpackColormap: PANIC! Size mismatch in colormap data. "
<< "Resulting size is " << check_size << " with "
<< "expected size " << dst_size << ".\n"
<< logofs_flush;
#endif
cerr << "Error" << ": Size mismatch in colormap data. "
<< "Resulting size is " << check_size << " with "
<< "expected size " << dst_size << ".\n";
return -1;
}
#ifdef TEST
*logofs << "UnpackColormap: Decompressed " << src_size - 1
<< " bytes to " << dst_size << " bytes of colormap data.\n"
<< logofs_flush;
#endif
return 1;
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef Colormap_H
#define Colormap_H
int UnpackColormap(unsigned char method, unsigned char *src_data, int src_size,
unsigned char *dst_data, int dst_size);
#endif /* Colormap_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "ConfigureWindow.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Here are the methods to handle messages' content.
//
int ConfigureWindowStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message;
//
// Here is the fingerprint.
//
configureWindow -> window = GetULONG(buffer + 4, bigEndian);
configureWindow -> value_mask = GetUINT(buffer + 8, bigEndian);
//
// To increase effectiveness of the caching algorithm
// we remove the unused bytes carried in the data part.
//
if ((int) size > dataOffset)
{
#ifdef DEBUG
*logofs << name() << ": Removing unused bytes from the data payload.\n" << logofs_flush;
#endif
configureWindow -> value_mask &= (1 << 7) - 1;
unsigned int mask = 0x1;
unsigned char *source = (unsigned char *) buffer + CONFIGUREWINDOW_DATA_OFFSET;
unsigned long value = 0;
for (unsigned int i = 0; i < 7; i++)
{
if (configureWindow -> value_mask & mask)
{
value = GetULONG(source, bigEndian);
value &= (1 << CONFIGUREWINDOW_FIELD_WIDTH[i]) - 1;
PutULONG(value, source, bigEndian);
source += 4;
}
mask <<= 1;
}
}
#ifdef DEBUG
*logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
int ConfigureWindowStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message;
//
// Fill all the message's fields.
//
PutULONG(configureWindow -> window, buffer + 4, bigEndian);
PutUINT(configureWindow -> value_mask, buffer + 8, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
void ConfigureWindowStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
ConfigureWindowMessage *configureWindow = (ConfigureWindowMessage *) message;
*logofs << "ConfigureWindow: window " << configureWindow -> window
<< ", value_mask " << configureWindow -> value_mask
<< ", size " << configureWindow -> size_ << ".\n";
#endif
}
void ConfigureWindowStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
md5_append(md5_state_, buffer + 4, 4);
md5_append(md5_state_, buffer + 8, 2);
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef ConfigureWindow_H
#define ConfigureWindow_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define CONFIGUREWINDOW_ENABLE_CACHE 1
#define CONFIGUREWINDOW_ENABLE_DATA 0
#define CONFIGUREWINDOW_ENABLE_SPLIT 0
#define CONFIGUREWINDOW_ENABLE_COMPRESS 0
#define CONFIGUREWINDOW_DATA_LIMIT 32
#define CONFIGUREWINDOW_DATA_OFFSET 12
#define CONFIGUREWINDOW_CACHE_SLOTS 3000
#define CONFIGUREWINDOW_CACHE_THRESHOLD 5
#define CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class ConfigureWindowMessage : public Message
{
friend class ConfigureWindowStore;
public:
ConfigureWindowMessage()
{
}
~ConfigureWindowMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned int window;
unsigned short value_mask;
};
class ConfigureWindowStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
ConfigureWindowStore() : MessageStore()
{
enableCache = CONFIGUREWINDOW_ENABLE_CACHE;
enableData = CONFIGUREWINDOW_ENABLE_DATA;
enableSplit = CONFIGUREWINDOW_ENABLE_SPLIT;
enableCompress = CONFIGUREWINDOW_ENABLE_COMPRESS;
dataLimit = CONFIGUREWINDOW_DATA_LIMIT;
dataOffset = CONFIGUREWINDOW_DATA_OFFSET;
cacheSlots = CONFIGUREWINDOW_CACHE_SLOTS;
cacheThreshold = CONFIGUREWINDOW_CACHE_THRESHOLD;
cacheLowerThreshold = CONFIGUREWINDOW_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~ConfigureWindowStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "ConfigureWindow";
}
virtual unsigned char opcode() const
{
return X_ConfigureWindow;
}
virtual unsigned int storage() const
{
return sizeof(ConfigureWindowMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new ConfigureWindowMessage();
}
virtual Message *create(const Message &message) const
{
return new ConfigureWindowMessage((const ConfigureWindowMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (ConfigureWindowMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
};
#endif /* ConfigureWindow_H */
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#include "CopyArea.h"
#include "ClientCache.h"
#include "EncodeBuffer.h"
#include "DecodeBuffer.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
int CopyAreaStore::parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
CopyAreaMessage *copyArea = (CopyAreaMessage *) message;
//
// Here is the fingerprint.
//
copyArea -> src_drawable = GetULONG(buffer + 4, bigEndian);
copyArea -> dst_drawable = GetULONG(buffer + 8, bigEndian);
copyArea -> gcontext = GetULONG(buffer + 12, bigEndian);
copyArea -> src_x = GetUINT(buffer + 16, bigEndian);
copyArea -> src_y = GetUINT(buffer + 18, bigEndian);
copyArea -> dst_x = GetUINT(buffer + 20, bigEndian);
copyArea -> dst_y = GetUINT(buffer + 22, bigEndian);
copyArea -> width = GetUINT(buffer + 24, bigEndian);
copyArea -> height = GetUINT(buffer + 26, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Parsed Identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
int CopyAreaStore::unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const
{
CopyAreaMessage *copyArea = (CopyAreaMessage *) message;
//
// Fill all the message's fields.
//
PutULONG(copyArea -> src_drawable, buffer + 4, bigEndian);
PutULONG(copyArea -> dst_drawable, buffer + 8, bigEndian);
PutULONG(copyArea -> gcontext, buffer + 12, bigEndian);
PutUINT(copyArea -> src_x, buffer + 16, bigEndian);
PutUINT(copyArea -> src_y, buffer + 18, bigEndian);
PutUINT(copyArea -> dst_x, buffer + 20, bigEndian);
PutUINT(copyArea -> dst_y, buffer + 22, bigEndian);
PutUINT(copyArea -> width, buffer + 24, bigEndian);
PutUINT(copyArea -> height, buffer + 26, bigEndian);
#ifdef DEBUG
*logofs << name() << ": Unparsed identity for message at " << this << ".\n" << logofs_flush;
#endif
return 1;
}
void CopyAreaStore::dumpIdentity(const Message *message) const
{
#ifdef DUMP
CopyAreaMessage *copyArea = (CopyAreaMessage *) message;
*logofs << name() << ": Identity src_drawable " << copyArea -> src_drawable
<< ", dst_drawable " << copyArea -> dst_drawable << ", gcontext " << copyArea -> gcontext
<< ", src_x " << copyArea -> src_x << ", src_y " << copyArea -> src_y
<< ", dst_x " << copyArea -> dst_x << ", dst_y " << copyArea -> dst_y
<< ", width " << copyArea -> width << ", height " << copyArea -> height
<< ", size " << copyArea -> size_ << ".\n";
#endif
}
void CopyAreaStore::identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const
{
md5_append(md5_state_, buffer + 16, 12);
}
void CopyAreaStore::updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const
{
CopyAreaMessage *copyArea = (CopyAreaMessage *) message;
CopyAreaMessage *cachedCopyArea = (CopyAreaMessage *) cachedMessage;
ClientCache *clientCache = (ClientCache *) channelCache;
#ifdef TEST
*logofs << name() << ": Encoding value " << copyArea -> src_drawable
<< " as " << "src_drawable" << " field.\n" << logofs_flush;
#endif
encodeBuffer.encodeXidValue(copyArea -> src_drawable, clientCache -> drawableCache);
cachedCopyArea -> src_drawable = copyArea -> src_drawable;
#ifdef TEST
*logofs << name() << ": Encoding value " << copyArea -> dst_drawable
<< " as " << "dst_drawable" << " field.\n" << logofs_flush;
#endif
encodeBuffer.encodeXidValue(copyArea -> dst_drawable, clientCache -> drawableCache);
cachedCopyArea -> dst_drawable = copyArea -> dst_drawable;
#ifdef TEST
*logofs << name() << ": Encoding value " << copyArea -> gcontext
<< " as " << "gcontext" << " field.\n" << logofs_flush;
#endif
encodeBuffer.encodeXidValue(copyArea -> gcontext, clientCache -> gcCache);
cachedCopyArea -> gcontext = copyArea -> gcontext;
}
void CopyAreaStore::updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const
{
CopyAreaMessage *copyArea = (CopyAreaMessage *) message;
ClientCache *clientCache = (ClientCache *) channelCache;
unsigned int value;
decodeBuffer.decodeXidValue(value, clientCache -> drawableCache);
copyArea -> src_drawable = value;
#ifdef DEBUG
*logofs << name() << ": Decoded value " << copyArea -> src_drawable
<< " as " << "src_drawable" << " field.\n" << logofs_flush;
#endif
decodeBuffer.decodeXidValue(value, clientCache -> drawableCache);
copyArea -> dst_drawable = value;
#ifdef DEBUG
*logofs << name() << ": Decoded value " << copyArea -> dst_drawable
<< " as " << "dst_drawable" << " field.\n" << logofs_flush;
#endif
decodeBuffer.decodeXidValue(value, clientCache -> gcCache);
copyArea -> gcontext = value;
#ifdef DEBUG
*logofs << name() << ": Decoded value " << copyArea -> gcontext
<< " as gcontext field.\n" << logofs_flush;
#endif
}
/**************************************************************************/
/* */
/* Copyright (c) 2001, 2007 NoMachine, http://www.nomachine.com/. */
/* */
/* NXCOMP, NX protocol compression and NX extensions to this software */
/* are copyright of NoMachine. Redistribution and use of the present */
/* software is allowed according to terms specified in the file LICENSE */
/* which comes in the source distribution. */
/* */
/* Check http://www.nomachine.com/licensing.html for applicability. */
/* */
/* NX and NoMachine are trademarks of NoMachine S.r.l. */
/* */
/* All rights reserved. */
/* */
/**************************************************************************/
#ifndef CopyArea_H
#define CopyArea_H
#include "Message.h"
//
// Set the verbosity level.
//
#define PANIC
#define WARNING
#undef TEST
#undef DEBUG
#undef DUMP
//
// Set default values.
//
#define COPYAREA_ENABLE_CACHE 1
#define COPYAREA_ENABLE_DATA 0
#define COPYAREA_ENABLE_SPLIT 0
#define COPYAREA_ENABLE_COMPRESS 0
#define COPYAREA_DATA_LIMIT 0
#define COPYAREA_DATA_OFFSET 28
#define COPYAREA_CACHE_SLOTS 3000
#define COPYAREA_CACHE_THRESHOLD 5
#define COPYAREA_CACHE_LOWER_THRESHOLD 1
//
// The message class.
//
class CopyAreaMessage : public Message
{
friend class CopyAreaStore;
public:
CopyAreaMessage()
{
}
~CopyAreaMessage()
{
}
//
// Put here the fields which constitute
// the 'identity' part of the message.
//
private:
unsigned int src_drawable;
unsigned int dst_drawable;
unsigned int gcontext;
unsigned short src_x;
unsigned short src_y;
unsigned short dst_x;
unsigned short dst_y;
unsigned short width;
unsigned short height;
};
class CopyAreaStore : public MessageStore
{
//
// Constructors and destructors.
//
public:
CopyAreaStore() : MessageStore()
{
enableCache = COPYAREA_ENABLE_CACHE;
enableData = COPYAREA_ENABLE_DATA;
enableSplit = COPYAREA_ENABLE_SPLIT;
enableCompress = COPYAREA_ENABLE_COMPRESS;
dataLimit = COPYAREA_DATA_LIMIT;
dataOffset = COPYAREA_DATA_OFFSET;
cacheSlots = COPYAREA_CACHE_SLOTS;
cacheThreshold = COPYAREA_CACHE_THRESHOLD;
cacheLowerThreshold = COPYAREA_CACHE_LOWER_THRESHOLD;
messages_ -> resize(cacheSlots);
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
*i = NULL;
}
temporary_ = NULL;
}
virtual ~CopyAreaStore()
{
for (T_messages::iterator i = messages_ -> begin();
i < messages_ -> end(); i++)
{
destroy(*i);
}
destroy(temporary_);
}
virtual const char *name() const
{
return "CopyArea";
}
virtual unsigned char opcode() const
{
return X_CopyArea;
}
virtual unsigned int storage() const
{
return sizeof(CopyAreaMessage);
}
//
// Message handling methods.
//
public:
virtual Message *create() const
{
return new CopyAreaMessage();
}
virtual Message *create(const Message &message) const
{
return new CopyAreaMessage((const CopyAreaMessage &) message);
}
virtual void destroy(Message *message) const
{
delete (CopyAreaMessage *) message;
}
virtual int parseIdentity(Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual int unparseIdentity(const Message *message, unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void updateIdentity(EncodeBuffer &encodeBuffer, const Message *message,
const Message *cachedMessage,
ChannelCache *channelCache) const;
virtual void updateIdentity(DecodeBuffer &decodeBuffer, const Message *message,
ChannelCache *channelCache) const;
virtual void identityChecksum(const Message *message, const unsigned char *buffer,
unsigned int size, int bigEndian) const;
virtual void dumpIdentity(const Message *message) const;
};
#endif /* CopyArea_H */
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment