|
@@ -1,7 +1,12 @@
|
|
#include "../include/machineiomanager.hpp"
|
|
#include "../include/machineiomanager.hpp"
|
|
#include "../include/commands.hpp"
|
|
#include "../include/commands.hpp"
|
|
|
|
+#include "../include/base64.hpp"
|
|
|
|
|
|
|
|
+#include <fstream>
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
|
+#include <vector>
|
|
|
|
+#include <limits>
|
|
|
|
+#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
#include <readline/readline.h>
|
|
#include <readline/readline.h>
|
|
|
|
|
|
@@ -11,19 +16,32 @@ void MachineIoManager::run() {
|
|
std::cout << "MachineIoManager::run() says hello!" << std::endl;
|
|
std::cout << "MachineIoManager::run() says hello!" << std::endl;
|
|
|
|
|
|
boost::asio::streambuf recvbuf;
|
|
boost::asio::streambuf recvbuf;
|
|
- boost::system::error_code errcode;
|
|
|
|
|
|
|
|
- Json::Value root;
|
|
|
|
|
|
+ Json::Value root, recv;
|
|
const char *recvjson;
|
|
const char *recvjson;
|
|
|
|
|
|
- Json::StreamWriterBuilder wbuilder;
|
|
|
|
-
|
|
|
|
bool keep_reading = true;
|
|
bool keep_reading = true;
|
|
COMMANDID cmd;
|
|
COMMANDID cmd;
|
|
char *line = NULL;
|
|
char *line = NULL;
|
|
|
|
+
|
|
|
|
+ std::vector<std::string> tokens, pathtemp;
|
|
|
|
+
|
|
|
|
+ std::fstream fs;
|
|
|
|
+
|
|
|
|
+ // .open(path, mode; mode std::fstream::in, out, binary, trunc(ate))
|
|
|
|
+ // .read(char* dest, int size)
|
|
|
|
+ // .write(char* src, int size)
|
|
|
|
+ // .eof()
|
|
|
|
+ // .seekg(offset, ios_base::beg, cur, end)
|
|
|
|
+ // .tellg()
|
|
|
|
+ // .close()
|
|
|
|
+
|
|
while (keep_reading) {
|
|
while (keep_reading) {
|
|
|
|
+ // clean up
|
|
free(line);
|
|
free(line);
|
|
root = Json::Value();
|
|
root = Json::Value();
|
|
|
|
+ recv = Json::Value();
|
|
|
|
+ recvbuf.consume(recvbuf.size());
|
|
|
|
|
|
// read an input line
|
|
// read an input line
|
|
line = readline("");
|
|
line = readline("");
|
|
@@ -32,8 +50,20 @@ void MachineIoManager::run() {
|
|
if (strlen(line) == 0) {
|
|
if (strlen(line) == 0) {
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ boost::algorithm::split(tokens, std::string(line), boost::algorithm::is_any_of(" "), boost::algorithm::token_compress_on);
|
|
|
|
+
|
|
|
|
+ std::cerr << "tokens are: [ ";
|
|
|
|
+ for(int i = 0; i < tokens.size(); i++) {
|
|
|
|
+ std::cerr << tokens[i] << " ";
|
|
|
|
+ }
|
|
|
|
+ std::cerr << "]" << std::endl;
|
|
|
|
+
|
|
|
|
+ if(tokens.size() < 1) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
|
|
- cmd = getCmdIdFromString(line);
|
|
|
|
|
|
+ cmd = getCmdIdFromString(tokens[0].c_str());
|
|
|
|
|
|
switch (cmd) {
|
|
switch (cmd) {
|
|
case CMD_DISCONNECT: {
|
|
case CMD_DISCONNECT: {
|
|
@@ -45,36 +75,145 @@ void MachineIoManager::run() {
|
|
root["command"] = "status";
|
|
root["command"] = "status";
|
|
|
|
|
|
// send request
|
|
// send request
|
|
- boost::asio::write(*tcpsock, buffer(Json::writeString(wbuilder, root)),
|
|
|
|
- errcode);
|
|
|
|
- if (errcode) {
|
|
|
|
- std::cerr << "couldnt send version check" << std::endl
|
|
|
|
- << errcode.message() << std::endl;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ sendJson(root);
|
|
// receive answer
|
|
// receive answer
|
|
- // using transfer_at_least(1) to avoid lockup with transfer_all()
|
|
|
|
- boost::asio::read(*tcpsock, recvbuf, boost::asio::transfer_at_least(1),
|
|
|
|
- errcode);
|
|
|
|
- if (errcode && errcode != boost::asio::error::eof) {
|
|
|
|
- std::cerr << "couldnt recieve version check" << std::endl
|
|
|
|
- << errcode.message() << std::endl;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ receiveJson(recvbuf);
|
|
|
|
+ //
|
|
|
|
+ parseJson(&recv, recvbuf);
|
|
|
|
|
|
// dump received data to stdout for gui to handle
|
|
// dump received data to stdout for gui to handle
|
|
- recvjson = boost::asio::buffer_cast<const char *>(recvbuf.data());
|
|
|
|
- std::cout << recvjson;
|
|
|
|
|
|
+ std::cout << recv;
|
|
|
|
+ //~ recvjson = boost::asio::buffer_cast<const char *>(recvbuf.data());
|
|
|
|
+ //~ std::cout << recvjson;
|
|
|
|
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ case CMD_PUT: {
|
|
|
|
+ int size, chunks, haveread;
|
|
|
|
+ char rbuf[BLOCKSIZE];
|
|
|
|
+ if(tokens.size() < 2) {
|
|
|
|
+ std::cerr << "no files specified" << std::endl;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ fs.open(tokens[1], std::fstream::in | std::fstream::binary);
|
|
|
|
+ if(!fs.is_open()) {
|
|
|
|
+ std::cerr << "couldnt open file " << tokens[1] << std::endl;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ fs.seekg(0, fs.end);
|
|
|
|
+ size = fs.tellg();
|
|
|
|
+ fs.seekg(0, fs.beg);
|
|
|
|
+ chunks = size / BLOCKSIZE + ((size % BLOCKSIZE)?1:0);
|
|
|
|
+ std::cout << "size is " << size << " chunks are " << chunks << std::endl;
|
|
|
|
+
|
|
|
|
+ if(!size) {
|
|
|
|
+ std::cerr << "not sending empty file" << std::endl;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ boost::algorithm::split(pathtemp, tokens[1], boost::algorithm::is_any_of("/"), boost::algorithm::token_compress_on);
|
|
|
|
+
|
|
|
|
+ root["command"] = "put";
|
|
|
|
+ root["file"] = pathtemp.back();
|
|
|
|
+ root["size"] = size;
|
|
|
|
+
|
|
|
|
+ std::cout << root;
|
|
|
|
+
|
|
|
|
+ if(!sendJson(root) | !receiveJson(recvbuf) | !parseJson(&recv, recvbuf)) {
|
|
|
|
+ // error occured, stop working
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ // dump to stdout for GUI
|
|
|
|
+ std::cout << recv;
|
|
|
|
+
|
|
|
|
+ // check correct command once asychronous
|
|
|
|
+ if(recv["accept"].asBool()) {
|
|
|
|
+ // request ok, start sending...
|
|
|
|
+ root = Json::Value();
|
|
|
|
+ root["command"] = "put";
|
|
|
|
+ root["cancel"] = false;
|
|
|
|
+
|
|
|
|
+ std::cout << root;
|
|
|
|
+
|
|
|
|
+ while(chunks) {
|
|
|
|
+ haveread = fs.readsome(rbuf, BLOCKSIZE);
|
|
|
|
+ chunks--;
|
|
|
|
+ root["data"] = base64::encodeVector(std::vector<char>(rbuf, rbuf+haveread*sizeof(char)));
|
|
|
|
+ root["remaining"] = chunks;
|
|
|
|
+ if(!sendJson(root) | !receiveJson(recvbuf) | !parseJson(&recv, recvbuf)) {
|
|
|
|
+ // error occured, stop working
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if(recv["cancel"].asBool()) {
|
|
|
|
+ // transfer cancelled by server
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ std::cout << root;
|
|
|
|
+ std::this_thread::sleep_for (std::chrono::seconds(1));
|
|
|
|
+ }
|
|
|
|
+ if(chunks) std::cerr << "not all data sent, remain chunks " << chunks << std::endl;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case CMD_GET: {
|
|
|
|
+ int chunks;
|
|
|
|
+ std::vector<char> wtmp;
|
|
|
|
+ char wbuf[BLOCKSIZE];
|
|
|
|
+ if(tokens.size() < 2) {
|
|
|
|
+ std::cerr << "no files specified" << std::endl;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ fs.open(tokens[1], std::fstream::out | std::fstream::binary | std::fstream::trunc);
|
|
|
|
+ if(!fs.is_open()) {
|
|
|
|
+ std::cerr << "couldnt open file " << tokens[1] << std::endl;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ root["command"] = "get";
|
|
|
|
+ root["file"] = tokens[1];
|
|
|
|
+
|
|
|
|
+ if(!sendJson(root) | !receiveJson(recvbuf) | !parseJson(&recv, recvbuf)) {
|
|
|
|
+ // error occured, stop working
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ std::cout << recv << std::endl;
|
|
|
|
+
|
|
|
|
+ if(recv["accept"].asBool()) {
|
|
|
|
+ // for ACK
|
|
|
|
+ root["command"] = "get";
|
|
|
|
+ root["remaining"] = 0;
|
|
|
|
+ root["cancel"] = false;
|
|
|
|
+ // request ok, start receiving
|
|
|
|
+ chunks = std::numeric_limits<int>::max();
|
|
|
|
+ std::cout << "survive" << std::endl;
|
|
|
|
+ while(chunks) {
|
|
|
|
+ std::cout << "survive" << std::endl;
|
|
|
|
+ if(!receiveJson(recvbuf) | !parseJson(&recv, recvbuf)) break;
|
|
|
|
+ std::cout << "survive" << std::endl;
|
|
|
|
+ std::cout << recv << std::endl;
|
|
|
|
+ wtmp = base64::decodeVector(recv["data"].asString());
|
|
|
|
+ fs.write(wtmp.data(), wtmp.size());
|
|
|
|
+ chunks = recv["remaining"].asInt();
|
|
|
|
+ if(!sendJson(root)) {
|
|
|
|
+ // couldnt ACK
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(recv["cancel"].asBool()) std::cerr << "transfer was cancelled" << std::endl;
|
|
|
|
+ if(recv["remaining"].asInt()) std::cerr << "not all data received, remain chunks " << recv["remaining"].asInt();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
default: {
|
|
default: {
|
|
std::cerr << "unknown command " << line << "\n";
|
|
std::cerr << "unknown command " << line << "\n";
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
std::printf("\n");
|
|
std::printf("\n");
|
|
|
|
+
|
|
|
|
+ // if a command used fs, close it now
|
|
|
|
+ if(fs.is_open()) fs.close();
|
|
}
|
|
}
|
|
free(line);
|
|
free(line);
|
|
|
|
|