<commit_before>/**
 * A class which describes the properties and actions of a client application.
 *
 * @date                    December 25, 2014
 * @author                  <NAME>
 * @version                 0.1
 *
 * Copyright 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <vector>
#include <unistd.h>
#include <netinet/in.h>

// Application dependencies.
#include <ias/application/client/model/client_application_model.h>
#include <ias/network/posix/posix_tcp_socket.h>
#include <ias/network/posix/ssl/posix_ssl_socket.h>
#include <ias/network/proxy/socks.h>
#include <ias/network/util.h>
#include <ias/user/command/command_stop.h>

// END Includes. /////////////////////////////////////////////////////

// BEGIN Constants. //////////////////////////////////////////////////

const char ClientApplicationModel::kCommandQuit[] = "quit";

// END Constants. ////////////////////////////////////////////////////

void ClientApplicationModel::initialize( void ) {
    mSocket = nullptr;
    mSslContext = nullptr;
    mSocksHost.clear();
    mSocksPort = 0;
    mLoggedIn = false;
    mCommunicationThreadSend = nullptr;
    mCommunicationThreadReceive = nullptr;
}

void ClientApplicationModel::setSocketTimeouts( void ) {
    struct timeval tv;

    // Checking the precondition.
    assert( mSocket != nullptr );

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    mSocket->setReceiveTimeout(tv);
}

int ClientApplicationModel::connectToSocksProxy( const std::string & host,
                                                 const std::size_t port ) const {
    int fd;

    fd = connectToSocks(mSocksHost,mSocksPort,host,port);

    return ( fd );
}

void ClientApplicationModel::readResponses( void ) {
    std::uint8_t messageType;
    Reader * reader;

    // Checking the precondition.
    assert( mSocket->isConnected() );

    reader = mSocket->getReader();
    messageType = 0xff;
    if( reader->readBytes(reinterpret_cast<char *>(&messageType),1) == 1 ) {
        switch(messageType) {
        case 0x00:
            sendHeartbeat();
            break;
        case 0x01:
            readResponse();
            break;
        }
    }
}

void ClientApplicationModel::sendHeartbeat( void ) {
    static const std::uint8_t beat = 0x00;
    Writer * writer;

    // Checking the precondition.
    assert( isConnected() );

    mSendMutex.lock();
    writer = mSocket->getWriter();
    writer->writeBytes(reinterpret_cast<const char *>(&beat),1);
    mSendMutex.unlock();
}

void ClientApplicationModel::readResponse( void ) {
    Reader * reader;
    std::uint16_t messageSize;

    // Checking the precondition.
    assert( mSocket->isConnected() );

    reader = mSocket->getReader();
    messageSize = 0;
    reader->readBytes(reinterpret_cast<char *>(&messageSize),
                      sizeof(messageSize));
    messageSize = ntohs(messageSize);
    char buffer[messageSize + 1];
    reader->readBytes(buffer,static_cast<std::size_t>(messageSize));
    buffer[messageSize] = 0;
    notifyObservers(buffer);
}

void ClientApplicationModel::stopCommunicationThreads( void ) {
    if( mCommunicationThreadSend != nullptr ) {
        mSendLock.notify_one();
        mCommunicationThreadSend->join();
        delete mCommunicationThreadSend;
        mCommunicationThreadSend = nullptr;
    }
    if( mCommunicationThreadReceive != nullptr ) {
        mCommunicationThreadReceive->join();
        delete mCommunicationThreadReceive;
        mCommunicationThreadReceive = nullptr;
    }
}

void ClientApplicationModel::spawnCommunicationThreads( void ) {<commit_msg>Fix precondition failure.<commit_after>/**
 * A class which describes the properties and actions of a client application.
 *
 * @date                    December 25, 2014
 * @author                  <NAME>
 * @version                 0.1
 *
 * Copyright 2014 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// BEGIN Includes. ///////////////////////////////////////////////////

// System dependencies.
#include <cassert>
#include <vector>
#include <unistd.h>
#include <netinet/in.h>

// Application dependencies.
#include <ias/application/client/model/client_application_model.h>
#include <ias/network/posix/posix_tcp_socket.h>
#include <ias/network/posix/ssl/posix_ssl_socket.h>
#include <ias/network/proxy/socks.h>
#include <ias/network/util.h>
#include <ias/user/command/command_stop.h>

// END Includes. /////////////////////////////////////////////////////

// BEGIN Constants. //////////////////////////////////////////////////

const char ClientApplicationModel::kCommandQuit[] = "quit";

// END Constants. ////////////////////////////////////////////////////

void ClientApplicationModel::initialize( void ) {
    mSocket = nullptr;
    mSslContext = nullptr;
    mSocksHost.clear();
    mSocksPort = 0;
    mLoggedIn = false;
    mCommunicationThreadSend = nullptr;
    mCommunicationThreadReceive = nullptr;
}

void ClientApplicationModel::setSocketTimeouts( void ) {
    struct timeval tv;

    // Checking the precondition.
    assert( mSocket != nullptr );

    tv.tv_sec = 1;
    tv.tv_usec = 0;
    mSocket->setReceiveTimeout(tv);
}

int ClientApplicationModel::connectToSocksProxy( const std::string & host,
                                                 const std::size_t port ) const {
    int fd;

    fd = connectToSocks(mSocksHost,mSocksPort,host,port);

    return ( fd );
}

void ClientApplicationModel::readResponses( void ) {
    std::uint8_t messageType;
    Reader * reader;

    // Checking the precondition.
    assert( mSocket->isConnected() );

    reader = mSocket->getReader();
    messageType = 0xff;
    if( reader->readBytes(reinterpret_cast<char *>(&messageType),1) == 1 ) {
        switch(messageType) {
        case 0x00:
            sendHeartbeat();
            break;
        case 0x01:
            readResponse();
            break;
        }
    }
}

void ClientApplicationModel::sendHeartbeat( void ) {
    static const std::uint8_t beat = 0x00;
    Writer * writer;

    // Checking the precondition.
    assert( isConnected() );

    mSendMutex.lock();
    writer = mSocket->getWriter();
    writer->writeBytes(reinterpret_cast<const char *>(&beat),1);
    mSendMutex.unlock();
}

void ClientApplicationModel::readResponse( void ) {
    Reader * reader;
    std::uint16_t messageSize;

    if( mSocket->isConnected() ) {
        reader = mSocket->getReader();
        messageSize = 0;
        reader->readBytes(reinterpret_cast<char *>(&messageSize),
                          sizeof(messageSize));
        messageSize = ntohs(messageSize);
        char buffer[messageSize + 1];
        reader->readBytes(buffer,static_cast<std::size_t>(messageSize));
        buffer[messageSize] = 0;
        notifyObservers(buffer);
    }
}

void ClientApplicationModel::stopCommunicationThreads( void ) {
    if( mCommunicationThreadSend != nullptr ) {
        mSendLock.notify_one();
        mCommunicationThreadSend->join();
        delete mCommunicationThreadSend;
        mCommunicationThreadSend = nullptr;
    }
    if( mCommunicationThreadReceive != nullptr ) {
        mCommunicationThreadReceive->join();
        delete mCommunicationThreadReceive;
        mCommunicationThreadReceive = nullptr;
    }
}

void ClientApplicationModel::spawnCommunicationThreads( void ) {
{'fraction_non_alphanumeric': 0.15152590489709014, 'fraction_numerical': 0.009226401703335699, 'mean_word_length': 2.508298755186722, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3749080', 'n_tokens_mistral': 2436, 'n_tokens_neox': 2317, 'n_words': 575}