diff options
-rwxr-xr-x | Makefile | 3 | ||||
-rw-r--r-- | diff.cpp | 38 | ||||
-rw-r--r-- | diff.h | 10 | ||||
-rw-r--r-- | html/index.html | 3 | ||||
-rw-r--r-- | html/whiteboard.js | 25 | ||||
-rw-r--r-- | tests/Makefile | 3 | ||||
-rw-r--r-- | tests/test-diff.cpp | 28 | ||||
-rw-r--r-- | webassembly/Makefile | 20 | ||||
-rw-r--r-- | whiteboard.cpp | 7 |
9 files changed, 122 insertions, 15 deletions
@@ -18,6 +18,7 @@ OBJECTS=$(HEADERS:.h=.o) TARGETS=whiteboard build: $(TARGETS) + $(MAKE) -C webassembly all: build ./whiteboard -c whiteboard.conf @@ -49,7 +50,9 @@ test: clean: -rm -f *.o $(TARGETS) *.gcov + -rm -f html/libwhiteboard.wasm html/libwhiteboard.js $(MAKE) -C tests clean + $(MAKE) -C webassembly clean deb: dpkg-buildpackage @@ -102,12 +102,28 @@ void Diff::create(const std::string& old_version, const std::string& new_version m_data = new_version.substr(old_pos0, new_pos1 - new_pos0); } +Diff::Diff(const std::string& xml) +{ + create(xml); +} + +void Diff::create(const std::string& xml) +{ + pt::ptree tree; + std::istringstream ss{xml}; + pt::read_xml(ss, tree, pt::xml_parser::no_comments | pt::xml_parser::trim_whitespace); + + m_pos0 = tree.get<int>("diff.start"); + m_pos1 = tree.get<int>("diff.end"); + m_data = tree.get<std::string>("diff.data"); +} + boost::property_tree::ptree Diff::get_structure() const { pt::ptree ptree; - ptree.put("diff.chunk.start", std::to_string(m_pos0)); - ptree.put("diff.chunk.end", std::to_string(m_pos1)); - ptree.put("diff.chunk.data", m_data); + ptree.put("diff.start", std::to_string(m_pos0)); + ptree.put("diff.end", std::to_string(m_pos1)); + ptree.put("diff.data", m_data); return ptree; } @@ -123,3 +139,19 @@ std::string Diff::get_xml() const return oss.str(); } +extern "C" { + + const char* diff_create(const char* old_version, const char* new_version) + { + Diff diff{old_version, new_version}; + return strdup(diff.get_xml().c_str()); + } + + const char* diff_apply(const char* old_version, const char* diff) + { + Diff d{diff}; + + return strdup(d.apply(old_version).c_str()); + } + +} @@ -9,9 +9,12 @@ class Diff public: Diff(); Diff(const std::string& old_version, const std::string& new_version); + void create(const std::string& old_version, const std::string& new_version); + + Diff(const std::string& xml); + void create(const std::string& xml); std::string apply(const std::string& old_version) const; - void create(const std::string& old_version, const std::string& new_version); boost::property_tree::ptree get_structure() const; std::string get_xml() const; @@ -22,3 +25,8 @@ private: size_t m_pos1{}; std::string m_data; }; + +extern "C" { + const char* diff_create(const char* old_version, const char* new_version); + const char* diff_apply(const char* old_version, const char* diff); +} diff --git a/html/index.html b/html/index.html index 4d1fb2a..decc540 100644 --- a/html/index.html +++ b/html/index.html @@ -7,6 +7,7 @@ <title>Reichwein Whiteboard</title> <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon"/> <link rel="stylesheet" type="text/css" href="whiteboard.css"/> + <script src="libwhiteboard.js"></script> <script src="whiteboard.js"></script> </head> <body onload="init();"> @@ -20,7 +21,7 @@ <br/> <button class="button" onclick="on_new_page();">New page</button> <button class="button" onclick="on_qrcode_click();">QR code</button> - <span id="connecting">Connecting...</span> + <span id="status">Starting up...</span> <button class="buttonred" id="reconnect" onclick="on_reconnect_click();" hidden>Reconnect</button> <br/> <br/> diff --git a/html/whiteboard.js b/html/whiteboard.js index 83601b8..aef4391 100644 --- a/html/whiteboard.js +++ b/html/whiteboard.js @@ -8,6 +8,17 @@ var revision; // helper for breaking feedback loop var caretpos = 0; +function set_status(message) +{ + if (message == "") { + document.getElementById("status").textContent = message; + document.getElementById("status").style.display = 'block'; + } else { + document.getElementById("status").textContent = ""; + document.getElementById("status").style.display = 'none'; + } +} + function showQRWindow() { document.getElementById("qrwindow").style.display = 'block'; @@ -103,7 +114,7 @@ function handleSelection() { function connect_websocket() { document.getElementById("reconnect").style.display = 'none'; - document.getElementById("connecting").style.display = 'block'; + set_status("Connecting..."); var newlocation = location.origin + location.pathname; newlocation = newlocation.replace(/^http/, 'ws'); if (newlocation.slice(-1) != "/") @@ -123,7 +134,7 @@ function connect_websocket() { websocket.send("<request><command>getversion</command></request>"); websocket.send("<request><command>getfile</command><id>" + get_id() + "</id></request>"); - document.getElementById("connecting").style.display = 'none'; + set_status(""); // ok }; websocket.onclose = function(e) { @@ -135,15 +146,21 @@ function connect_websocket() { alert("Error: Server connection closed."); document.getElementById("reconnect").style.display = 'inline'; }; - } +// button in html function on_reconnect_click() { connect_websocket(); } function init_board() { - connect_websocket(); + set_status("Loading..."); + Module.onRuntimeInitialized = () => { + connect_websocket(); + }; + //Module.onRuntimeInitialized = () => { alert("DEBUG: " + Module._getnum(1) + " " + UTF8ToString(Module._getstring(allocateUTF8("abc")))); + //_free(allocateUTF8("abc")); + //}; var board = document.getElementById("board"); board.addEventListener("input", function() {on_input(); }); diff --git a/tests/Makefile b/tests/Makefile index c4109d5..0347210 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -17,7 +17,8 @@ UNITTESTS=test-config.cpp \ test-storage.cpp \ test-compiledsql.cpp \ test-qrcode.cpp \ - test-whiteboard.cpp + test-whiteboard.cpp \ + test-diff.cpp CXXFLAGS+=\ -I/usr/src/googletest/googletest/include \ diff --git a/tests/test-diff.cpp b/tests/test-diff.cpp new file mode 100644 index 0000000..b6b703a --- /dev/null +++ b/tests/test-diff.cpp @@ -0,0 +1,28 @@ +#include <gtest/gtest.h> + +#include <filesystem> +#include <string> +#include <system_error> + +#include "libreichwein/file.h" + +#include "diff.h" + +namespace fs = std::filesystem; +using namespace Reichwein; + +class DiffTest: public ::testing::Test +{ +protected: + DiffTest(){ + } + + ~DiffTest(){ + } +}; + +TEST_F(DiffTest, constructor) +{ + Diff diff{}; +} + diff --git a/webassembly/Makefile b/webassembly/Makefile new file mode 100644 index 0000000..eeaa357 --- /dev/null +++ b/webassembly/Makefile @@ -0,0 +1,20 @@ +TARGET=libwhiteboard.wasm +TARGETJS=$(TARGET:.wasm=.js) + +OBJS=diff.o + +CXX=em++ + +CXXFLAGS=-I/usr/include +LDFLAGS=-s WASM=1 -s LINKABLE=1 -s EXPORT_ALL=1 +default: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) $(LDFLAGS) $(OBJS) -o $(TARGETJS) + cp $(TARGETJS) $(TARGET) ../html/ + +diff.o: ../diff.cpp + $(CXX) -c $< $(CXXFLAGS) -o $@ + +clean: + -rm -f *.o *.js *.wasm *.html diff --git a/whiteboard.cpp b/whiteboard.cpp index df18242..b84f7cc 100644 --- a/whiteboard.cpp +++ b/whiteboard.cpp @@ -36,6 +36,7 @@ #include "libreichwein/base64.h" #include "libreichwein/file.h" +#include "libreichwein/xml.h" #include "config.h" #include "qrcode.h" @@ -88,11 +89,7 @@ std::string make_xml(const std::initializer_list<std::pair<std::string, std::str xml.put(fmt::format("serverinfo.{}", i.first), i.second); } - std::ostringstream oss; - // write_xml_element instead of write_xml to omit <!xml...> header - //pt::xml_parser::write_xml(oss, xml); - pt::xml_parser::write_xml_element(oss, {}, xml, -1, boost::property_tree::xml_writer_settings<pt::ptree::key_type>{}); - return oss.str(); + return Reichwein::XML::plain_xml(xml); } void Whiteboard::notify_other_connections_file(Whiteboard::connection& c, const std::string& id) |