Browse Source

major work on sending files

logicp 5 years ago
parent
commit
34d8431716
12 changed files with 258 additions and 107 deletions
  1. 1 0
      .gitignore
  2. 17 1
      argdialog.cpp
  3. 7 1
      argdialog.h
  4. 40 10
      argdialog.ui
  5. 70 0
      client.cpp
  6. 4 1
      client.hpp
  7. BIN
      favicon.ico
  8. 9 0
      headers/util.hpp
  9. 4 0
      mainwindow.cpp
  10. 1 1
      mainwindow.h
  11. 85 85
      mainwindow.ui
  12. 20 8
      ui_argdialog.h

+ 1 - 0
.gitignore

@@ -6,3 +6,4 @@ tags
 **.o
 Makefile
 *.stash
+qrc_kres.*

+ 17 - 1
argdialog.cpp

@@ -1,11 +1,27 @@
-#include "argdialog.h"
+#include "argdialog.h"
 #include "ui_argdialog.h"
+#include <QDebug>
+#include <QIODevice>
+#include <vector>
 
 ArgDialog::ArgDialog(QWidget *parent) :
     QDialog(parent),
     ui(new Ui::ArgDialog)
 {
     ui->setupUi(this);
+    QObject::connect(ui->addFile, &QPushButton::clicked, this, [this]() {
+        auto file_name = QFileDialog::getOpenFileName(this,
+                                                tr("Open File"), "~", tr("Image Files (*.png *.jpg *.bmp)"));
+        qDebug() << "Selected file:" << file_name;
+        if (file_name.size() > 0) {
+            QFile file(file_name);
+            std::vector<char> byte_array{};
+            if (file.open(QIODevice::ReadOnly)) {
+                QByteArray bytes = file.readAll();
+                emit ArgDialog::uploadFile(bytes);
+            }
+        }
+    });
 }
 
 ArgDialog::~ArgDialog()

+ 7 - 1
argdialog.h

@@ -1,7 +1,10 @@
-#ifndef ARGDIALOG_H
+#ifndef ARGDIALOG_H
 #define ARGDIALOG_H
 
 #include <QDialog>
+#include <QFileDialog>
+#include <QPushButton>
+#include <QFile>
 
 namespace Ui {
 class ArgDialog;
@@ -15,6 +18,9 @@ public:
     explicit ArgDialog(QWidget *parent = nullptr);
     ~ArgDialog();
 
+signals:
+    void uploadFile(QByteArray bytes);
+
 private:
     Ui::ArgDialog *ui;
 };

+ 40 - 10
argdialog.ui

@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>490</width>
-    <height>347</height>
+    <height>314</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -16,8 +16,8 @@
   <widget class="QDialogButtonBox" name="argButtonBox">
    <property name="geometry">
     <rect>
-     <x>70</x>
-     <y>300</y>
+     <x>80</x>
+     <y>260</y>
      <width>341</width>
      <height>32</height>
     </rect>
@@ -37,13 +37,13 @@ color: rgb(16, 16, 16);</string>
    <property name="geometry">
     <rect>
      <x>60</x>
-     <y>60</y>
+     <y>140</y>
      <width>361</width>
-     <height>151</height>
+     <height>91</height>
     </rect>
    </property>
    <property name="styleSheet">
-    <string notr="true">background-color: rgb(0, 255, 0);
+    <string notr="true">background-color: rgb(255, 255, 255);
 color: rgb(5, 5, 5);
 font: 87 10pt &quot;Noto Sans&quot;;
 selection-background-color: rgb(255, 0, 174);</string>
@@ -53,7 +53,7 @@ selection-background-color: rgb(255, 0, 174);</string>
    <property name="geometry">
     <rect>
      <x>340</x>
-     <y>240</y>
+     <y>70</y>
      <width>80</width>
      <height>26</height>
     </rect>
@@ -70,13 +70,13 @@ color: rgb(16, 16, 16);</string>
    <property name="geometry">
     <rect>
      <x>80</x>
-     <y>240</y>
+     <y>70</y>
      <width>231</width>
      <height>26</height>
     </rect>
    </property>
    <property name="styleSheet">
-    <string notr="true">background-color: rgb(0, 255, 0);
+    <string notr="true">background-color: rgb(255, 255, 255);
 color: rgb(5, 5, 5);
 font: 87 10pt &quot;Noto Sans&quot;;</string>
    </property>
@@ -85,7 +85,7 @@ font: 87 10pt &quot;Noto Sans&quot;;</string>
    <property name="geometry">
     <rect>
      <x>130</x>
-     <y>10</y>
+     <y>0</y>
      <width>231</width>
      <height>51</height>
     </rect>
@@ -104,6 +104,36 @@ font: 87 10pt &quot;Noto Sans&quot;;</string>
     <string>Add Arguments</string>
    </property>
   </widget>
+  <widget class="QPushButton" name="addFile">
+   <property name="geometry">
+    <rect>
+     <x>340</x>
+     <y>100</y>
+     <width>80</width>
+     <height>26</height>
+    </rect>
+   </property>
+   <property name="styleSheet">
+    <string notr="true">background-color: rgb(203, 0, 239);
+color: rgb(16, 16, 16);</string>
+   </property>
+   <property name="text">
+    <string>File</string>
+   </property>
+  </widget>
+  <widget class="QLabel" name="label">
+   <property name="geometry">
+    <rect>
+     <x>70</x>
+     <y>120</y>
+     <width>81</width>
+     <height>18</height>
+    </rect>
+   </property>
+   <property name="text">
+    <string>Output</string>
+   </property>
+  </widget>
  </widget>
  <resources/>
  <connections>

+ 70 - 0
client.cpp

@@ -6,6 +6,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 #include <functional>
+#include <algorithm>
 #include <cstring>
 #include <QDebug>
 #include <QByteArray>
@@ -21,6 +22,8 @@ using namespace KData;
 using json = nlohmann::json;
 
 static const int MAX_BUFFER_SIZE = 2048;
+static const int MAX_PACKET_SIZE = 4096;
+static const int HEADER_SIZE = 4;
 
 flatbuffers::FlatBufferBuilder builder(1024);
 
@@ -75,6 +78,8 @@ void Client::handleMessages() {
                 s_v.push_back(v.data());
             }
             emit Client::messageReceived(COMMANDS_UPDATE_TYPE, "", s_v);
+        } else if(serverWaitingForFile(data_string.c_str())) {
+            sendFileEncoded(outgoing_file);
         }
         std::string formatted_json = getJsonString(data_string);
         emit Client::messageReceived(MESSAGE_UPDATE_TYPE, QString::fromUtf8(formatted_json.data(), formatted_json.size()), {});
@@ -178,6 +183,59 @@ void Client::sendEncoded(std::string message) {
     builder.Clear();
 }
 
+void Client::sendPackets(uint8_t* data, int size) {
+    uint32_t total_size = static_cast<uint32_t>(size + HEADER_SIZE);
+    uint32_t total_packets = static_cast<uint32_t>(ceil(
+        static_cast<double>(
+            total_size / MAX_PACKET_SIZE) // total size / packet
+        )
+    );
+
+    uint32_t idx = 0;
+
+    for (; idx < total_packets; idx++) {
+        bool is_first_packet = (idx == 0);
+        bool is_last_packet = (idx == (total_packets - 1));
+        if (is_first_packet) {
+          uint32_t first_packet_size =
+              std::min(size + HEADER_SIZE, MAX_PACKET_SIZE);
+          uint8_t packet[first_packet_size];
+
+          packet[0] = (total_size >> 24) & 0xFF;
+          packet[1] = (total_size >> 16) & 0xFF;
+          packet[2] = (total_size >> 8) & 0xFF;
+          packet[3] = (total_size) & 0xFF;
+
+          std::memcpy(packet + HEADER_SIZE, data, first_packet_size - HEADER_SIZE);
+          /**
+           * SEND PACKET !!!
+           */
+          ::send(m_client_socket_fd, packet, first_packet_size, 0);
+          if (is_last_packet) {
+            break;
+          }
+          continue;
+        }
+        int offset = (idx * MAX_PACKET_SIZE) - HEADER_SIZE;
+        uint32_t packet_size = std::min(size - offset, MAX_PACKET_SIZE);
+        uint8_t packet[packet_size];
+
+        std::memcpy(packet, data + offset, packet_size);
+        /**
+         * SEND PACKET !!!
+         */
+        ::send(m_client_socket_fd, packet, packet_size, 0);
+        if (is_last_packet) {
+            // cleanup
+            outgoing_file.clear();
+        }
+    }
+}
+
+void Client::sendFileEncoded(QByteArray bytes) {
+    sendPackets(reinterpret_cast<uint8_t*>(bytes.data()), bytes.size());
+}
+
 void Client::closeConnection() {
     if (m_client_socket_fd != -1) {
         std::string stop_operation_string = createOperation("stop", {});
@@ -213,3 +271,15 @@ void Client::execute() {
         }
     }
 }
+
+void Client::sendFile(QByteArray bytes) {
+    if (outgoing_file.isNull()) {
+        std::string send_file_operation = createOperation("FileUpload", {});
+        int size = bytes.size();
+        qDebug() << size << " bytes to send";
+        sendEncoded(send_file_operation);
+        outgoing_file = bytes;
+    } else {
+        qDebug() << "Outgoing file buffer is not ready";
+    }
+}

+ 4 - 1
client.hpp

@@ -49,13 +49,16 @@ public:
 public slots:
     void sendMessage(const QString& s);
     void sendEncoded(std::string message);
+    void sendFileEncoded(QByteArray bytes);
     void setSelectedApp(std::vector<QString> app_names);
+    void sendFile(QByteArray bytes);
 
 signals:
     void messageReceived(int t, QString s,QVector<QString> args);
 
 private:
     void handleMessages();
+    void sendPackets(uint8_t* data, int size);
     int argc;
     char** argv;
     int m_client_socket_fd;
@@ -63,5 +66,5 @@ private:
     CommandMap m_commands;
     CommandArgMap m_command_arg_map;
     std::vector<int> selected_commands;
-
+    QByteArray outgoing_file;
 };

BIN
favicon.ico


+ 9 - 0
headers/util.hpp

@@ -191,6 +191,15 @@ bool isNewSession(const char* data) {
     return false;
 }
 
+bool serverWaitingForFile(const char* data) {
+    Document d;
+    d.Parse(data);
+    if (d.HasMember("message")) {
+        return strcmp(d["message"].GetString(), "File Ready") == 0;
+    }
+    return false;
+}
+
 std::string stringTupleVecToJson(
     std::vector<std::pair<std::string, std::string>> v) {
     json j{};

+ 4 - 0
mainwindow.cpp

@@ -98,6 +98,10 @@ void MainWindow::connectClient() {
             qDebug() << "Can only add arguments to one app. Please select just one app before adding arguments";
         }
     });
+
+    QObject::connect(arg_ui, &ArgDialog::uploadFile, this, [q_client](QByteArray bytes) {
+        q_client->sendFile(bytes);
+    });
 }
 
 /**

+ 1 - 1
mainwindow.h

@@ -4,7 +4,7 @@
 #include <QMainWindow>
 #include <QString>
 #include <QList>
-#include <QListWidget>
+#include <QListView>
 #include <QListWidgetItem>
 #include <client.hpp>
 #include <headers/ktextedit.hpp>

+ 85 - 85
mainwindow.ui

@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>380</width>
-    <height>485</height>
+    <height>493</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -45,76 +45,51 @@ background-color: rgb(10, 10, 10);</string>
     <property name="geometry">
      <rect>
       <x>10</x>
-      <y>70</y>
+      <y>60</y>
       <width>357</width>
-      <height>351</height>
+      <height>370</height>
      </rect>
     </property>
     <layout class="QGridLayout" name="gridLayout_2">
-     <item row="1" column="0" colspan="2">
-      <widget class="QTextEdit" name="inputText">
-       <property name="styleSheet">
-        <string notr="true">background-color: rgb(0, 255, 0);
-color: rgb(5, 5, 5);
-font: 87 10pt &quot;Noto Sans&quot;;</string>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="0" colspan="2">
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <item>
-        <widget class="QProgressBar" name="progressBar">
-         <property name="styleSheet">
-          <string notr="true">background-color: rgb(203, 0, 239);
+     <item row="0" column="1">
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="1" column="0">
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QPushButton" name="addArgs">
+           <property name="styleSheet">
+            <string notr="true">background-color: rgb(203, 0, 239);
 color: rgb(16, 16, 16);</string>
-         </property>
-         <property name="value">
-          <number>0</number>
-         </property>
-        </widget>
+           </property>
+           <property name="text">
+            <string>Args</string>
+           </property>
+          </widget>
+         </item>
+         <item>
+          <widget class="QPushButton" name="execute">
+           <property name="styleSheet">
+            <string notr="true">background-color: rgb(203, 0, 239);
+color: rgb(16, 16, 16);</string>
+           </property>
+           <property name="text">
+            <string>Execute</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
        </item>
-       <item>
-        <widget class="QPushButton" name="sendMessage">
+       <item row="3" column="0">
+        <widget class="QPushButton" name="disconnect">
          <property name="styleSheet">
           <string notr="true">background-color: rgb(203, 0, 239);
 color: rgb(16, 16, 16);</string>
          </property>
          <property name="text">
-          <string>Send</string>
+          <string>Disconnect</string>
          </property>
         </widget>
        </item>
-      </layout>
-     </item>
-     <item row="0" column="0">
-      <widget class="QTextEdit" name="messages">
-       <property name="toolTip">
-        <string>Messages</string>
-       </property>
-       <property name="toolTipDuration">
-        <number>1</number>
-       </property>
-       <property name="autoFillBackground">
-        <bool>false</bool>
-       </property>
-       <property name="styleSheet">
-        <string notr="true">background-color: rgb(0, 255, 0);
-color: rgb(5, 5, 5);
-font: 87 10pt &quot;Noto Sans&quot;;</string>
-       </property>
-       <property name="lineWrapMode">
-        <enum>QTextEdit::WidgetWidth</enum>
-       </property>
-       <property name="readOnly">
-        <bool>true</bool>
-       </property>
-       <property name="placeholderText">
-        <string/>
-       </property>
-      </widget>
-     </item>
-     <item row="0" column="1">
-      <layout class="QGridLayout" name="gridLayout">
        <item row="0" column="0">
         <widget class="QListWidget" name="appList">
          <property name="font">
@@ -155,42 +130,67 @@ background-color: rgb(255, 0, 153);
          </property>
         </widget>
        </item>
-       <item row="3" column="0">
-        <widget class="QPushButton" name="disconnect">
+      </layout>
+     </item>
+     <item row="0" column="0">
+      <widget class="QTextEdit" name="messages">
+       <property name="toolTip">
+        <string>Messages</string>
+       </property>
+       <property name="toolTipDuration">
+        <number>1</number>
+       </property>
+       <property name="autoFillBackground">
+        <bool>false</bool>
+       </property>
+       <property name="styleSheet">
+        <string notr="true">background-color: rgb(0, 255, 0);
+color: rgb(5, 5, 5);
+font: 87 10pt &quot;Noto Sans&quot;;</string>
+       </property>
+       <property name="lineWrapMode">
+        <enum>QTextEdit::WidgetWidth</enum>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="placeholderText">
+        <string/>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0" colspan="2">
+      <widget class="QTextEdit" name="inputText">
+       <property name="styleSheet">
+        <string notr="true">background-color: rgb(0, 255, 0);
+color: rgb(5, 5, 5);
+font: 87 10pt &quot;Noto Sans&quot;;</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="0" colspan="2">
+      <layout class="QHBoxLayout" name="horizontalLayout">
+       <item>
+        <widget class="QProgressBar" name="progressBar">
          <property name="styleSheet">
           <string notr="true">background-color: rgb(203, 0, 239);
 color: rgb(16, 16, 16);</string>
          </property>
-         <property name="text">
-          <string>Disconnect</string>
+         <property name="value">
+          <number>0</number>
          </property>
         </widget>
        </item>
-       <item row="1" column="0">
-        <layout class="QHBoxLayout" name="horizontalLayout_2">
-         <item>
-          <widget class="QPushButton" name="addArgs">
-           <property name="styleSheet">
-            <string notr="true">background-color: rgb(203, 0, 239);
-color: rgb(16, 16, 16);</string>
-           </property>
-           <property name="text">
-            <string>Args</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QPushButton" name="execute">
-           <property name="styleSheet">
-            <string notr="true">background-color: rgb(203, 0, 239);
+       <item>
+        <widget class="QPushButton" name="sendMessage">
+         <property name="styleSheet">
+          <string notr="true">background-color: rgb(203, 0, 239);
 color: rgb(16, 16, 16);</string>
-           </property>
-           <property name="text">
-            <string>Execute</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
+         </property>
+         <property name="text">
+          <string>Send</string>
+         </property>
+        </widget>
        </item>
       </layout>
      </item>

+ 20 - 8
ui_argdialog.h

@@ -28,46 +28,56 @@ public:
     QPushButton *addArgument;
     QLineEdit *argInput;
     QLabel *argDialogTitle;
+    QPushButton *addFile;
+    QLabel *label;
 
     void setupUi(QDialog *ArgDialog)
     {
         if (ArgDialog->objectName().isEmpty())
             ArgDialog->setObjectName(QString::fromUtf8("ArgDialog"));
-        ArgDialog->resize(490, 347);
+        ArgDialog->resize(490, 314);
         argButtonBox = new QDialogButtonBox(ArgDialog);
         argButtonBox->setObjectName(QString::fromUtf8("argButtonBox"));
-        argButtonBox->setGeometry(QRect(70, 300, 341, 32));
+        argButtonBox->setGeometry(QRect(80, 260, 341, 32));
         argButtonBox->setStyleSheet(QString::fromUtf8("background-color: rgb(203, 0, 239);\n"
 "color: rgb(16, 16, 16);"));
         argButtonBox->setOrientation(Qt::Horizontal);
         argButtonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
         argList = new QListView(ArgDialog);
         argList->setObjectName(QString::fromUtf8("argList"));
-        argList->setGeometry(QRect(60, 60, 361, 151));
-        argList->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 255, 0);\n"
+        argList->setGeometry(QRect(60, 140, 361, 91));
+        argList->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 255, 255);\n"
 "color: rgb(5, 5, 5);\n"
 "font: 87 10pt \"Noto Sans\";\n"
 "selection-background-color: rgb(255, 0, 174);"));
         addArgument = new QPushButton(ArgDialog);
         addArgument->setObjectName(QString::fromUtf8("addArgument"));
-        addArgument->setGeometry(QRect(340, 240, 80, 26));
+        addArgument->setGeometry(QRect(340, 70, 80, 26));
         addArgument->setStyleSheet(QString::fromUtf8("background-color: rgb(203, 0, 239);\n"
 "color: rgb(16, 16, 16);"));
         argInput = new QLineEdit(ArgDialog);
         argInput->setObjectName(QString::fromUtf8("argInput"));
-        argInput->setGeometry(QRect(80, 240, 231, 26));
-        argInput->setStyleSheet(QString::fromUtf8("background-color: rgb(0, 255, 0);\n"
+        argInput->setGeometry(QRect(80, 70, 231, 26));
+        argInput->setStyleSheet(QString::fromUtf8("background-color: rgb(255, 255, 255);\n"
 "color: rgb(5, 5, 5);\n"
 "font: 87 10pt \"Noto Sans\";"));
         argDialogTitle = new QLabel(ArgDialog);
         argDialogTitle->setObjectName(QString::fromUtf8("argDialogTitle"));
-        argDialogTitle->setGeometry(QRect(130, 10, 231, 51));
+        argDialogTitle->setGeometry(QRect(130, 0, 231, 51));
         QFont font;
         font.setPointSize(22);
         font.setBold(true);
         font.setWeight(75);
         argDialogTitle->setFont(font);
         argDialogTitle->setStyleSheet(QString::fromUtf8("color: rgb(170, 0, 255);"));
+        addFile = new QPushButton(ArgDialog);
+        addFile->setObjectName(QString::fromUtf8("addFile"));
+        addFile->setGeometry(QRect(340, 100, 80, 26));
+        addFile->setStyleSheet(QString::fromUtf8("background-color: rgb(203, 0, 239);\n"
+"color: rgb(16, 16, 16);"));
+        label = new QLabel(ArgDialog);
+        label->setObjectName(QString::fromUtf8("label"));
+        label->setGeometry(QRect(70, 120, 81, 18));
 
         retranslateUi(ArgDialog);
         QObject::connect(argButtonBox, SIGNAL(accepted()), ArgDialog, SLOT(accept()));
@@ -81,6 +91,8 @@ public:
         ArgDialog->setWindowTitle(QCoreApplication::translate("ArgDialog", "Dialog", nullptr));
         addArgument->setText(QCoreApplication::translate("ArgDialog", "Add", nullptr));
         argDialogTitle->setText(QCoreApplication::translate("ArgDialog", "Add Arguments", nullptr));
+        addFile->setText(QCoreApplication::translate("ArgDialog", "File", nullptr));
+        label->setText(QCoreApplication::translate("ArgDialog", "Output", nullptr));
     } // retranslateUi
 
 };