Ejemplo n.º 1
0
unsigned char *ReadBuffer::allocateBuffer(unsigned int newSize)
{
  unsigned char *newBuffer = new unsigned char[newSize];

  if (newBuffer == NULL)
  {
    #ifdef PANIC
    *logofs << "ReadBuffer: PANIC! Can't allocate "
            << newSize << " bytes of memory for buffer "
            << "in context [B].\n" << logofs_flush;
    #endif

    cerr << "Error" << ": Can't allocate memory for "
         << "read buffer in context [B].\n";

    HandleCleanup();
  }

  #ifdef VALGRIND

  memset(newBuffer, '\0', newSize);

  #endif

  return newBuffer;
}
Ejemplo n.º 2
0
int GenericChannel::handleCompletion(EncodeBuffer &encodeBuffer)
{
    //
    // Add the bits telling to the remote
    // that all data in the frame has been
    // encoded.
    //

    if (encodeBuffer.getLength() > 0)
    {
#if defined(TEST) || defined(INFO)
        *logofs << "handleCompletion: Writing completion bits with "
                << encodeBuffer.getLength() << " bytes encoded "
                << "for FD#" << fd_ << ".\n" << logofs_flush;
#endif

        encodeBuffer.encodeValue(0, 32, 14);

        return 1;
    }
#if defined(TEST) || defined(INFO)
    else
    {
        *logofs << "handleCompletion: PANIC! No completion to write "
                << "for FD#" << fd_ << ".\n" << logofs_flush;

        HandleCleanup();
    }
#endif

    return 0;
}
Ejemplo n.º 3
0
  int IApp::Run(void)
  {
    SLOG(App_Run,SeverityInfo) << std::endl;

    // First set our Running flag to true
    mRunning = true;

    // Register our App pointer with our StatManager
    mStatManager.RegisterApp(this);

    // Register our App pointer with our StateManager
    mStateManager.RegisterApp(this);

    // First register the IAssetHandler derived classes in the GQE Core library
    mAssetManager.RegisterHandler(new(std::nothrow) ConfigHandler());
    mAssetManager.RegisterHandler(new(std::nothrow) FontHandler());
    mAssetManager.RegisterHandler(new(std::nothrow) ImageHandler());
    mAssetManager.RegisterHandler(new(std::nothrow) MusicHandler());
    mAssetManager.RegisterHandler(new(std::nothrow) SoundHandler());

    // Give derived class a time to register custom IAssetHandler classes
    InitAssetHandlers();

    // Attempt to open the application wide settings.cfg file as a ConfigAsset
    // registered under the ID of "resources/settings.cfg"
    InitSettingsConfig();

    // Try to open the Renderer window to display graphics
    InitRenderer();

    // Give the derived application a chance to register a IScreenFactory class
    // to provide IScreen derived classes (previously known as IState derived
    // classes) as requested.
    InitScreenFactory();

    // Give the StatManager a chance to initialize
    mStatManager.DoInit();

    // GameLoop if Running flag is still true
    GameLoop();

    // Cleanup our application
    HandleCleanup();

    // Perform our own internal Cleanup
    Cleanup();

    // Make sure our Running flag is set to false before exiting
    mRunning = false;

    if(mExitCode < 0)
      SLOGR(App_Run,SeverityError) << "exitCode=" << mExitCode << std::endl;
    else
      SLOGR(App_Run,SeverityInfo) << "exitCode=" << mExitCode << std::endl;

    // Return the Exit Code specified by Quit or 0 of Quit was never called
    return mExitCode;
  }
Ejemplo n.º 4
0
void ReadBuffer::fullReset()
{
  #ifdef TEST

  if (owner_ == 0)
  {
    *logofs << "ReadBuffer: PANIC! Class for FD#"
            << transport_ -> fd() << " doesn't "
            << "appear to be the owner of the buffer "
            << "in reset.\n" << logofs_flush;

    HandleCleanup();
  }

  #endif

  if (length_ == 0 && size_ > maximumBufferSize_)
  {
    #ifdef TEST
    *logofs << "ReadBuffer: Resizing buffer for FD#"
            << transport_ -> fd() << " in reset from "
            << size_ << " to " << maximumBufferSize_
            << " bytes.\n" << logofs_flush;
    #endif

    delete [] buffer_;

    int newSize = maximumBufferSize_;

    unsigned char *newBuffer = allocateBuffer(newSize);

    buffer_ = newBuffer;
    size_   = newSize;

    transport_ -> pendingReset();

    owner_ = 1;
    start_ = 0;
  }
}
Ejemplo n.º 5
0
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();
  }
}
Ejemplo n.º 6
0
int GenericChannel::handleRead(EncodeBuffer &encodeBuffer, const unsigned char *message,
                               unsigned int length)
{
#ifdef TEST
    *logofs << "handleRead: Called for FD#" << fd_
            << " with " << encodeBuffer.getLength()
            << " bytes already encoded.\n"
            << logofs_flush;
#endif

    //
    // Pointer to located message and
    // its size in bytes.
    //

    const unsigned char *inputMessage;
    unsigned int inputLength;

    //
    // Tag message as generic data in compression
    // routine. Opcode is not actually transferred
    // over the network.
    //

    unsigned char inputOpcode = X_NXInternalGenericData;

#if defined(TEST) || defined(INFO)
    *logofs << "handleRead: Trying to read from FD#"
            << fd_ << " at " << strMsTimestamp() << ".\n"
            << logofs_flush;
#endif

    int result = readBuffer_.readMessage();

#ifdef DEBUG
    *logofs << "handleRead: Read result on FD#" << fd_
            << " is " << result << ".\n"
            << logofs_flush;
#endif

    if (result < 0)
    {
        //
        // Let the proxy close the channel.
        //

        return -1;
    }
    else if (result == 0)
    {
#if defined(TEST) || defined(INFO)

        *logofs << "handleRead: PANIC! No data read from FD#"
                << fd_ << " while encoding messages.\n"
                << logofs_flush;

        HandleCleanup();

#endif

        return 0;
    }

#if defined(TEST) || defined(INFO) || defined(FLUSH)
    *logofs << "handleRead: Encoding messages for FD#" << fd_
            << " with " << readBuffer_.getLength() << " bytes "
            << "in the buffer.\n" << logofs_flush;
#endif

    //
    // Divide the available data in multiple
    // messages and encode them one by one.
    //

    if (proxy -> handleAsyncSwitch(fd_) < 0)
    {
        return -1;
    }

    while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL)
    {
        encodeBuffer.encodeValue(inputLength, 32, 14);

        if (isCompressed() == 1)
        {
            unsigned int compressedDataSize = 0;
            unsigned char *compressedData   = NULL;

            if (handleCompress(encodeBuffer, inputOpcode, 0,
                               inputMessage, inputLength, compressedData,
                               compressedDataSize) < 0)
            {
                return -1;
            }
        }
        else
        {
            encodeBuffer.encodeMemory(inputMessage, inputLength);
        }

        int bits = encodeBuffer.diffBits();

#if defined(TEST) || defined(OPCODES)
        *logofs << "handleRead: Handled generic data for FD#" << fd_
                << ". " << inputLength << " bytes in, " << bits << " bits ("
                << ((float) bits) / 8 << " bytes) out.\n" << logofs_flush;
#endif

        addProtocolBits(inputLength << 3, bits);

        if (isPrioritized() == 1)
        {
            priority_++;
        }

    } // End of while ((inputMessage = readBuffer_.getMessage(inputLength)) != NULL) ...

    //
    // All data has been read from the read buffer.
    // We still need to mark the end of the encode
    // buffer just before sending the frame. This
    // allows us to accomodate multiple reads in
    // a single frame.
    //

    if (priority_ > 0)
    {
#if defined(TEST) || defined(INFO)
        *logofs << "handleRead: WARNING! Requesting flush "
                << "because of " << priority_ << " prioritized "
                << "messages for FD#" << fd_ << ".\n"
                << logofs_flush;
#endif

        if (proxy -> handleAsyncPriority() < 0)
        {
            return -1;
        }

        //
        // Reset the priority flag.
        //

        priority_ = 0;
    }

    //
    // Flush if we produced enough data.
    //

    if (proxy -> canAsyncFlush() == 1)
    {
#if defined(TEST) || defined(INFO)
        *logofs << "handleRead: WARNING! Requesting flush "
                << "because of enough data or timeout on the "
                << "proxy link.\n" << logofs_flush;
#endif

        if (proxy -> handleAsyncFlush() < 0)
        {
            return -1;
        }
    }

#if defined(TEST) || defined(INFO)

    if (transport_ -> pending() != 0 ||
            readBuffer_.checkMessage() != 0)
    {
        *logofs << "handleRead: PANIC! Buffer for X descriptor FD#"
                << fd_ << " has " << transport_ -> pending()
                << " bytes to read.\n" << logofs_flush;

        HandleCleanup();
    }

#endif

    //
    // Reset the read buffer.
    //

    readBuffer_.fullReset();

    return 1;
}
Ejemplo n.º 7
0
void ReadBuffer::readMessage(const unsigned char *message, unsigned int length)
{
  //
  // To be here we must be the real owner
  // of the buffer and there must not be
  // pending bytes in the transport.
  //

  #ifdef TEST

  if (owner_ == 0)
  {
    *logofs << "ReadBuffer: PANIC! Class for FD#"
            << transport_ -> fd() << " doesn't "
            << "appear to be the owner of the buffer "
            << "while borrowing from the caller.\n"
            << logofs_flush;

    HandleCleanup();
  }

  #endif

  //
  // Be sure that any outstanding data from
  // the transport is appended to our own
  // byffer.
  //

  if (transport_ -> pending() != 0)
  {
    #ifdef WARNING
    *logofs << "ReadBuffer: WARNING! Class for FD#"
            << transport_ -> fd() << " has pending "
            << "data in the transport while "
            << "borrowing from the caller.\n"
            << logofs_flush;
    #endif

    readMessage();

    if (owner_ == 0)
    {
      convertBuffer();
    }
  }

  //
  // Can't borrow the buffer if there is data
  // from a partial message. In this case add
  // the new data to the end of our buffer.
  //

  if (length_ == 0)
  {
    #ifdef TEST
    *logofs << "ReadBuffer: Borrowing " << length
            << " bytes from the caller for FD#"
            << transport_ -> fd() << " with "
            << length_ << " bytes in the buffer.\n"
            << logofs_flush;
    #endif

    delete [] buffer_;

    buffer_ = (unsigned char *) message;
    size_   = length;

    length_ = length;

    owner_ = 0;
    start_ = 0;
  }
  else
  {
    #ifdef TEST
    *logofs << "ReadBuffer: Appending " << length
            << " bytes from the caller for FD#"
            << transport_ -> fd() << " with "
            << length_ << " bytes in the buffer.\n"
            << logofs_flush;
    #endif

    appendBuffer(message, length);
  }
}
Ejemplo n.º 8
0
const unsigned char *ReadBuffer::getMessage(unsigned int &controlLength,
                                                unsigned int &dataLength)
{
  #ifdef TEST

  if (transport_ -> pending() > 0)
  {
    *logofs << "ReadBuffer: PANIC! The transport "
            << "appears to have data pending.\n"
            << logofs_flush;

    HandleCleanup();
  }

  #endif

  if (length_ == 0)
  {
    #ifdef DEBUG
    *logofs << "ReadBuffer: No message can be located "
            << "for FD#" << transport_ -> fd() << ".\n"
            << logofs_flush;
    #endif

    if (owner_ == 0)
    {
      buffer_ = NULL;
      size_   = 0;

      transport_ -> pendingReset();

      owner_ = 1;
      start_ = 0;
    }

    return NULL;
  }

  unsigned int trailerLength;

  #ifdef DEBUG
  *logofs << "ReadBuffer: Going to locate message with "
          << "start at " << start_ << " and length "
          << length_ << " for FD#" << transport_ -> fd()
          << ".\n" << logofs_flush;
  #endif

  int located = locateMessage(buffer_ + start_, buffer_ + start_ + length_,
                                  controlLength, dataLength, trailerLength);

  if (located == 0)
  {
    //
    // No more complete messages are in
    // the buffer.
    //

    #ifdef DEBUG
    *logofs << "ReadBuffer: No message was located "
            << "for FD#" << transport_ -> fd()
            << ".\n" << logofs_flush;
    #endif

    if (owner_ == 0)
    {
      //
      // Must move the remaining bytes in
      // our own buffer.
      //

      convertBuffer();
    }
  
    return NULL;
  }
  else
  {
    const unsigned char *result = buffer_ + start_;

    if (dataLength > 0)
    {
      //
      // Message contains data, so go to the
      // first byte of payload.
      //

      result += trailerLength;

      start_  += (dataLength + trailerLength);
      length_ -= (dataLength + trailerLength);
    }
    else
    {
      //
      // It is a control message.
      //

      start_  += (controlLength + trailerLength);
      length_ -= (controlLength + trailerLength);
    }

    #ifdef DEBUG
    *logofs << "ReadBuffer: Located message for FD#"
            << transport_ -> fd() << " with control length "
            << controlLength << " and data length "
            << dataLength << ".\n" << logofs_flush;
    #endif

    remaining_ = 0;

    return result;
  }
}
Ejemplo n.º 9
0
int ReadBuffer::readMessage()
{
  int pendingLength = transport_ -> pending();

  if (pendingLength > 0)
  {
    //
    // Can't move the data in the borrowed buffer,
    // so use the tansport buffer only if we don't
    // have any partial message. This can happen
    // with the proxy where we need to deflate the
    // stream.
    //

    if (length_ == 0)
    {
      unsigned char *newBuffer;

      length_ = transport_ -> getPending(newBuffer);

      if (newBuffer == NULL)
      {
        #ifdef PANIC
        *logofs << "ReadBuffer: PANIC! Failed to borrow "
                << length_ << " bytes of memory for buffer "
                << "in context [A].\n" << logofs_flush;
        #endif

        cerr << "Error" << ": Failed to borrow memory for "
             << "read buffer in context [A].\n";

        HandleCleanup();
      }

      delete [] buffer_;

      buffer_ = newBuffer;
      size_   = length_;

      owner_ = 0;
      start_ = 0;

      #ifdef TEST
      *logofs << "ReadBuffer: Borrowed " << length_
              << " pending bytes for FD#" << transport_ ->
                 fd() << ".\n" << logofs_flush;
      #endif

      return length_;
    }
    #ifdef TEST
    else
    {
      *logofs << "ReadBuffer: WARNING! Cannot borrow "
              << pendingLength << " bytes for FD#"
              << transport_ -> fd() << " with "
              << length_ << " bytes in the buffer.\n"
              << logofs_flush;
    }
    #endif
  }

  unsigned int readLength = suggestedLength(pendingLength);

  #ifdef DEBUG
  *logofs << "ReadBuffer: Requested " << readLength
          << " bytes for FD#" << transport_ -> fd()
          << " with readable " << transport_ -> readable()
          << " remaining " << remaining_ << " pending "
          << transport_ -> pending() << ".\n"
          << logofs_flush;
  #endif

  if (readLength < initialReadSize_)
  {
    readLength = initialReadSize_;
  }

  #ifdef DEBUG
  *logofs << "ReadBuffer: Buffer size is " << size_
          << " length " << length_ << " and start "
          << start_  << ".\n" << logofs_flush;
  #endif

  //
  // We can't use the transport buffer
  // to read our own data in it.
  //

  #ifdef TEST

  if (owner_ == 0)
  {
    *logofs << "ReadBuffer: PANIC! Class for FD#"
            << transport_ -> fd() << " doesn't "
            << "appear to be the owner of the buffer "
            << "while reading.\n" << logofs_flush;

    HandleCleanup();
  }

  #endif

  //
  // Be sure that we have enough space
  // to store all the requested data.
  //

  if (buffer_ == NULL || length_ + readLength > size_)
  {
    unsigned int newSize = length_ + readLength;

    #ifdef TEST
    *logofs << "ReadBuffer: Resizing buffer for FD#"
            << transport_ -> fd() << " in read from "
            << size_ << " to " << newSize << " bytes.\n"
            << logofs_flush;
    #endif

    unsigned char *newBuffer = allocateBuffer(newSize);

    memcpy(newBuffer, buffer_ + start_, length_);

    delete [] buffer_;

    buffer_ = newBuffer;
    size_   = newSize;

    transport_ -> pendingReset();

    owner_ = 1;
  }
  else if (start_ != 0 && length_ != 0)
  {
    //
    // If any bytes are left due to a partial
    // message, shift them to the beginning
    // of the buffer.
    //

    #ifdef TEST
    *logofs << "ReadBuffer: Moving " << length_
            << " bytes of data " << "at beginning of "
            << "the buffer for FD#" << transport_ -> fd() 
            << ".\n" << logofs_flush;
    #endif

    memmove(buffer_, buffer_ + start_, length_);
  }

  start_ = 0;

  #ifdef DEBUG
  *logofs << "ReadBuffer: Buffer size is now " << size_ 
          << " length is " << length_ << " and start is " 
          << start_ << ".\n" << logofs_flush;
  #endif

  unsigned char *readData = buffer_ + length_;

  #ifdef DEBUG
  *logofs << "ReadBuffer: Going to read " << readLength 
          << " bytes from FD#" << transport_ -> fd() << ".\n"
          << logofs_flush;
  #endif

  int bytesRead = transport_ -> read(readData, readLength);

  if (bytesRead > 0)
  {
    #ifdef TEST
    *logofs << "ReadBuffer: Read " << bytesRead
            << " bytes from FD#" << transport_ -> fd()
            << ".\n" << logofs_flush;
    #endif

    length_ += bytesRead;
  }
  else if (bytesRead < 0)
  {
    //
    // Check if there is more data pending than the
    // size of the provided buffer. After reading
    // the requested amount, in fact, the transport
    // may have decompressed the data and produced
    // more input. This trick allows us to always
    // borrow the buffer from the transport, even
    // when the partial read would have prevented
    // that.
    //

    if (transport_ -> pending() > 0)
    {
      #ifdef TEST
      *logofs << "ReadBuffer: WARNING! Trying to read some "
              << "more with " << transport_ -> pending()
              << " bytes pending for FD#" << transport_ ->
                 fd() << ".\n" << logofs_flush;
      #endif

      return readMessage();
    }

    #ifdef TEST
    *logofs << "ReadBuffer: Error detected reading "
            << "from FD#" << transport_ -> fd()
            << ".\n" << logofs_flush;
    #endif

    return -1;
  }
  #ifdef TEST
  else
  {
    *logofs << "ReadBuffer: No data read from FD#"
            << transport_ -> fd() << " with remaining "
            << remaining_ << ".\n" << logofs_flush;
  }
  #endif

  return bytesRead;
}
Ejemplo n.º 10
0
NXConnection::~NXConnection()
{
  NX_LOG_LOGDEBUG( "NXConnection's destructor called.");
  HandleCleanup();
}