<commit_before>/*
Copyright 2017 Google Inc.

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

    https://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.
*/

#include <grpc++/grpc++.h>

#include <getopt.h>

#include <chrono>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <thread>
#include <iostream>
#include <fstream>
#include <sstream>

#include "google/assistant/embedded/v1alpha2/embedded_assistant.pb.h"
#include "google/assistant/embedded/v1alpha2/embedded_assistant.grpc.pb.h"

#include "assistant_config.h"
#include "audio_input.h"
#include "audio_input_file.h"
#include "base64_encode.h"
#include "json_util.h"

using google::assistant::embedded::v1alpha2::EmbeddedAssistant;
using google::assistant::embedded::v1alpha2::AssistRequest;
using google::assistant::embedded::v1alpha2::AssistResponse;
using google::assistant::embedded::v1alpha2::AudioInConfig;
using google::assistant::embedded::v1alpha2::AudioOutConfig;
using google::assistant::embedded::v1alpha2::AssistResponse_EventType_END_OF_UTTERANCE;

using grpc::CallCredentials;
using grpc::Channel;
using grpc::ClientReaderWriter;

static const std::string kCredentialsTypeUserAccount = "USER_ACCOUNT";
static const std::string kLanguageCode = "en-US";
static const std::string kDeviceModelId = "default";
static const std::string kDeviceInstanceId = "default";

bool verbose = false;

// Creates a channel to be connected to Google.
std::shared_ptr<Channel> CreateChannel(const std::string& host) {
  std::ifstream file("robots.pem");
  std::stringstream buffer;
  buffer << file.rdbuf();
  std::string roots_pem = buffer.str();

  if (verbose) {
    std::clog << "assistant_sdk robots_pem: " << roots_pem << std::endl;
  }
  ::grpc::SslCredentialsOptions ssl_opts = {roots_pem, "", ""};
  auto creds = ::grpc::SslCredentials(ssl_opts);
  std::string server = host + ":443";
  if (verbose) {
    std::clog << "assistant_sdk CreateCustomChannel(" << server << ", creds, arg)"
      << std::endl << std::endl;
  }
  ::grpc::ChannelArguments channel_args;
  return CreateCustomChannel(server, creds, channel_args);
}

void PrintUsage() {
  std::cerr << "Usage: ./run_assistant_file "
            << "--input <audio_file> "
            << "--output <audio_file> "
            << "--credentials <credentials_file> "
            << "[--api_endpoint <API endpoint>] "
            << "[--locale <locale>]"
            << std::endl;
}

bool GetCommandLineFlags(
    int argc, char** argv, std::string* audio_input, std::string* audio_output,
    std::string* credentials_file_path, std::string* api_endpoint,
    std::string* locale) {
  const struct option long_options[] = {
    {"input",      required_argument, nullptr, 'i'},
    {"output",      required_argument, nullptr, 'o'},
    {"credentials", required_argument, nullptr, 'c'},
    {"api_endpoint",     required_argument, nullptr, 'e'},
    {"locale",           required_argument, nullptr, 'l'},
    {"verbose",          no_argument, nullptr, 'v'},
    {nullptr, 0, nullptr, 0}
  };
  *api_endpoint = ASSISTANT_ENDPOINT;
  while (true) {
    int option_index;
    int option_char =
        getopt_long(argc, argv, "i:o:c:e:l:v", long_options, &option_index);
    if (option_char == -1) {
      break;
    }
    switch (option_char) {
      case 'i':
        *audio_input = optarg;
        break;
      case 'o':
        *audio_output = optarg;
        break;
      case 'c':
        *credentials_file_path = optarg;
        break;
      case 'e':
        *api_endpoint = optarg;
        break;
      case 'l':
        *locale = optarg;
        break;
      case 'v':
        verbose = true;
        break;
      default:
        PrintUsage();
        return false;
    }
  }
  return true;
}

int main(int argc, char** argv) {
  std::string audio_input_source, audio_output_source, credentials_file_path,
              api_endpoint, locale;
  // Initialize gRPC and DNS resolvers
  // https://github.com/grpc/grpc/issues/11366#issuecomment-328595941
  grpc_init();
  if (!GetCommandLineFlags(argc, argv, &audio_input_source, &audio_output_source, &credentials_file_path,
                          &api_endpoint, &locale)) {
    return -1;
  }

  // Create an AssistRequest
  AssistRequest request;
  auto* assist_config = request.mutable_config();

  if (locale.empty()) {
    locale = kLanguageCode; // Default locale
  }
  if (verbose) {
    std::clog << "Using locale " << locale << std::endl;
  }
  // Set the DialogStateIn of the AssistRequest
  assist_config->mutable_dialog_state_in()->set_language_code(locale);

  // Set the DeviceConfig of the AssistRequest
  assist_config->mutable_device_config()->set_device_id(kDeviceInstanceId);
  assist_config->mutable_device_config()->set_device_model_id(kDeviceModelId);

  // Set parameters for audio output
  assist_config->mutable_audio_out_config()->set_encoding(
    AudioOutConfig::LINEAR16);
  assist_config->mutable_audio_out_config()->set_sample_rate_hertz(16000);

  std::unique_ptr<AudioInput> audio_input;
  if (!audio_input_source.empty()) {
    // Set the AudioInConfig of the AssistRequest
    assist_config->mutable_audio_in_config()->set_encoding(
      AudioInConfig::LINEAR16);
    assist_config->mutable_audio_in_config()->set_sample_rate_hertz(16000);
  } else {
    std::cerr << "requires --input" << std::endl;
    return -1;
  }

  // Read credentials file.
  std::ifstream credentials_file(credentials_file_path);
  if (!credentials_file) {
    std::cerr << "Credentials file \"" << credentials_file_path
              << "\" does not exist." << std::endl;
    return -1;
  }
  std::stringstream credentials_buffer;
  credentials_buffer << credentials_file.rdbuf();
  std::string credentials = credentials_buffer.str();
  std::shared_ptr<CallCredentials> call_credentials;
  call_credentials = grpc::GoogleRefreshTokenCredentials(credentials);
  if (call_credentials.get() == nullptr) {
    std::cerr << "Credentials file \"" << credentials_file_path
              << "\" is invalid. Check step 5 in README for how to get valid "
              << "credentials." << std::endl;
    return -1;
  }

  // Begin a stream.
  auto channel = CreateChannel(api_endpoint);
  std::unique_ptr<EmbeddedAssistant::Stub> assistant(
      EmbeddedAssistant::NewStub(channel));

  grpc::ClientContext context;
  context.set_fail_fast(false);
  context.set_credentials(call_credentials);

  std::shared_ptr<ClientReaderWriter<AssistRequest, AssistResponse>>
      stream(std::move(assistant->Assist(&context)));
  // Write config in first stream.
  if (verbose) {
    std::clog << "assistant_sdk wrote first request: "
              << request.ShortDebugString() << std::endl;
  }
  stream->Write(request);

  std::ifstream audio_file(audio_input_source);
  if (!audio_file) {
    std::cerr << "Audio input file \"" << audio_input_source
              << "\" does not exist." << std::endl;
    return -1;
  }
  audio_input.reset(new AudioInputFile(audio_input_source));

  audio_input->AddDataListener(
    [stream, &request](std::shared_ptr<std::vector<unsigned char>> data) {
      request.set_audio_in(&((*data)[0]), data->size());
      stream->Write(request);
  });
  audio_input->AddStopListener([stream]() {
    stream->WritesDone();
  });
  audio_input->Start();

  // Read responses.
  if (verbose) {
    std::clog << "assistant_sdk waiting for response ... " << std::endl;
  }
  AssistResponse response;
  while (stream->Read(&response)) {  // Returns false when no more to read.
    if (response.has_audio_out() ||
        response.event_type() == AssistResponse_EventType_END_OF_UTTERANCE) {
      // Synchronously stops audio input if there is one.
      if (audio_input != nullptr && audio_input->IsRunning()) {
        audio_input->Stop();
      }
    }
    // CUSTOMIZE: render spoken request on screen
    for (int i = 0; i < response.speech_results_size(); i++) {
      google::assistant::embedded::v1alpha2::SpeechRecognitionResult result =
          response.speech_results(i);
      if (verbose) {
        std::clog << "assistant_sdk request: \n"
                  << result.transcript() << " ("
                  << std::to_string(result.stability())
                  << ")" << std::endl;
      }
    }
    if (response.dialog_state_out().supplemental_display_text().size() > 0) {
      // CUSTOMIZE: render spoken response on screen
      std::clog << "assistant_sdk response:" << std::endl;
      std::cout << response.dialog_state_out().supplemental_display_text()
                << std::endl;
    }
  }

  grpc::Status status = stream->Finish();
  if (!status.ok()) {
    // Report the RPC failure.
    std::cerr << "assistant_sdk failed, error: "
              << status.error_message() << std::endl;
    return -1;
  }

  return 0;
}
<commit_msg>Adds file output parameter to save audio data<commit_after>/*
Copyright 2017 Google Inc.

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

    https://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.
*/

#include <grpc++/grpc++.h>

#include <getopt.h>

#include <chrono>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <thread>
#include <iostream>
#include <fstream>
#include <sstream>

#include "google/assistant/embedded/v1alpha2/embedded_assistant.pb.h"
#include "google/assistant/embedded/v1alpha2/embedded_assistant.grpc.pb.h"

#include "assistant_config.h"
#include "audio_input.h"
#include "audio_input_file.h"
#include "base64_encode.h"
#include "json_util.h"

using google::assistant::embedded::v1alpha2::EmbeddedAssistant;
using google::assistant::embedded::v1alpha2::AssistRequest;
using google::assistant::embedded::v1alpha2::AssistResponse;
using google::assistant::embedded::v1alpha2::AudioInConfig;
using google::assistant::embedded::v1alpha2::AudioOutConfig;
using google::assistant::embedded::v1alpha2::AssistResponse_EventType_END_OF_UTTERANCE;

using grpc::CallCredentials;
using grpc::Channel;
using grpc::ClientReaderWriter;

static const std::string kCredentialsTypeUserAccount = "USER_ACCOUNT";
static const std::string kLanguageCode = "en-US";
static const std::string kDeviceModelId = "default";
static const std::string kDeviceInstanceId = "default";

bool verbose = false;

// Creates a channel to be connected to Google.
std::shared_ptr<Channel> CreateChannel(const std::string& host) {
  std::ifstream file("robots.pem");
  std::stringstream buffer;
  buffer << file.rdbuf();
  std::string roots_pem = buffer.str();

  if (verbose) {
    std::clog << "assistant_sdk robots_pem: " << roots_pem << std::endl;
  }
  ::grpc::SslCredentialsOptions ssl_opts = {roots_pem, "", ""};
  auto creds = ::grpc::SslCredentials(ssl_opts);
  std::string server = host + ":443";
  if (verbose) {
    std::clog << "assistant_sdk CreateCustomChannel(" << server << ", creds, arg)"
      << std::endl << std::endl;
  }
  ::grpc::ChannelArguments channel_args;
  return CreateCustomChannel(server, creds, channel_args);
}

void PrintUsage() {
  std::cerr << "Usage: ./run_assistant_file "
            << "--input <audio_file> "
            << "--output <audio_file> "
            << "--credentials <credentials_file> "
            << "[--api_endpoint <API endpoint>] "
            << "[--locale <locale>]"
            << std::endl;
}

bool GetCommandLineFlags(
    int argc, char** argv, std::string* audio_input, std::string* audio_output,
    std::string* credentials_file_path, std::string* api_endpoint,
    std::string* locale) {
  const struct option long_options[] = {
    {"input",      required_argument, nullptr, 'i'},
    {"output",      required_argument, nullptr, 'o'},
    {"credentials", required_argument, nullptr, 'c'},
    {"api_endpoint",     required_argument, nullptr, 'e'},
    {"locale",           required_argument, nullptr, 'l'},
    {"verbose",          no_argument, nullptr, 'v'},
    {nullptr, 0, nullptr, 0}
  };
  *api_endpoint = ASSISTANT_ENDPOINT;
  while (true) {
    int option_index;
    int option_char =
        getopt_long(argc, argv, "i:o:c:e:l:v", long_options, &option_index);
    if (option_char == -1) {
      break;
    }
    switch (option_char) {
      case 'i':
        *audio_input = optarg;
        break;
      case 'o':
        *audio_output = optarg;
        break;
      case 'c':
        *credentials_file_path = optarg;
        break;
      case 'e':
        *api_endpoint = optarg;
        break;
      case 'l':
        *locale = optarg;
        break;
      case 'v':
        verbose = true;
        break;
      default:
        PrintUsage();
        return false;
    }
  }
  return true;
}

int main(int argc, char** argv) {
  std::string audio_input_source, audio_output_source, credentials_file_path,
              api_endpoint, locale;
  // Initialize gRPC and DNS resolvers
  // https://github.com/grpc/grpc/issues/11366#issuecomment-328595941
  grpc_init();
  if (!GetCommandLineFlags(argc, argv, &audio_input_source, &audio_output_source, &credentials_file_path,
                          &api_endpoint, &locale)) {
    return -1;
  }

  // Create an AssistRequest
  AssistRequest request;
  auto* assist_config = request.mutable_config();

  if (locale.empty()) {
    locale = kLanguageCode; // Default locale
  }
  if (verbose) {
    std::clog << "Using locale " << locale << std::endl;
  }
  // Set the DialogStateIn of the AssistRequest
  assist_config->mutable_dialog_state_in()->set_language_code(locale);

  // Set the DeviceConfig of the AssistRequest
  assist_config->mutable_device_config()->set_device_id(kDeviceInstanceId);
  assist_config->mutable_device_config()->set_device_model_id(kDeviceModelId);

  // Set parameters for audio output
  assist_config->mutable_audio_out_config()->set_encoding(
    AudioOutConfig::LINEAR16);
  assist_config->mutable_audio_out_config()->set_sample_rate_hertz(16000);

  if (audio_input_source.empty()) {
    std::cerr << "requires --input" << std::endl;
    return -2;
  }
  // Make sure the input file exists
  std::ifstream audio_input_file(audio_input_source);
  if (!audio_input_file) {
      std::cerr << "Audio input file \"" << audio_input_source
              << "\" does not exist." << std::endl;
      return -2;
  }
  if (audio_output_source.empty()) {
    std::clog << "requires --output" << std::endl;
    return -3;
  }

  std::unique_ptr<AudioInput> audio_input;
  // Set the AudioInConfig of the AssistRequest
  assist_config->mutable_audio_in_config()->set_encoding(
    AudioInConfig::LINEAR16);
  assist_config->mutable_audio_in_config()->set_sample_rate_hertz(16000);

  // Read credentials file.
  std::ifstream credentials_file(credentials_file_path);
  if (!credentials_file) {
    std::cerr << "Credentials file \"" << credentials_file_path
              << "\" does not exist." << std::endl;
    return -1;
  }
  std::stringstream credentials_buffer;
  credentials_buffer << credentials_file.rdbuf();
  std::string credentials = credentials_buffer.str();
  std::shared_ptr<CallCredentials> call_credentials;
  call_credentials = grpc::GoogleRefreshTokenCredentials(credentials);
  if (call_credentials.get() == nullptr) {
    std::cerr << "Credentials file \"" << credentials_file_path
              << "\" is invalid. Check step 5 in README for how to get valid "
              << "credentials." << std::endl;
    return -1;
  }

  // Begin a stream.
  auto channel = CreateChannel(api_endpoint);
  std::unique_ptr<EmbeddedAssistant::Stub> assistant(
      EmbeddedAssistant::NewStub(channel));

  grpc::ClientContext context;
  context.set_fail_fast(false);
  context.set_credentials(call_credentials);

  std::shared_ptr<ClientReaderWriter<AssistRequest, AssistResponse>>
      stream(std::move(assistant->Assist(&context)));
  // Write config in first stream.
  if (verbose) {
    std::clog << "assistant_sdk wrote first request: "
              << request.ShortDebugString() << std::endl;
  }
  stream->Write(request);

  audio_input.reset(new AudioInputFile(audio_input_source));

  audio_input->AddDataListener(
    [stream, &request](std::shared_ptr<std::vector<unsigned char>> data) {
      request.set_audio_in(&((*data)[0]), data->size());
      stream->Write(request);
  });
  audio_input->AddStopListener([stream]() {
    stream->WritesDone();
  });
  audio_input->Start();

  // Read responses.
  if (verbose) {
    std::clog << "assistant_sdk waiting for response ... " << std::endl;
  }
  AssistResponse response;

  // Create an audio file to store the response
  std::ofstream audio_output_file;
  // Make sure to rewrite contents of file
  audio_output_file.open(audio_output_source, std::ofstream::out | std::ofstream::trunc);
  // Check whether file was opened correctly
  if (audio_output_file.fail()) {
    std::cerr << "error opening file " << audio_output_source << std::endl;
    return -3;
  }
  if (verbose) {
    std::clog << "assistant_sdk writing audio response to " << audio_output_source << std::endl;
  }

  while (stream->Read(&response)) {  // Returns false when no more to read.
    if (response.has_audio_out() ||
        response.event_type() == AssistResponse_EventType_END_OF_UTTERANCE) {
      // Synchronously stops audio input if there is one.
      if (audio_input != nullptr && audio_input->IsRunning()) {
        audio_input->Stop();
      }
    }
    if (response.has_audio_out()) {
      audio_output_file << response.audio_out().audio_data();
    }
    // CUSTOMIZE: render spoken request on screen
    for (int i = 0; i < response.speech_results_size(); i++) {
      google::assistant::embedded::v1alpha2::SpeechRecognitionResult result =
          response.speech_results(i);
      if (verbose) {
        std::clog << "assistant_sdk request: \n"
                  << result.transcript() << " ("
                  << std::to_string(result.stability())
                  << ")" << std::endl;
      }
    }
    if (response.dialog_state_out().supplemental_display_text().size() > 0) {
      // CUSTOMIZE: render spoken response on screen
      std::clog << "assistant_sdk response:" << std::endl;
      std::cout << response.dialog_state_out().supplemental_display_text()
                << std::endl;
    }
  }
  audio_input_file.close();
  audio_output_file.close();

  grpc::Status status = stream->Finish();
  if (!status.ok()) {
    // Report the RPC failure.
    std::cerr << "assistant_sdk failed, error: " <<
              status.error_message() << std::endl;
    return -1;
  }

  return 0;
}<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "llbc/common/Export.h"
#include "llbc/common/BeforeIncl.h"

#include "llbc/core/helper/STLHelper.h"
#include "llbc/core/file/File.h"
#include "llbc/core/utils/Util_Text.h"
#include "llbc/core/helper/JVHelper.h"

#include "llbc/core/config/Config.h"

__LLBC_NS_BEGIN

LLBC_Config::LLBC_Config()
{
    _errMsg = "OK";
}

LLBC_Config::~LLBC_Config()
{
    LLBC_STLHelper::DeleteContainer(_values);
}

int LLBC_Config::AddFile(const LLBC_String &file)
{
    if (file.empty())
    {
        LLBC_SetLastError(LLBC_ERROR_ARG);
        return LLBC_FAILED;
    }

    std::map<LLBC_String, LLBC_JsonValue *>::iterator iter = _values.find(file);
    if (iter != _values.end())
    {
        delete iter->second;
        iter->second = NULL;
    }
    else
    {
        _values[file] = NULL;
    }

    return LLBC_OK;
}

int LLBC_Config::Initialize()
{
    std::map<LLBC_String, LLBC_JsonValue *>::iterator iter = _values.begin();
    for (; iter != _values.end(); iter ++)
    {
        LLBC_XDelete(iter->second);
    }

    iter = _values.begin();
    for (; iter != _values.end(); iter ++)
    {
        const LLBC_String &fileName = iter->first;

        LLBC_File file(fileName, LLBC_FileMode::BinaryRead);
        if (!file.IsOpened())
        {
            BuildErrMsg(fileName, LLBC_FormatLastError());
            return LLBC_FAILED;
        }

        LLBC_String content = file.ReadToEnd();

        Json::Reader reader;
        LLBC_JsonValue *value = new LLBC_JsonValue;
        if (!reader.parse(content, *value))
        {
            delete value;

            BuildErrMsg(fileName, reader.getFormatedErrorMessages().c_str());
            LLBC_SetLastError(LLBC_ERROR_INVALID);

            return LLBC_FAILED;
        }

        iter->second = value;
    }

    _errMsg = "OK";

    return LLBC_OK;
}

const LLBC_String &LLBC_Config::GetError() const
{
    return _errMsg;
}

LLBC_JsonValue LLBC_Config::GetJsonValue(const LLBC_String &file, const char *field) const
{
    if (!field)
    {
        field = ".";
    }

    std::map<LLBC_String, LLBC_JsonValue *>::const_iterator iter = _values.find(file);
    if (iter == _values.end() || !iter->second)
    {
        LLBC_SetLastError(LLBC_ERROR_NOT_FOUND);
        return LLBC_JsonValue();
    }

    LLBC_SetLastError(LLBC_ERROR_SUCCESS);

    Json::Path path(field);
    return path.make(*iter->second);
}

std::vector<LLBC_JsonValue> LLBC_Config::GetJsonValueArray(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::vector<LLBC_JsonValue>();
    }

    std::vector<LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter ++)
    {
        values.push_back(*jsonIter);
    }

    return values;
}

std::map<int, LLBC_JsonValue> LLBC_Config::GetIntJsonMap(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::map<int, LLBC_JsonValue>();
    }

    std::map<int, LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter ++)
    {
        const LLBC_JsonValue &key = jsonIter.key();
        values[LLBC_Str2Int32(key.asCString())] = *jsonIter;
    }

    return values;
}

std::map<LLBC_String, LLBC_JsonValue> LLBC_Config::GetStringJsonMap(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::map<LLBC_String, LLBC_JsonValue>();
    }

    std::map<LLBC_String, LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter ++)
    {
        const LLBC_JsonValue &key = jsonIter.key();
        values[key.asCString()] = *jsonIter;
    }

    return values;
}

LLBC_Variant LLBC_Config::GetVariantValue(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue json = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return LLBC_Variant();
    }

    return LLBC_JVHelper::J2V(json);
}

std::vector<LLBC_Variant> LLBC_Config::GetVariantValueArray(const LLBC_String &file, const char *field) const
{
    std::vector<LLBC_JsonValue> jsons = GetJsonValueArray(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::vector<LLBC_Variant>();
    }

    std::vector<LLBC_Variant> variants;
    for (size_t i = 0; i < jsons.size(); i ++)
    {
        variants.push_back(LLBC_JVHelper::J2V(jsons[i]));
    }

    return variants;
}

std::map<int, LLBC_Variant> LLBC_Config::GetIntVariantMap(const LLBC_String &file, const char *field) const
{
    std::map<int, LLBC_JsonValue> jsons = GetIntJsonMap(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::map<int, LLBC_Variant>();
    }

    std::map<int, LLBC_Variant> variants;
    std::map<int, LLBC_JsonValue>::const_iterator iter = jsons.begin();
    for (; iter != jsons.end(); iter ++)
    {
        variants.insert(std::make_pair(
            iter->first, LLBC_JVHelper::J2V(iter->second)));
    }

    return variants;
}

std::map<LLBC_String, LLBC_Variant> LLBC_Config::GetStringVariantMap(const LLBC_String &file, const char *field) const
{
    std::map<LLBC_String, LLBC_JsonValue> jsons = GetStringJsonMap(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
    {
        return std::map<LLBC_String, LLBC_Variant>();
    }

    std::map<LLBC_String, LLBC_Variant> variants;
    std::map<LLBC_String, LLBC_JsonValue>::const_iterator iter = jsons.begin();
    for (; iter != jsons.end(); iter ++)
    {
        variants.insert(std::make_pair(
            iter->first, LLBC_JVHelper::J2V(iter->second)));
    }

    return variants;
}

void LLBC_Config::BuildErrMsg(const LLBC_String &file, const LLBC_String &err)
{
    _errMsg.format("parse file[%s] failed, err:%s", file.c_str(), err.c_str());
}

__LLBC_NS_END

#include "llbc/common/AfterIncl.h"
<commit_msg>code tidying up<commit_after>// The MIT License (MIT)

// Copyright (c) 2013 lailongwei<lailongwei@126.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "llbc/common/Export.h"
#include "llbc/common/BeforeIncl.h"

#include "llbc/core/helper/STLHelper.h"
#include "llbc/core/file/File.h"
#include "llbc/core/utils/Util_Text.h"
#include "llbc/core/helper/JVHelper.h"

#include "llbc/core/config/Config.h"

__LLBC_NS_BEGIN

LLBC_Config::LLBC_Config()
{
    _errMsg = "OK";
}

LLBC_Config::~LLBC_Config()
{
    LLBC_STLHelper::DeleteContainer(_values);
}

int LLBC_Config::AddFile(const LLBC_String &file)
{
    if (file.empty())
    {
        LLBC_SetLastError(LLBC_ERROR_ARG);
        return LLBC_FAILED;
    }

    std::map<LLBC_String, LLBC_JsonValue *>::iterator iter = _values.find(file);
    if (iter != _values.end())
    {
        delete iter->second;
        iter->second = NULL;
    }
    else
    {
        _values[file] = NULL;
    }

    return LLBC_OK;
}

int LLBC_Config::Initialize()
{
    std::map<LLBC_String, LLBC_JsonValue *>::iterator iter = _values.begin();
    for (; iter != _values.end(); iter++)
        LLBC_XDelete(iter->second);

    iter = _values.begin();
    for (; iter != _values.end(); iter++)
    {
        const LLBC_String &fileName = iter->first;

        LLBC_File file(fileName, LLBC_FileMode::BinaryRead);
        if (!file.IsOpened())
        {
            BuildErrMsg(fileName, LLBC_FormatLastError());
            return LLBC_FAILED;
        }

        LLBC_String content = file.ReadToEnd();

        Json::Reader reader;
        LLBC_JsonValue *value = new LLBC_JsonValue;
        if (!reader.parse(content, *value))
        {
            delete value;

            BuildErrMsg(fileName, reader.getFormatedErrorMessages().c_str());
            LLBC_SetLastError(LLBC_ERROR_INVALID);

            return LLBC_FAILED;
        }

        iter->second = value;
    }

    _errMsg = "OK";

    return LLBC_OK;
}

const LLBC_String &LLBC_Config::GetError() const
{
    return _errMsg;
}

LLBC_JsonValue LLBC_Config::GetJsonValue(const LLBC_String &file, const char *field) const
{
    if (!field)
        field = ".";

    std::map<LLBC_String, LLBC_JsonValue *>::const_iterator iter = _values.find(file);
    if (iter == _values.end() || !iter->second)
    {
        LLBC_SetLastError(LLBC_ERROR_NOT_FOUND);
        return LLBC_JsonValue();
    }

    LLBC_SetLastError(LLBC_ERROR_SUCCESS);

    Json::Path path(field);
    return path.make(*iter->second);
}

std::vector<LLBC_JsonValue> LLBC_Config::GetJsonValueArray(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::vector<LLBC_JsonValue>();

    std::vector<LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter++)
        values.push_back(*jsonIter);

    return values;
}

std::map<int, LLBC_JsonValue> LLBC_Config::GetIntJsonMap(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::map<int, LLBC_JsonValue>();

    std::map<int, LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter++)
    {
        const LLBC_JsonValue &key = jsonIter.key();
        values[LLBC_Str2Int32(key.asCString())] = *jsonIter;
    }

    return values;
}

std::map<LLBC_String, LLBC_JsonValue> LLBC_Config::GetStringJsonMap(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue value = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::map<LLBC_String, LLBC_JsonValue>();

    std::map<LLBC_String, LLBC_JsonValue> values;

    LLBC_JsonValueIter jsonIter = value.begin();
    for (; jsonIter != value.end(); jsonIter++)
    {
        const LLBC_JsonValue &key = jsonIter.key();
        values[key.asCString()] = *jsonIter;
    }

    return values;
}

LLBC_Variant LLBC_Config::GetVariantValue(const LLBC_String &file, const char *field) const
{
    LLBC_JsonValue json = GetJsonValue(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return LLBC_Variant();

    return LLBC_JVHelper::J2V(json);
}

std::vector<LLBC_Variant> LLBC_Config::GetVariantValueArray(const LLBC_String &file, const char *field) const
{
    std::vector<LLBC_JsonValue> jsons = GetJsonValueArray(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::vector<LLBC_Variant>();

    std::vector<LLBC_Variant> variants;
    for (size_t i = 0; i < jsons.size(); i++)
        variants.push_back(LLBC_JVHelper::J2V(jsons[i]));

    return variants;
}

std::map<int, LLBC_Variant> LLBC_Config::GetIntVariantMap(const LLBC_String &file, const char *field) const
{
    std::map<int, LLBC_JsonValue> jsons = GetIntJsonMap(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::map<int, LLBC_Variant>();

    std::map<int, LLBC_Variant> variants;
    std::map<int, LLBC_JsonValue>::const_iterator iter = jsons.begin();
    for (; iter != jsons.end(); iter++)
        variants.insert(std::make_pair(
            iter->first, LLBC_JVHelper::J2V(iter->second)));

    return variants;
}

std::map<LLBC_String, LLBC_Variant> LLBC_Config::GetStringVariantMap(const LLBC_String &file, const char *field) const
{
    std::map<LLBC_String, LLBC_JsonValue> jsons = GetStringJsonMap(file, field);
    if (LLBC_GetLastError() != LLBC_ERROR_SUCCESS)
        return std::map<LLBC_String, LLBC_Variant>();

    std::map<LLBC_String, LLBC_Variant> variants;
    std::map<LLBC_String, LLBC_JsonValue>::const_iterator iter = jsons.begin();
    for (; iter != jsons.end(); iter++)
        variants.insert(std::make_pair(
            iter->first, LLBC_JVHelper::J2V(iter->second)));

    return variants;
}

void LLBC_Config::BuildErrMsg(const LLBC_String &file, const LLBC_String &err)
{
    _errMsg.format("parse file[%s] failed, err:%s", file.c_str(), err.c_str());
}

__LLBC_NS_END

#include "llbc/common/AfterIncl.h"
<|endoftext|>


<commit_before><commit_msg>Move rain along x axis and reset<commit_after><|endoftext|>


<commit_before>/*
 * SoundgatesConfig.cpp
 *
 *  Created on: 10.12.2013
 *      Author: gwue
 */

#include "SoundgatesConfig.hpp"

SoundgatesConfig* SoundgatesConfig::instance = 0;

SoundgatesConfig* SoundgatesConfig::getInstance()
{
	if (instance == 0)
	{
		instance = new SoundgatesConfig();
	}
	return instance;
}

SoundgatesConfig::SoundgatesConfig()
{
	this->initialized = false;
	this->cfgPath = "";

}

double SoundgatesConfig::getConf(SoundgatesConfValue v)
{
	if (!initialized)
	{
		std::cerr << "Configuration was not initialized before reading!"
				<< std::endl;
	}

	return configValues[v];
}

void SoundgatesConfig::load(string path)
{
	//TODO NOT YET IMPLEMENTED
	throw 0;
}

void SoundgatesConfig::loadDefault()
{
	// How large to create the ALSA Buffer.
	// Adds slightly to latency but increases robustness against buffer underruns
	// Non power of twos might lead to unexpected results!
	configValues[CFG_SOUND_BUFFER_SIZE] = 16384;
	// How many bytes need to be collected before sending data to ALSA
	// To low values may lead to artifacts in the sound output
	// Non power of twos might lead to unexpected results!
	configValues[CFG_ALSA_CHUNKS] = 1024;
	// Desired sample rate for the system. Not all rates might be supported
	configValues[CFG_SAMPLE_RATE] = 44100;
	initialized = true;
}
<commit_msg>Load defaults when trying to access configuration values before initialization<commit_after>/*
 * SoundgatesConfig.cpp
 *
 *  Created on: 10.12.2013
 *      Author: gwue
 */

#include "SoundgatesConfig.hpp"

SoundgatesConfig* SoundgatesConfig::instance = 0;

SoundgatesConfig* SoundgatesConfig::getInstance()
{
	if (instance == 0)
	{
		instance = new SoundgatesConfig();
	}
	return instance;
}

SoundgatesConfig::SoundgatesConfig()
{
	this->initialized = false;
	this->cfgPath = "";

}

double SoundgatesConfig::getConf(SoundgatesConfValue v)
{
	if (!initialized)
	{
		std::cerr << "Configuration was not initialized before reading! Using defaults"
				<< std::endl;
		this->loadDefault();
	}

	return configValues[v];
}

void SoundgatesConfig::load(string path)
{
	//TODO NOT YET IMPLEMENTED
	throw 0;
}

void SoundgatesConfig::loadDefault()
{
	// How large to create the ALSA Buffer.
	// Adds slightly to latency but increases robustness against buffer underruns
	// Non power of twos might lead to unexpected results!
	configValues[CFG_SOUND_BUFFER_SIZE] = 16384;
	// How many bytes need to be collected before sending data to ALSA
	// To low values may lead to artifacts in the sound output
	// Non power of twos might lead to unexpected results!
	configValues[CFG_ALSA_CHUNKS] = 1024;
	// Desired sample rate for the system. Not all rates might be supported
	configValues[CFG_SAMPLE_RATE] = 44100;
	initialized = true;
}
<|endoftext|>


<commit_before>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/FORMAT/molFileFactory.h>
#include <BALL/FORMAT/genericMolFile.h>
#include <BALL/KERNEL/system.h>
#include <BALL/FORMAT/commandlineParser.h>

using namespace BALL;

int main(int argc, char* argv[])
{
	// instantiate CommandlineParser object
	CommandlineParser parpars("MolecularFileConverter", "converts molecular file-formats", "bla", String(__DATE__), "File conversion");
	parpars.registerParameter("i",  "input file",    INFILE,  true);
	parpars.registerParameter("of", "output format", STRING,  false);
	parpars.registerParameter("o",  "output file",   OUTFILE, true);

	// TODO: was machen wir mit der of option?

	// the available formats
	String supp_formats = MolFileFactory::getSupportedFormats();

	// the manual
	String man = String("This tool converts different molecular file formats.\nSupported formats are ") + supp_formats + String(".");
	// TODO welcher wollen wir anbieten in BOA?
	// Marcels allgemeiner Converter kann: mol2, sdf, drf, pdb, ac, ent, brk, hin, mol, xyz,
	// mol2.gz, sdf.gz, drf.gz, pdb.gz, ac.gz, ent.gz, brk.gz, hin.gz, mol.gz, xyz.gz.
	parpars.setToolManual(man);

	parpars.setSupportedFormats("i", supp_formats);
	parpars.setSupportedFormats("o", supp_formats);

	// set supported formats as options for parameter of
	String formats = supp_formats;
	vector<String> temp;
	formats.split(temp,",");
	list<String> supp_format_list;
	for (Size i=0; i<temp.size(); i++)
	{
		supp_format_list.push_back(temp[i]);
	}
	parpars.setParameterRestrictions("of", supp_format_list);

	// parse the command line
	parpars.parse(argc, argv);

	// check if optional parameter 'of' is given
	String default_format = "mol2";
	if (parpars.has("of"))
		default_format = parpars.get("of");

	// read input/output file
	GenericMolFile* in_file  = MolFileFactory::open(parpars.get("i"), std::ios::in);
	GenericMolFile* out_file = MolFileFactory::open(parpars.get("o"), std::ios::out, default_format);

	if (!in_file)
	{
		// if file does not exist: complain and abort
		Log.error() << "error opening " << parpars.get("i") << " for input." << std::endl;
		return 2;
	}
	if (!out_file)
	{
		// if file does not exist: complain and abort
		Log.error() << "error opening " << parpars.get("o") << " for output." << std::endl;
		return 2;
	}

	// create a system and read the contents of the molecular file
	System S;
	in_file->read(S);
	in_file->close();

	// and write
	if (out_file)
	{
		out_file->write(S);
		out_file->close();
	}

	delete in_file;
	delete out_file;
}

<commit_msg>MolecularFileConverter: add a tool hint for successful file conversion<commit_after>// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

#include <BALL/FORMAT/molFileFactory.h>
#include <BALL/FORMAT/genericMolFile.h>
#include <BALL/KERNEL/system.h>
#include <BALL/FORMAT/commandlineParser.h>

using namespace BALL;

int main(int argc, char* argv[])
{
	// instantiate CommandlineParser object
	CommandlineParser parpars("MolecularFileConverter", "converts molecular file-formats", "bla", String(__DATE__), "File conversion");
	parpars.registerParameter("i",  "input file",    INFILE,  true);
	parpars.registerParameter("of", "output format", STRING,  false);
	parpars.registerParameter("o",  "output file",   OUTFILE, true);

	// the available formats
	String supp_formats = MolFileFactory::getSupportedFormats();

	// the manual
	String man = String("This tool converts different molecular file formats.\nSupported formats are ") + supp_formats + String(".");

	// we support: mol2, sdf, drf, pdb, ac, ent, brk, hin, mol, xyz,
	// mol2.gz, sdf.gz, drf.gz, pdb.gz, ac.gz, ent.gz, brk.gz, hin.gz, mol.gz, xyz.gz.
	parpars.setToolManual(man);

	parpars.setSupportedFormats("i", supp_formats);
	parpars.setSupportedFormats("o", supp_formats);

	// set supported formats as options for parameter of
	String formats = supp_formats;
	vector<String> temp;
	formats.split(temp,",");
	list<String> supp_format_list;
	for (Size i=0; i<temp.size(); i++)
	{
		supp_format_list.push_back(temp[i]);
	}
	parpars.setParameterRestrictions("of", supp_format_list);

	// parse the command line
	parpars.parse(argc, argv);

	// check if optional parameter 'of' is given
	String default_format = "mol2";
	if (parpars.has("of"))
		default_format = parpars.get("of");

	// read input/output file
	GenericMolFile* in_file  = MolFileFactory::open(parpars.get("i"), std::ios::in);
	GenericMolFile* out_file = MolFileFactory::open(parpars.get("o"), std::ios::out, default_format);

	if (!in_file)
	{
		// if file does not exist: complain and abort
		Log.error() << "error opening " << parpars.get("i") << " for input." << std::endl;
		return 2;
	}
	if (!out_file)
	{
		// if file does not exist: complain and abort
		Log.error() << "error opening " << parpars.get("o") << " for output." << std::endl;
		return 2;
	}

	// create a system and read the contents of the molecular file
	System S;
	in_file->read(S);
	in_file->close();

	// and write
	if (out_file)
	{
		out_file->write(S);
		out_file->close();
		Log.info() << "Wrote converted file " << parpars.get("o") << std::endl;
	}

	delete in_file;
	delete out_file;
}

<|endoftext|>


<commit_before>/*
 * IPK.2017
 *
 * TCP communication with REST API.
 *
 * Marián Mrva (xmrvam01)
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

#include <iostream>
#include <string>
#include <string.h>
#include <time.h>

using namespace std;

#define BUFSIZE 1024

// arg 1 - string
// arg 2 - find substr
int isInString(string s1, string s2){
    if (s1.find(s2) != string::npos) {
        return 1;
    }
    return -1;
}

const string currentDateTime() {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%A, %d %b %Y %X %Z", &tstruct);

    return buf;
}

int main (int argc, const char * argv[]) {

	int client_socket, port_number, bytestx, bytesrx;
    socklen_t serverlen;
    const char *server_hostname;
    struct hostent *server;
    struct sockaddr_in server_address;
    char buf[BUFSIZE];//;

    /* 1. test vstupnich parametru: */
    if (argc != 3) {
        fprintf(stderr, "Unknown error.\n");
        exit(EXIT_FAILURE);
    }

    /*
     *
     *  parse args
     *
     */
    const char * command  = argv[1];
    const char * all_path = argv[2];
    string s_command = command;
    string s_path = all_path;
    //cout <<  "command = " <<  command << endl;
    //cout <<  "path = " << all_path << endl;
    string serv_hostname;
    string serv_port = "";
    string serv_path;

    s_path.erase(0,7); // delete first 7 chars http://

    string delimiter = ":";
    serv_hostname = s_path.substr(0, s_path.find(delimiter)); // get ip/localhost

    // delete ip/localhost from path
    s_path.erase(0,serv_hostname.length() +1); // +1 for delete ':'

    // get port
    string delimiter2 = "/";
    serv_port = s_path.substr(0, s_path.find(delimiter2)); // get ip/localhost

    // delete port
    s_path.erase(0,serv_port.length());

    // just path stay here now
    serv_path = s_path;

    server_hostname = strdup(serv_hostname.c_str());
    port_number = stoi(serv_port);

//    cout << "final hostname = " << server_hostname << endl;
//    cout << "final port = " << port_number << endl;

    /*
     *
     *  convert client command to server command
     *
     */
    string final_command;
   if (s_command == "del" || s_command == "rmd") {
       final_command = "DELETE";
   }
   else if (s_command == "get" || s_command == "lst") {
       final_command = "GET";
   }
   else if (s_command == "put" || s_command == "mkd") {
       final_command = "PUT";
   }
   else {
       fprintf(stderr,"Unknown error.%s \n");
   }
    string type_of_medium;
    // its file or folder ?
    if (isInString(s_path, ".") != -1){
        // its file
        type_of_medium = "file";
    }
    else {
        type_of_medium = "folder";
    }

    /* 2. ziskani adresy serveru pomoci DNS */

    if ((server = gethostbyname(server_hostname)) == NULL) {
        fprintf(stderr,"ERROR: no such host as %s\n", server_hostname);
        exit(EXIT_FAILURE);
    }

    /* 3. nalezeni IP adresy serveru a inicializace struktury server_address */
    bzero((char *) &server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&server_address.sin_addr.s_addr, server->h_length);
    server_address.sin_port = htons(port_number);

    /* tiskne informace o vzdalenem soketu */
    //fprintf(stderr, "INFO: Server socket: %s : %d \n", inet_ntoa(server_address.sin_addr), ntohs(server_address.sin_port));

    /* Vytvoreni soketu */
	if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
	{
		perror("ERROR: socket");
		exit(EXIT_FAILURE);
	}

    /*
     * create http header
     */
    // DELETE /Users/majko/workspace/HTTP-REST-API-app/client.cpp
    string rest_command = final_command + " " + serv_path + "?type=" + type_of_medium + string(" HTTP/1.1 ") + " \r\n ";
    string host = string("Host: ") + inet_ntoa(server_address.sin_addr) + " \r\n ";
    string date = "Date: " + currentDateTime() + " \r\n ";
    string accept = string("Accept: text/plain") + " \r\n ";
    string accept_encoding = string("Accept-Encoding: identity") + " \r\n ";
    string content_type = string("Content-Type: ") + " \r\n ";
    string content_length = string("Content-Length: 0") + " \r\n ";

    /*
     *  concatenate header and convert to char *
     */

    string final_header = rest_command + host + date + accept + accept_encoding + content_type + content_length;
    strcpy(buf, final_header.c_str());
    //cout << final_header;

    if (connect(client_socket, (const struct sockaddr *) &server_address, sizeof(server_address)) != 0)
    {
		perror("ERROR: connect");
		exit(EXIT_FAILURE);
    }

    /* odeslani zpravy na server */
    bytestx = send(client_socket, buf, strlen(buf), 0);
    // send err
    if (bytestx < 0) {
        perror("ERROR in sendto");
    }
    memset(buf, '\0', sizeof(buf));

    while (bytesrx = recv(client_socket, buf, BUFSIZE, 0) > 0) {

        if (bytesrx < 0) {
            perror("ERROR in recvfrom");
            break;
        }
    }

    //printf("[CLIENT] RESPONSE from server: %s \n", buf);
    string s_header = buf;

    string s_helper = "";
    string s_error = "";

    string delimiter3 = ".\n";
    string s_help = s_header.substr(0, s_header.find(delimiter3)); // get all chars before 'ERR:'
    s_header.erase(0,s_help.length());

    cout << s_header;

    if (isInString(s_header, "ERR") != -1) {
        // its err
        // get error string
        string delimiter = "ERR";
        s_helper = s_header.substr(0, s_header.find(delimiter)); // get all chars before 'ERR:'
        s_header.erase(0,s_helper.length());
        s_header.erase(0, 4); // rm 'ERR:'
        s_error = s_header;
        fprintf(stderr, "%s \n", s_error.c_str());
    }

    close(client_socket);
    return 0;
}

<commit_msg>little change<commit_after>/*
 * IPK.2017
 *
 * TCP communication with REST API.
 *
 * Marián Mrva (xmrvam01)
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>

#include <iostream>
#include <string>
#include <string.h>
#include <time.h>

using namespace std;

#define BUFSIZE 1024

// arg 1 - string
// arg 2 - find substr
int isInString(string s1, string s2){
    if (s1.find(s2) != string::npos) {
        return 1;
    }
    return -1;
}

const string currentDateTime() {
    time_t     now = time(0);
    struct tm  tstruct;
    char       buf[80];
    tstruct = *localtime(&now);
    // Visit http://en.cppreference.com/w/cpp/chrono/c/strftime
    // for more information about date/time format
    strftime(buf, sizeof(buf), "%A, %d %b %Y %X %Z", &tstruct);

    return buf;
}

int main (int argc, const char * argv[]) {

	int client_socket, port_number, bytestx, bytesrx;
    socklen_t serverlen;
    const char *server_hostname;
    struct hostent *server;
    struct sockaddr_in server_address;
    char buf[BUFSIZE];//;

    /* 1. test vstupnich parametru: */
    if (argc != 3) {
        fprintf(stderr, "Unknown error.\n");
        exit(EXIT_FAILURE);
    }

    /*
     *
     *  parse args
     *
     */
    const char * command  = argv[1];
    const char * all_path = argv[2];
    string s_command = command;
    string s_path = all_path;
    //cout <<  "command = " <<  command << endl;
    //cout <<  "path = " << all_path << endl;
    string serv_hostname;
    string serv_port = "";
    string serv_path;

    s_path.erase(0,7); // delete first 7 chars http://

    string delimiter = ":";
    serv_hostname = s_path.substr(0, s_path.find(delimiter)); // get ip/localhost

    // delete ip/localhost from path
    s_path.erase(0,serv_hostname.length() +1); // +1 for delete ':'

    // get port
    string delimiter2 = "/";
    serv_port = s_path.substr(0, s_path.find(delimiter2)); // get ip/localhost

    // delete port
    s_path.erase(0,serv_port.length());

    // just path stay here now
    serv_path = s_path;

    server_hostname = strdup(serv_hostname.c_str());
    port_number = stoi(serv_port);

//    cout << "final hostname = " << server_hostname << endl;
//    cout << "final port = " << port_number << endl;

    /*
     *
     *  convert client command to server command
     *
     */
    string final_command;
   if (s_command == "del" || s_command == "rmd") {
       final_command = "DELETE";
   }
   else if (s_command == "get" || s_command == "lst") {
       final_command = "GET";
   }
   else if (s_command == "put" || s_command == "mkd") {
       final_command = "PUT";
   }
   else {
       fprintf(stderr,"Unknown error.%s \n");
   }
    string type_of_medium;
    // its file or folder ?
    if (isInString(s_path, ".") != -1){
        // its file
        type_of_medium = "file";
    }
    else {
        type_of_medium = "folder";
    }

    /* 2. ziskani adresy serveru pomoci DNS */

    if ((server = gethostbyname(server_hostname)) == NULL) {
        fprintf(stderr,"ERROR: no such host as %s\n", server_hostname);
        exit(EXIT_FAILURE);
    }

    /* 3. nalezeni IP adresy serveru a inicializace struktury server_address */
    bzero((char *) &server_address, sizeof(server_address));
    server_address.sin_family = AF_INET;
    bcopy((char *)server->h_addr, (char *)&server_address.sin_addr.s_addr, server->h_length);
    server_address.sin_port = htons(port_number);

    /* tiskne informace o vzdalenem soketu */
    //fprintf(stderr, "INFO: Server socket: %s : %d \n", inet_ntoa(server_address.sin_addr), ntohs(server_address.sin_port));

    /* Vytvoreni soketu */
	if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) <= 0)
	{
		perror("ERROR: socket");
		exit(EXIT_FAILURE);
	}

    /*
     * create http header
     */
    // DELETE /Users/majko/workspace/HTTP-REST-API-app/client.cpp
    string rest_command = final_command + " " + serv_path + "?type=" + type_of_medium + string(" HTTP/1.1 ") + " \r\n ";
    string host = string("Host: ") + inet_ntoa(server_address.sin_addr) + " \r\n ";
    string date = "Date: " + currentDateTime() + " \r\n ";
    string accept = string("Accept: text/plain") + " \r\n ";
    string accept_encoding = string("Accept-Encoding: identity") + " \r\n ";
    string content_type = string("Content-Type: ") + " \r\n ";
    string content_length = string("Content-Length: 0") + " \r\n ";

    /*
     *  concatenate header and convert to char *
     */

    string final_header = rest_command + host + date + accept + accept_encoding + content_type + content_length;
    strcpy(buf, final_header.c_str());
    //cout << final_header;

    if (connect(client_socket, (const struct sockaddr *) &server_address, sizeof(server_address)) != 0)
    {
		perror("ERROR: connect");
		exit(EXIT_FAILURE);
    }

    /* odeslani zpravy na server */
    bytestx = send(client_socket, buf, strlen(buf), 0);
    // send err
    if (bytestx < 0) {
        perror("ERROR in sendto");
    }
    memset(buf, '\0', sizeof(buf));

    while (bytesrx = recv(client_socket, buf, BUFSIZE, 0) > 0) {

        if (bytesrx < 0) {
            perror("ERROR in recvfrom");
            break;
        }
    }

    //printf("[CLIENT] RESPONSE from server: %s \n", buf);
    string s_header = "";
    s_header = buf;

    string s_helper = "";
    string s_error = "";

    string delimiter3 = ".\n";
    string s_help = s_header.substr(0, s_header.find(delimiter3)); // get all chars before 'ERR:'
    s_header.erase(0,s_help.length());

    cout << s_header;

    if (isInString(s_header, "ERR") != -1) {
        // its err
        // get error string
        string delimiter = "ERR";
        s_helper = s_header.substr(0, s_header.find(delimiter)); // get all chars before 'ERR:'
        s_header.erase(0,s_helper.length());
        s_header.erase(0, 4); // rm 'ERR:'
        s_error = s_header;
        fprintf(stderr, "%s \n", s_error.c_str());
    }

    close(client_socket);
    return 0;
}

<|endoftext|>


<commit_before>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"
#include "raw.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    cooked_mode();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  char *input;
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

  char stdin_buffer[SAY_MAX + 1];
  char *stdin_buffer_position = stdin_buffer;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

//  char stdin_buffer[kBufferSize];
//  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  if (raw_mode() != 0){
    Error("client: error using raw mode");
  }

  std::cout << ">" << std::flush;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        char c = (char) getchar();
        if (c == '\n') {
          *stdin_buffer_position++ = '\0';
          stdin_buffer_position = stdin_buffer;
          printf("\n");
          fflush(stdout);
          input = stdin_buffer;
          if (input[0] == '/') {
            if (!ProcessInput(input)) {
              break;
            }
          } else {
            // Send chat messages
            RequestSay(input);
          }
        } else if (stdin_buffer_position != stdin_buffer + SAY_MAX) {
          *stdin_buffer_position++ = c;
          printf("%c", c);
//          std::cout << c << std::endl;
          fflush(stdout);
        }

//        if (input != NULL) {
//          if (input[0] == '/') {
//            ProcessInput(input);
//          } else {
//            // Send chat messages
////            StripChar(stdin_buffer, '\n');
//            RequestSay(input);
//          }
//        }
//
//        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN_FILENO

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
//              std::cin.readsome(tmp_buffer, sizeof(tmp_buffer));
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << stdin_buffer << std::flush;
              memset(&tmp_buffer, 0, SAY_MAX);
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<commit_msg>print stdin_buffer_position after adding null char<commit_after>#include <netdb.h>
#include <unistd.h>
#include <sys/fcntl.h>

#include "client.h"
#include "duckchat.h"
#include "raw.h"

// Variables
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
int client_socket;
struct addrinfo *server_info;
char *channel;

// Prints an error message and exits the program.
void Error(const char *msg) {
  std::cerr << msg << std::endl;
  exit(1);
}

// Connects to the server at a the given port.
void Connect(char *domain, const char *port) {
  std::cout << "Connecting to " << domain << std::endl;

  struct addrinfo hints;
  struct addrinfo *server_info_tmp;
  int status;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_protocol = 0;

  if ((status = getaddrinfo(domain, port, &hints, &server_info_tmp)) != 0) {
    std::cerr << "client: unable to resolve address: " << gai_strerror(status) << std::endl;
    exit(1);
  }

  // getaddrinfo() returns a list of address structures into server_info_tmp.
  // Try each address until we successfully connect().
  // If socket() (or connect()) fails, close the socket and try the next address.

  for (server_info = server_info_tmp; server_info != NULL; server_info = server_info->ai_next) {
    if ((client_socket = socket(server_info->ai_family, server_info->ai_socktype, server_info->ai_protocol)) < 0) {
      continue;
    }
    if (connect(client_socket, server_info->ai_addr, server_info->ai_addrlen) != -1) {
      fcntl(client_socket, F_SETFL, O_NONBLOCK);
      break; // Success
    }
    close(client_socket);
  }

  if (server_info == NULL) {
    Error("client: all sockets failed to connect");
  }
}

// Sends a message to all users in on the active channel.
int RequestSay(const char *message) {
  struct request_say say;
  memset(&say, 0, sizeof(say));
  say.req_type = REQ_SAY;
  strncpy(say.req_text, message, SAY_MAX);
  strncpy(say.req_channel, channel, CHANNEL_MAX);

  if (sendto(client_socket, &say, sizeof(say), 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to send message\n");
  }

  return 0;
}

// Sends login requests to the server.
int RequestLogin(char *username) {
  struct request_login login;
  memset(&login, 0, sizeof(login));
  login.req_type = REQ_LOGIN;
  strncpy(login.req_username, username, USERNAME_MAX);

  size_t message_size = sizeof(struct request_login);

  if (sendto(client_socket, &login, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request login\n");
  }

  return 0;
}

// Sends logout requests to the server.
int RequestLogout() {
  struct request_logout logout;
  memset((char *) &logout, 0, sizeof(logout));
  logout.req_type = REQ_LOGOUT;

  size_t message_size = sizeof(struct request_logout);

  if (sendto(client_socket, &logout, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request logout\n");
  }

  return 0;
}

// Sends join requests to the server.
int RequestJoin(char *channel) {
  struct request_join join;
  memset((char *) &join, 0, sizeof(join));
  join.req_type = REQ_JOIN;
  strncpy(join.req_channel, channel, CHANNEL_MAX);

  size_t message_size = sizeof(struct request_join);

  if (sendto(client_socket, &join, message_size, 0, server_info->ai_addr, server_info->ai_addrlen) < 0) {
    Error("client: failed to request join\n");
  }

  return 0;
}

// Splits strings around spaces.
std::vector<std::string> StringSplit(std::string input) {
  std::istringstream iss(input);
  std::vector<std::string> result{std::istream_iterator<std::string>{iss}, std::istream_iterator<std::string>{}};

  return result;
}

// Splits strings around spaces.
std::vector<std::string> SplitString(char *input, char delimiter) {
  std::vector<std::string> result;
  std::string word = "";

  size_t input_size = strlen(input);
  for (size_t i = 0; i < input_size; i++) {
    if (input[i] != delimiter) {
      word += input[i];
    } else {
      result.push_back(word);
      word = "";
    }
  }
  result.push_back(word);

  return result;
}

void StripChar(char *input, char c) {
  size_t size = strlen(input);
  for (size_t i = 0; i < size; i++) {
    if (input[i] == c) {
      input[i] = '\0';
    }
  }
}

// Processes the input string to decide what type of command it is.
bool ProcessInput(std::string input) {
  std::vector<std::string> inputs = StringSplit(input);
  bool result = true;

  if (inputs[0] == "/exit") {
    RequestLogout();
    cooked_mode();
    result = false;
  } else if (inputs[0] == "/list") {

  } else if (inputs[0] == "/join") {

  } else if (inputs[0] == "/leave") {

  } else if (inputs[0] == "/who") {

  } else if (inputs[0] == "/switch") {

  } else {
    std::cout << "\n*Unknown command" << std::endl;
  }

  return result;
}

int main(int argc, char *argv[]) {
  char *domain;
  char *port_str;
  int port_num;
  char *username;
  char *input;
  char tmp_buffer[SAY_MAX];
  memset(&tmp_buffer, 0, SAY_MAX);

  char stdin_buffer[SAY_MAX + 1];
  char *stdin_buffer_position = stdin_buffer;

//  struct timeval timeout;
  fd_set read_set;
//  int file_desc = 0;
  int result;
  char receive_buffer[kBufferSize];
  memset(&receive_buffer, 0, kBufferSize);

//  char stdin_buffer[kBufferSize];
//  memset(&stdin_buffer, 0, kBufferSize);

  if (argc < 4) {
    Error("usage: client [server name] [port] [username]");
  }

  domain = argv[1];
  port_str = argv[2];
  port_num = atoi(argv[2]);
  username = argv[3];

  if (strlen(domain) > UNIX_PATH_MAX) {
    Error("client: server name must be less than 108 characters");
  }

  if (port_num < 0 || port_num > 65535) {
    Error("client: port number must be between 0 and 65535");
  }

  if (strlen(username) > USERNAME_MAX) {
    Error("client: username must be less than 32 characters");
  }

  Connect(domain, port_str);

  RequestLogin(username);

  channel = (char *) "Common";
  RequestJoin(channel);

  // TODO handle response from send

  if (raw_mode() != 0){
    Error("client: error using raw mode");
  }

  std::cout << ">" << std::flush;

  while (1) {
    FD_ZERO(&read_set);
    FD_SET(client_socket, &read_set);
    FD_SET(STDIN_FILENO, &read_set);

    if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) {
      Error("client: problem using select");
    }

    if (result > 0) {
      if (FD_ISSET(STDIN_FILENO, &read_set)) {
        char c = (char) getchar();
        if (c == '\n') {
          *stdin_buffer_position++ = '\0';
          stdin_buffer_position = stdin_buffer;
          printf("\n");
          fflush(stdout);
          input = stdin_buffer;
          if (input[0] == '/') {
            if (!ProcessInput(input)) {
              break;
            }
          } else {
            // Send chat messages
            RequestSay(input);
          }
        } else if (stdin_buffer_position != stdin_buffer + SAY_MAX) {
          *stdin_buffer_position++ = c;
          printf("%c", c);
//          std::cout << c << std::endl;
          fflush(stdout);
        }

//        if (input != NULL) {
//          if (input[0] == '/') {
//            ProcessInput(input);
//          } else {
//            // Send chat messages
////            StripChar(stdin_buffer, '\n');
//            RequestSay(input);
//          }
//        }
//
//        memset(&stdin_buffer, 0, kBufferSize);
      } // end of if STDIN_FILENO

      if (FD_ISSET(client_socket, &read_set)) {
        // Socket has data
        int read_size = read(client_socket, receive_buffer, kBufferSize);

        if (read_size != 0) {
          // TODO capture user input, store, clean input, then print buffer, afterward replace input
          struct text message;
          memcpy(&message, receive_buffer, sizeof(struct text));
          text_t text_type = message.txt_type;

          switch (text_type) {
            case TXT_SAY:
              struct text_say say;
              memcpy(&say, receive_buffer, sizeof(struct text_say));
//              std::cin.readsome(tmp_buffer, sizeof(tmp_buffer));
              *stdin_buffer_position++ = '\0';
              std::cout << "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b";
              std::cout << "[" << say.txt_channel << "]" << "[" << say.txt_username << "]: " << say.txt_text << std::endl;
              std::cout << ">" << stdin_buffer_position << std::flush;
              memset(&tmp_buffer, 0, SAY_MAX);
              break;
            default:
              break;
          }
        }

        memset(&receive_buffer, 0, SAY_MAX);
      } // end of if client_socket

    } // end of if result

  } // end of while

  return 0;
}<|endoftext|>


<commit_before>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define WIN_SIZE 16

using namespace std;

bool gremlin(Packet * pack, int corruptProb, int lossProb);
bool init(int argc, char** argv);
bool loadFile();
bool sendFile();
bool getFile();
char * recvPkt();
bool isvpack(unsigned char * p);
Packet createPacket(int index);
bool sendPacket();
bool isAck();
void handleAck();
void handleNak(int& x);

int seqNum;
int s;
int probCorrupt;
int probLoss;
string hs;
short int port;
char * file;
unsigned char* window[16]; //packet window
int base; //used to determine position in window of arriving packets
int length;
struct sockaddr_in a;
struct sockaddr_in sa;
socklen_t salen;
string fstr;
bool dropPck;
Packet p;
int delayT;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendto(s, "GET Testfile", BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
    return false;
  }

  getFile();

  return 0;
}

bool init(int argc, char** argv) {
  base = 0; //initialize base
  s = 0;

  hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  port = 10038; /* Can be any port within 10038-10041, inclusive. */

  char* delayTStr = argv[2];
  delayT = boost::lexical_cast<int>(delayTStr);

  /*if(!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }*/

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return false;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  /*fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;*/

  seqNum = 0;
  dropPck = false;
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= length / BUFSIZE; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);
    if(index * BUFSIZE + BUFSIZE > length) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss;
    if((dropPck = gremlin(&p, pc, pl)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return false;
      }
      return true;
    } else return false;
}
bool isAck() {
    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[3];
  memcpy(sns, &p[0], 3);
  sns[2] = '\0';

  char * css = new char[6];
  memcpy(css, &p[2], 6);
  css[5] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[8], 122);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  cout << "sn: " << sn << endl;
  cout << "base: " << base << endl;
  cout << "base + WIN_SIZE: " << base + WIN_SIZE << endl;

  if((sn >= base) && (sn < base + WIN_SIZE)) { cout << "how is this real life" << endl; return false; }

  cout << "Checksum is failing." << endl;

  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){
  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  int rlen;
  int ack;

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&sa, &salen);

	/* Begin Window Loading */
	int tempSeqNum = boost::lexical_cast<int>(packet[0]);
	int properIndex = tempSeqNum - base;

	window[properIndex] = packet;
	cout << "Packet loaded into window" << endl;
	char* tempTest = new char[6];
		memcpy(tempTest, &window[1], 0);
		tempTest[5] = '\0';

	cout << "The Checksum pulled from client window: " << tempTest[0] << endl;

	for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
	  char * sns = new char[3];
	  memcpy(sns, &packet[0], 3);
	  sns[2] = '\0';

      char * css = new char[6];
      memcpy(css, &packet[2], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << sns << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      if(isvpack(packet)) {
        int x = boost::lexical_cast<int>(sns);
		cout << "sns: " << sns << endl;
		cout << "x (sns as int): " << x << endl;
		if(x == base) base++; //increment base of window //FIXME
        file << dataPull;
		file.flush();
      }
      cout << "Sent response: ";
      cout << "ACK " << base << endl;

	  if(packet[6] == '1') usleep(delayT*1000);

	  string wbs = to_string((long long)base);
	  const char * ackval = wbs.c_str();

      if(sendto(s, ackval, PAKSIZE, 0, (struct sockaddr *)&sa, salen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}
<commit_msg>Add more thorough testing, remain in disbelief<commit_after>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <boost/lexical_cast.hpp>
#include "packet.h"

#define BUFSIZE 121
#define FILENAME "Testfile"
#define TEST_FILENAME "Testfile2"
#define PORT 10038
#define PAKSIZE 128
#define ACK 0
#define NAK 1
#define WIN_SIZE 16

using namespace std;

bool gremlin(Packet * pack, int corruptProb, int lossProb);
bool init(int argc, char** argv);
bool loadFile();
bool sendFile();
bool getFile();
char * recvPkt();
bool isvpack(unsigned char * p);
Packet createPacket(int index);
bool sendPacket();
bool isAck();
void handleAck();
void handleNak(int& x);

int seqNum;
int s;
int probCorrupt;
int probLoss;
string hs;
short int port;
char * file;
unsigned char* window[16]; //packet window
int base; //used to determine position in window of arriving packets
int length;
struct sockaddr_in a;
struct sockaddr_in sa;
socklen_t salen;
string fstr;
bool dropPck;
Packet p;
int delayT;
unsigned char b[BUFSIZE];

int main(int argc, char** argv) {

  if(!init(argc, argv)) return -1;

  if(sendto(s, "GET Testfile", BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
    cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
    return false;
  }

  getFile();

  return 0;
}

bool init(int argc, char** argv) {
  base = 0; //initialize base
  s = 0;

  hs = string("131.204.14.") + argv[1]; /* Needs to be updated? Might be a string like "tux175.engr.auburn.edu." */
  port = 10038; /* Can be any port within 10038-10041, inclusive. */

  char* delayTStr = argv[2];
  delayT = boost::lexical_cast<int>(delayTStr);

  /*if(!loadFile()) {
    cout << "Loading file failed. (filename FILENAME)" << endl;
    return false;
  }*/

  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
    cout << "Socket creation failed. (socket s)" << endl;
    return false;
  }

  memset((char *)&a, 0, sizeof(a));
  a.sin_family = AF_INET;
  a.sin_addr.s_addr = htonl(INADDR_ANY); //why does this always give us 0?
  a.sin_port = htons(0);

  if (bind(s, (struct sockaddr *)&a, sizeof(a)) < 0){
    cout << "Socket binding failed. (socket s, address a)" << endl;
    return false;
  }

  memset((char *)&sa, 0, sizeof(sa));
  sa.sin_family = AF_INET;
  sa.sin_port = htons(port);
  inet_pton(AF_INET, hs.c_str(), &(sa.sin_addr));

  cout << endl;

  cout << "Server address (inet mode): " << inet_ntoa(sa.sin_addr) << endl;
  cout << "Port: " << ntohs(sa.sin_port) << endl;

  cout << endl << endl;

  /*fstr = string(file);

  cout << "File: " << endl << fstr << endl << endl;*/

  seqNum = 0;
  dropPck = false;
  return true;
}

bool loadFile() {

  ifstream is (FILENAME, ifstream::binary);

  if(is) {
    is.seekg(0, is.end);
    length = is.tellg();
    is.seekg(0, is.beg);

    file = new char[length];

    cout << "Reading " << length << " characters..." << endl;
    is.read(file, length);

    if(!is) { cout << "File reading failed. (filename " << FILENAME << "). Only " << is.gcount() << " could be read."; return false; }
    is.close();
  }
  return true;
}

bool sendFile() {

  for(int x = 0; x <= length / BUFSIZE; x++) {
    p = createPacket(x);
    if(!sendPacket()) continue;

    if(isAck()) {
      handleAck();
    } else {
      handleNak(x);
    }

    memset(b, 0, BUFSIZE);
  }
  return true;
}

Packet createPacket(int index){
    cout << endl;
    cout << "=== TRANSMISSION START" << endl;
    string mstr = fstr.substr(index * BUFSIZE, BUFSIZE);
    if(index * BUFSIZE + BUFSIZE > length) {
      mstr[length - (index * BUFSIZE)] = '\0';
    }
    return Packet (seqNum, mstr.c_str());
}

bool sendPacket(){
    int pc = probCorrupt; int pl = probLoss;
    if((dropPck = gremlin(&p, pc, pl)) == false){
      if(sendto(s, p.str(), BUFSIZE + 7, 0, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        cout << "Package sending failed. (socket s, server address sa, message m)" << endl;
        return false;
      }
      return true;
    } else return false;
}
bool isAck() {
    recvfrom(s, b, BUFSIZE + 7, 0, (struct sockaddr *)&sa, &salen);

    cout << endl << "=== SERVER RESPONSE TEST" << endl;
    cout << "Data: " << b << endl;
    if(b[6] == '0') return true;
    else return false;
}
void handleAck() {

}
void handleNak(int& x) {

      char * sns = new char[2];
      memcpy(sns, &b[0], 1);
      sns[1] = '\0';

      char * css = new char[5];
      memcpy(css, &b[1], 5);

      char * db = new char[BUFSIZE + 1];
      memcpy(db, &b[2], BUFSIZE);
      db[BUFSIZE] = '\0';

      cout << "Sequence number: " << sns << endl;
      cout << "Checksum: " << css << endl;

      Packet pk (0, db);
      pk.setSequenceNum(boost::lexical_cast<int>(sns));
      pk.setCheckSum(boost::lexical_cast<int>(css));

      if(!pk.chksm()) x--;
      else x = (x - 2 > 0) ? x - 2 : 0;
}

bool gremlin(Packet * pack, int corruptProb, int lossProb){
  bool dropPacket = false;
  int r = rand() % 100;

  cout << "Corruption probability: " << corruptProb << endl;
  cout << "Random number: " << r << endl;

  if(r <= (lossProb)){
    dropPacket = true;
    cout << "Dropped!" << endl;
  }
  else if(r <= (corruptProb)){
    cout << "Corrupted!" << endl;
    pack->loadDataBuffer((char*)"GREMLIN LOL");
  }
  else seqNum = (seqNum) ? false : true;
  cout << "Seq. num: " << pack->getSequenceNum() << endl;
  cout << "Checksum: " << pack->getCheckSum() << endl;
  cout << "Message: "  << pack->getDataBuffer() << endl;

  return dropPacket;
}

bool isvpack(unsigned char * p) {
  cout << endl << "=== IS VALID PACKET TESTING" << endl;

  char * sns = new char[3];
  memcpy(sns, &p[0], 3);
  sns[2] = '\0';

  char * css = new char[6];
  memcpy(css, &p[2], 6);
  css[5] = '\0';

  char * db = new char[121 + 1];
  memcpy(db, &p[8], 122);
  db[121] = '\0';

  cout << "Seq. num: " << sns << endl;
  cout << "Checksum: " << css << endl;
  cout << "Message: " << db << endl;

  int sn = boost::lexical_cast<int>(sns);
  int cs = boost::lexical_cast<int>(css);

  Packet pk (0, db);
  pk.setSequenceNum(sn);

  // change to validate based on checksum and sequence number

  cout << "sn: " << sn << endl;
  cout << "base: " << base << endl;
  cout << "base + WIN_SIZE: " << base + WIN_SIZE << endl;
  cout << "sn >= base: " << (sn >= base) << endl;
  cout << "sn < (base + WIN_SIZE): " << (sn < (base + WIN_SIZE) << endl;

  if((sn >= base) && (sn < (base + WIN_SIZE))) { cout << "how is this real life" << endl; return false; }

  cout << "Checksum is failing." << endl;

  if(cs != pk.generateCheckSum()) return false;
  return true;
}

bool getFile(){
  /* Loop forever, waiting for messages from a client. */
  cout << "Waiting on port " << PORT << "..." << endl;

  ofstream file("Dumpfile");

  int rlen;
  int ack;

  for (;;) {
    unsigned char packet[PAKSIZE + 1];
    unsigned char dataPull[PAKSIZE - 7 + 1];
    rlen = recvfrom(s, packet, PAKSIZE, 0, (struct sockaddr *)&sa, &salen);

	/* Begin Window Loading */
	int tempSeqNum = boost::lexical_cast<int>(packet[0]);
	int properIndex = tempSeqNum - base;

	window[properIndex] = packet;
	cout << "Packet loaded into window" << endl;
	char* tempTest = new char[6];
		memcpy(tempTest, &window[1], 0);
		tempTest[5] = '\0';

	cout << "The Checksum pulled from client window: " << tempTest[0] << endl;

	for(int x = 0; x < PAKSIZE - 7; x++) {
      dataPull[x] = packet[x + 7];
    }
    dataPull[PAKSIZE - 7] = '\0';
    packet[PAKSIZE] = '\0';
    if (rlen > 0) {
	  char * sns = new char[3];
	  memcpy(sns, &packet[0], 3);
	  sns[2] = '\0';

      char * css = new char[6];
      memcpy(css, &packet[2], 5);
      css[5] = '\0';
      cout << endl << endl << "=== RECEIPT" << endl;
      cout << "Seq. num: " << sns << endl;
      cout << "Checksum: " << css << endl;
      cout << "Received message: " << dataPull << endl;
      if(isvpack(packet)) {
        int x = boost::lexical_cast<int>(sns);
		cout << "sns: " << sns << endl;
		cout << "x (sns as int): " << x << endl;
		if(x == base) base++; //increment base of window //FIXME
        file << dataPull;
		file.flush();
      }
      cout << "Sent response: ";
      cout << "ACK " << base << endl;

	  if(packet[6] == '1') usleep(delayT*1000);

	  string wbs = to_string((long long)base);
	  const char * ackval = wbs.c_str();

      if(sendto(s, ackval, PAKSIZE, 0, (struct sockaddr *)&sa, salen) < 0) {
        cout << "Acknowledgement failed. (socket s, acknowledgement message ack, client address ca, client address length calen)" << endl;
        return 0;
      }
      delete css;
    }
  }
  file.close();
  return true;
}
<|endoftext|>