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