diff options
-rw-r--r-- | storage.cpp | 33 | ||||
-rw-r--r-- | storage.h | 3 | ||||
-rw-r--r-- | tests/test-storage.cpp | 26 | ||||
-rw-r--r-- | whiteboard.cpp | 41 | ||||
-rw-r--r-- | whiteboard.h | 2 |
5 files changed, 65 insertions, 40 deletions
diff --git a/storage.cpp b/storage.cpp index 6fb5b64..e7e9248 100644 --- a/storage.cpp +++ b/storage.cpp @@ -4,6 +4,7 @@ #include <chrono> #include <iostream> +#include <random> #include <SQLiteCpp/SQLiteCpp.h> @@ -164,3 +165,35 @@ void Storage::setRow(const std::string& id, const std::string& document, int rev throw std::runtime_error("Unable to insert row with id "s + id); } +uint32_t Storage::checksum32(const std::string& s) +{ + uint32_t result{0}; + for (unsigned int i = 0; i < s.size(); i++) { + result = ((result >> 1) | ((result & 1) << 31)) ^ (s[i] & 0xFF); + } + return result & 0x7FFFFFFF; +} + +std::string Storage::generate_id() +{ + static std::random_device r; + static std::default_random_engine e1(r()); + static std::uniform_int_distribution<int> uniform_dist(0, 35); + + // limit tries + for (int j = 0; j < 100000; j++) { + std::string result; + for (int i = 0; i < 6; i++) { + char c{static_cast<char>('0' + uniform_dist(e1))}; + if (c > '9') + c = c - '9' + 'a'; + result.push_back(c); + } + + if (!exists(result)) + return result; + } + + return "endofcodes"; +} + @@ -30,6 +30,9 @@ public: void cleanup(); + std::string generate_id(); + uint32_t checksum32(const std::string& s); + private: SQLite::Database m_db; uint64_t m_maxage; diff --git a/tests/test-storage.cpp b/tests/test-storage.cpp index b9994fb..1f3eda4 100644 --- a/tests/test-storage.cpp +++ b/tests/test-storage.cpp @@ -206,3 +206,29 @@ TEST_F(StorageTest, revision_increment) EXPECT_EQ(storage.getRevision("iabc"), 0); } +TEST_F(StorageTest, generate_id) +{ + Storage storage(*m_config); + std::string a{storage.generate_id()}; + std::string b{storage.generate_id()}; + + EXPECT_NE(a, b); + EXPECT_NE(a, ""); + EXPECT_NE(b, ""); + + EXPECT_GE(a.size(), 6); + +} + +TEST_F(StorageTest, checksum32) +{ + Storage storage(*m_config); + EXPECT_EQ(storage.checksum32(""), 0); + EXPECT_EQ(storage.checksum32("0"), 48); + EXPECT_EQ(storage.checksum32("\x00"), 0); + EXPECT_EQ(storage.checksum32("123"), 1073741862); + EXPECT_EQ(storage.checksum32("a"), 97); + EXPECT_EQ(storage.checksum32("ab"), 82); + EXPECT_EQ(storage.checksum32("abc"), 1073741898); +} + diff --git a/whiteboard.cpp b/whiteboard.cpp index 75472ba..6466635 100644 --- a/whiteboard.cpp +++ b/whiteboard.cpp @@ -14,7 +14,6 @@ #include <functional> #include <filesystem> #include <mutex> -#include <random> #include <regex> #include <string> #include <thread> @@ -56,6 +55,7 @@ Whiteboard::Whiteboard(): { } +// contents of cleanup thread; looping void Whiteboard::storage_cleanup() { while(true) { @@ -67,38 +67,6 @@ void Whiteboard::storage_cleanup() } } -uint32_t Whiteboard::checksum32(const std::string& s) -{ - uint32_t result{0}; - for (unsigned int i = 0; i < s.size(); i++) { - result = ((result >> 1) | ((result & 1) << 31)) ^ (s[i] & 0xFF); - } - return result & 0x7FFFFFFF; -} - -std::string Whiteboard::generate_id() -{ - static std::random_device r; - static std::default_random_engine e1(r()); - static std::uniform_int_distribution<int> uniform_dist(0, 35); - - // limit tries - for (int j = 0; j < 100000; j++) { - std::string result; - for (int i = 0; i < 6; i++) { - char c{static_cast<char>('0' + uniform_dist(e1))}; - if (c > '9') - c = c - '9' + 'a'; - result.push_back(c); - } - - if (!m_storage.exists(result)) - return result; - } - - return "endofcodes"; -} - // the actual main() for testability int Whiteboard::run(int argc, char* argv[]) { @@ -179,11 +147,8 @@ int Whiteboard::run(int argc, char* argv[]) std::string checksum_s {xml.get<std::string>("request.checksum")}; uint32_t checksum{static_cast<uint32_t>(stoul(checksum_s))}; - //std::cout << "Checksum JS: " << checksum_s << std::endl; - //std::cout << "Checksum C++: " << checksum32(filedata) << std::endl; - std::string filedata {m_storage.getDocument(id)}; - if (checksum != checksum32(filedata)) { + if (checksum != m_storage.checksum32(filedata)) { //std::cout << "Sending change..." << std::endl; FCGX_PutS("Content-Type: application/octet-stream\r\n", request.out); FCGX_FPrintF(request.out, "Content-Length: %d\r\n\r\n", filedata.size()); @@ -195,7 +160,7 @@ int Whiteboard::run(int argc, char* argv[]) } } else if (command == "newid") { FCGX_PutS("Content-Type: text/plain\r\n\r\n", request.out); - FCGX_PutS(generate_id().c_str(), request.out); + FCGX_PutS(m_storage.generate_id().c_str(), request.out); } else if (command == "qrcode") { std::string url{xml.get<std::string>("request.url")}; diff --git a/whiteboard.h b/whiteboard.h index be89f4b..f50f455 100644 --- a/whiteboard.h +++ b/whiteboard.h @@ -11,8 +11,6 @@ class Whiteboard public: Whiteboard(); int run(int argc, char* argv[]); - std::string generate_id(); - uint32_t checksum32(const std::string& s); private: Config m_config; |