summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2023-01-28 15:07:14 +0100
committerRoland Reichwein <mail@reichwein.it>2023-01-28 15:07:14 +0100
commita61c702d91d7444ce0bb094ddccc70f72416500b (patch)
tree8d5a47c73666ee2b710a7a34c0c392b728bda45b
parentf44d36b05e43cabde31aeaba5d25fded140345a1 (diff)
Added WebAssembly for C++ implementation of Diff
-rwxr-xr-xMakefile3
-rw-r--r--diff.cpp38
-rw-r--r--diff.h10
-rw-r--r--html/index.html3
-rw-r--r--html/whiteboard.js25
-rw-r--r--tests/Makefile3
-rw-r--r--tests/test-diff.cpp28
-rw-r--r--webassembly/Makefile20
-rw-r--r--whiteboard.cpp7
9 files changed, 122 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 449e915..d0a4b31 100755
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/diff.cpp b/diff.cpp
index b3ed5ce..ee17fad 100644
--- a/diff.cpp
+++ b/diff.cpp
@@ -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());
+ }
+
+}
diff --git a/diff.h b/diff.h
index 0193238..fbf09b1 100644
--- a/diff.h
+++ b/diff.h
@@ -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)