From e7e3711dc52cf6236c2cff326c5e5d311b131a06 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= <hugo@hornquist.se>
Date: Thu, 16 May 2019 14:16:33 +0200
Subject: [PATCH] Now parses xml from c++.

---
 Makefile        |  4 +--
 mediawikifs.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++---
 mediawikifs.h   |  2 +-
 3 files changed, 88 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index cd208e3..17dd622 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-LIBS = $(shell pkg-config --libs libcurl fuse)
-CFLAGS = $(shell pkg-config --cflags libcurl fuse) -ggdb \
+LIBS = $(shell pkg-config --libs libcurl fuse tinyxml2)
+CFLAGS = $(shell pkg-config --cflags libcurl fuse tinyxml2) -ggdb \
 		 -std=c++2a -Wall -Wextra -pedantic
 
 CPP_FILES = $(wildcard *.cpp)
diff --git a/mediawikifs.cpp b/mediawikifs.cpp
index beda09f..1e5eb42 100644
--- a/mediawikifs.cpp
+++ b/mediawikifs.cpp
@@ -7,17 +7,71 @@
 #include <cstdio>
 #include <cstring>
 #include <cstdlib>
+#include <ctime>
 
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <curl/curl.h>
 #include <fuse.h>
 
+#include <tinyxml2.h>
 
 static std::string str;
 
 static CURL* curl;
 
+time_t parse_timestring (const char* str_) {
+	char* str = new char[strlen(str_)];
+	strcpy(str, str_);
+
+	int len = 1;
+	while (*(++str) != '\0') ++len;
+
+	int year, month, day, hour, minute, second, zone_offset;
+
+	switch (len) {
+		case 20:
+			zone_offset = 0;
+			--str; /* Z */
+			/* fallthrough */
+		case 19:
+			second  =  *(--str) - '0';
+			second += (*(--str) - '0') * 10;
+			--str; /* : */
+			minute  =  *(--str) - '0';
+			minute += (*(--str) - '0') * 10;
+			--str; /* : */
+			hour    =  *(--str) - '0';
+			hour   += (*(--str) - '0') * 10;
+			--str; /* T */
+			/* fallthrough */
+		case 10:
+			day     =  *(--str) - '0';
+			day    += (*(--str) - '0') * 10;
+			--str; /* - */
+			month   =  *(--str) - '0';
+			month  += (*(--str) - '0') * 10;
+			--str; /* - */
+			year    =  *(--str) - '0';
+			year   += (*(--str) - '0') * 10;
+			year   += (*(--str) - '0') * 100;
+			year   += (*(--str) - '0') * 1000;
+	}
+	delete str;
+
+	struct tm t;
+	t.tm_sec = second;
+	t.tm_min = minute;
+	t.tm_hour = hour;
+	t.tm_mday = day;
+	t.tm_mon = month - 1;
+	t.tm_year = year - 1900;
+
+	return mktime (& t);
+}
+
+using namespace tinyxml2;
+
 static std::map<std::string, page> pages;
 page* get_page(const char* path) {
 	page* p = & pages[path];
@@ -33,11 +87,32 @@ page* get_page(const char* path) {
 	code = curl_easy_perform (curl);
 	if (code != CURLE_OK) ERR("Perform %i", code);
 
+	XMLDocument doc;
+	doc.Parse (str.c_str());
+	XMLNode* root = doc.RootElement();
+	if (root == nullptr) return nullptr;
+
+	XMLNode* page = root->FirstChildElement("page");
+	if (page == nullptr) return nullptr;
+
+	XMLNode* revision = page->FirstChildElement("revision");
+	if (revision == nullptr) return nullptr;
+
+	const char* timestr =
+		revision->FirstChildElement("timestamp")
+		        ->ToElement()
+		        ->GetText();
+
+
 	p->init = true;
 	p->name = path;
-	p->data = str;
-	p->size = str.size();
-	p->timestamp = 1;
+	p->timestamp = parse_timestring (timestr);
+
+	XMLElement* el = revision->FirstChildElement("text")->ToElement();
+
+	p->data = el->GetText();
+	p->data += "\n";
+	p->size = el->UnsignedAttribute("bytes") + 1;
 
 	return p;
 }
@@ -56,9 +131,13 @@ int getattr_callback(const char* path, struct stat* st) {
 	} else {
 
 		page* p = get_page(path + 1);
+		if (p == nullptr) {
+			if (p == nullptr) return -ENOENT;
+		}
+
 		st->st_mode = S_IFREG | 0444;
 		st->st_size = p->size;
-		// st->st_mtime
+		st->st_mtime = p->timestamp;
 	}
 
 	return 0;
@@ -77,6 +156,8 @@ int read_callback (
 {
 	page* p = get_page (path + 1);
 
+	if (p == nullptr) return -ENOENT;
+
 	std::string* s = & p->data;
 	ssize_t len = s->size();
 	
diff --git a/mediawikifs.h b/mediawikifs.h
index d78ef7c..258ba43 100644
--- a/mediawikifs.h
+++ b/mediawikifs.h
@@ -13,7 +13,7 @@ struct page {
 	bool init = false;
 	std::string name;
 	size_t size;
-	uint64_t timestamp;
+	time_t timestamp;
 	std::string data;
 };
 
-- 
GitLab