From f7dc7c17af52e8300cb188c4fb3e4a8b1638e8f9 Mon Sep 17 00:00:00 2001 From: Jonas Suhr Christensen Date: Thu, 22 Mar 2012 16:31:28 +0100 Subject: Fixed order of task in init. Now are tasks only (hopefully) added after its parent. Added write and read. --- src/Makefile.am | 18 +++- src/msgparser.cc | 4 +- src/muniad.cc | 4 + src/task.cc | 54 ++++++++++ src/task.h | 73 +++++++++++++- src/task_proto.cc | 288 ++++++++++++++++++++++++++++++------------------------ 6 files changed, 306 insertions(+), 135 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index d16b041..8c2cc25 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,22 +2,32 @@ SUBDIRS = bin_PROGRAMS = muniad -muniad_LDADD = $(LIBWEBSOCKETS_LIBS) +muniad_LDADD = $(LIBWEBSOCKETS_LIBS) $(EXPAT_LIBS) -muniad_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS) -I/usr/local/include +muniad_CXXFLAGS = $(LIBWEBSOCKETS_CFLAGS) $(EXPAT_CFLAGS) -I/usr/local/include muniad_SOURCES = \ + debug.cc \ muniad.cc \ + log.cc \ http.cc \ msgparser.cc \ + saxparser.cc \ task.cc \ - task_proto.cc + task_proto.cc \ + xml_encode_decode.cc \ + xmlparser.cc EXTRA_DIST = \ + debug.h \ + log.h \ http.h \ msgparser.h \ + saxparser.h \ task.h \ - task_proto.h + task_proto.h \ + xml_encode_decode.h \ + xmlparser.h ################ # Test Section # diff --git a/src/msgparser.cc b/src/msgparser.cc index 675e305..c5d5ab3 100644 --- a/src/msgparser.cc +++ b/src/msgparser.cc @@ -173,10 +173,10 @@ MsgVector parse_msg(std::string data) { } sprintf(m.add.title, "%s", t[1].c_str()); sprintf(m.add.desc, "%s", t[2].c_str()); - m.add.parent_id = atoi(t[3].c_str()); + m.add.parent_id = atoi(t[3].c_str()); // m.add.x = atoi(t[3].c_str()); // m.add.y = atoi(t[4].c_str()); -// printf("addcmd: %s %s %d %d\n", m.add.title, m.add.desc, m.add.x, m.add.y); + printf("addcmd: %s %s %d\n", m.add.title, m.add.desc, m.add.parent_id); break; } case cmd::del: { diff --git a/src/muniad.cc b/src/muniad.cc index ab69456..4523d8a 100644 --- a/src/muniad.cc +++ b/src/muniad.cc @@ -64,6 +64,7 @@ static struct option options[] = { { "ssl", no_argument, NULL, 's' }, { "killmask", no_argument, NULL, 'k' }, { "interface", required_argument, NULL, 'i' }, +// { "dumpfile", required_argument, NULL, 'd'}, { NULL, 0, 0, 0 } }; @@ -81,6 +82,7 @@ int main(int argc, char **argv) int opts = 0; char interface_name[128] = ""; const char * interface = NULL; +// std::string dumpfile; fprintf(stderr, "Munia test server\n" "(C) Copyright 2012 Bent Bisballe Nyeng (deva@aasimon.org)\n" @@ -94,6 +96,8 @@ int main(int argc, char **argv) case 's': use_ssl = 1; break; +// case 'd': +// dumpfile = optarg; case 'k': opts = LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK; break; diff --git a/src/task.cc b/src/task.cc index 9940fc6..03c1e56 100644 --- a/src/task.cc +++ b/src/task.cc @@ -27,7 +27,13 @@ */ #include "task.h" +#include + +#include "xml_encode_decode.h" + + TaskList tasklist; + static int id_count = 0; int current_id_count() { @@ -47,3 +53,51 @@ task_t create_task(std::string title, std::string desc, return t; } + +TaskList load_tasklist_from_file(std::string file) { + TaskList list; + + // create MuniaDb class which handles tasks, db-flush and db-init. + + return list; +} + +bool save_tasklist_to_file(TaskList list, std::string file) { + + FILE* fp; + + if(! (fp = fopen(file.c_str(), "w"))) { + return false; + } + + if(!fprintf(fp, "\n")) { + fclose(fp); + return false; + } + + TaskList::iterator it; + for(it = tasklist.begin(); it != tasklist.end(); it++) { + task_t t = *it; + int r = 1; + +// printf("Flushing task %d\n", t.id); + + r |= fprintf(fp, " \n", t.id, t.parent_id); + r |= fprintf(fp, " %s\n", xml_encode(t.title).c_str()); + r |= fprintf(fp, " %s\n", xml_encode(t.desc).c_str()); + r |= fprintf(fp, " )\n"); + + if(!r) { + fclose(fp); + return false; + } + } + + if(!fprintf(fp, "\n")) { + fclose(fp); + return false; + } + + fclose(fp); + return true; +} diff --git a/src/task.h b/src/task.h index 43541bc..5866719 100644 --- a/src/task.h +++ b/src/task.h @@ -30,6 +30,9 @@ #include #include +#include +#include +//#include /* Task: @@ -86,10 +89,78 @@ typedef struct { } task_t; -typedef std::list TaskList; +//typedef std::list TaskList; + +class CompareByParentid { +public: + bool operator()(const task_t &a, const task_t &b) const { + return a.parent_id < b.parent_id; + } +}; + + + + +class TaskList : public std::list{ +public: + TaskList() {} + ~TaskList(){} + + void insert(task_t t) { + printf("inserting task %d with parent %d\n", t.id, t.parent_id); + + if(t.parent_id == -1) { + std::list::push_front(t); + return; + } + + std::list::iterator it; + for(it = begin(); it != end(); ++it) { + printf("\tcomparing %d and %d\n", t.parent_id, it->id); + if(t.parent_id == it->id) { + break; + } + } + assert(it != end()); + + std::list::insert(++it, t); + +// std::list::push_back(t); +// std::list::sort(CompareByParentid()); + + } + + void move(task_t t) { + std::list::iterator it; + for(it = begin(); it != end(); it++) { + if(t.id == it->id) { + break; + } + } + assert(it != end()); + // if(it != end()) { + std::list::erase(it); + // } + insert(t); + } + + void push_back(task_t t) { + insert(t); + } + +private: + std::list list; +}; + + extern TaskList tasklist; +//typedef std::priority_queue, CompareByParentid> TaskList; + task_t create_task(std::string title, std::string desc, /*int x, int y*/ int parent_id); +TaskList load_tasklist_from_file(std::string file); +bool save_tasklist_to_file(TaskList t, std::string file); + #endif/*__MUNIA_TASK_H__*/ diff --git a/src/task_proto.cc b/src/task_proto.cc index 2312c9e..ced0552 100644 --- a/src/task_proto.cc +++ b/src/task_proto.cc @@ -35,10 +35,11 @@ #include "task.h" #include "msgparser.h" +#include "xmlparser.h" static void dump_handshake_info(struct lws_tokens *lwst) { - int n; + int n; static const char *token_names[WSI_TOKEN_COUNT] = { /*[WSI_TOKEN_GET_URI] =*/ "GET URI", /*[WSI_TOKEN_HOST] =*/ "Host", @@ -50,28 +51,28 @@ static void dump_handshake_info(struct lws_tokens *lwst) /*[WSI_TOKEN_ORIGIN] =*/ "Origin", /*[WSI_TOKEN_DRAFT] =*/ "Draft", /*[WSI_TOKEN_CHALLENGE] =*/ "Challenge", - + /* new for 04 */ /*[WSI_TOKEN_KEY] =*/ "Key", /*[WSI_TOKEN_VERSION] =*/ "Version", /*[WSI_TOKEN_SWORIGIN] =*/ "Sworigin", - + /* new for 05 */ /*[WSI_TOKEN_EXTENSIONS] =*/ "Extensions", - + /* client receives these */ /*[WSI_TOKEN_ACCEPT] =*/ "Accept", /*[WSI_TOKEN_NONCE] =*/ "Nonce", /*[WSI_TOKEN_HTTP] =*/ "Http", /*[WSI_TOKEN_MUXURL] =*/ "MuxURL", - }; - - for (n = 0; n < WSI_TOKEN_COUNT; n++) { - if (lwst[n].token == NULL || lwst[n].token_len == 0) continue; - fprintf(stderr, " %s = ", token_names[n]); - if(fwrite(lwst[n].token, 1, lwst[n].token_len, stderr)) {} - fprintf(stderr, "\n"); - } + }; + + for (n = 0; n < WSI_TOKEN_COUNT; n++) { + if (lwst[n].token == NULL || lwst[n].token_len == 0) continue; + fprintf(stderr, " %s = ", token_names[n]); + if(fwrite(lwst[n].token, 1, lwst[n].token_len, stderr)) {} + fprintf(stderr, "\n"); + } } std::map > msgqueue; @@ -81,29 +82,29 @@ int callback_lws_task(struct libwebsocket_context * context, enum libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { - int n; - struct per_session_data__lws_task *pss = + int n; + struct per_session_data__lws_task *pss = (struct per_session_data__lws_task *)user; - switch (reason) { + switch (reason) { printf("============= Reason %d\n", reason); - case LWS_CALLBACK_ESTABLISHED: + case LWS_CALLBACK_ESTABLISHED: { fprintf(stderr, "callback_lws_task: LWS_CALLBACK_ESTABLISHED\n"); // pss->ringbuffer_tail = ringbuffer_head; pss->wsi = wsi; // send all current tasks -// char buf[512]; + // char buf[512]; std::string init_str; TaskList::iterator it; for(it = tasklist.begin(); it != tasklist.end(); it++) { task_t &t = *it; -// sprintf(buf, "add %d %s %s %d %d;", -// t.id, t.title.c_str(), t.desc.c_str(), t.x, t.y); - -// init_str.append(task_cmd(t)); + printf("add %d %s %s %d;", + t.id, t.title.c_str(), t.desc.c_str(), t.parent_id); + + // init_str.append(task_cmd(t)); init_str += msg_tostring(create_msg(cmd::add, t)); } @@ -123,10 +124,10 @@ int callback_lws_task(struct libwebsocket_context * context, msgqueue.erase(wsi); } - case LWS_CALLBACK_SERVER_WRITEABLE: + case LWS_CALLBACK_SERVER_WRITEABLE: { printf("LWS_CALLBACK_SERVER_WRITEABLE\n"); - + // if(pss->ringbuffer_tail != ringbuffer_head) { if(msgqueue[wsi].size() > 0) { std::string msg = msgqueue[wsi].front(); @@ -141,21 +142,21 @@ int callback_lws_task(struct libwebsocket_context * context, exit(1); } } - + if(msgqueue[wsi].size()) { libwebsocket_rx_flow_control(wsi, 1); libwebsocket_callback_on_writable(context, wsi); } } - break; + break; - case LWS_CALLBACK_BROADCAST: + case LWS_CALLBACK_BROADCAST: printf("LWS_CALLBACK_BROADCAST\n"); - n = libwebsocket_write(wsi, (unsigned char*)in, len, LWS_WRITE_TEXT); - if (n < 0) fprintf(stderr, "task write failed\n"); - break; + n = libwebsocket_write(wsi, (unsigned char*)in, len, LWS_WRITE_TEXT); + if (n < 0) fprintf(stderr, "task write failed\n"); + break; - case LWS_CALLBACK_RECEIVE: + case LWS_CALLBACK_RECEIVE: { printf("LWS_CALLBACK_RECEIVE\n"); @@ -164,37 +165,47 @@ int callback_lws_task(struct libwebsocket_context * context, data.append((char*)in, len); /* - struct a_message &msg = ringbuffer[ringbuffer_head]; - if(msg.payload) { - free(msg.payload); - msg.payload = NULL; - } - -*/ -// char buf[1024]; -// size_t buf_len = 0; - + struct a_message &msg = ringbuffer[ringbuffer_head]; + if(msg.payload) { + free(msg.payload); + msg.payload = NULL; + } + + */ + // char buf[1024]; + // size_t buf_len = 0; + + // print tasklist + TaskList::iterator it_taskbegin; + printf("-->["); + for(it_taskbegin = tasklist.begin(); + it_taskbegin != tasklist.end(); + it_taskbegin++) { + printf(" %d", it_taskbegin->id); + } + printf("]\n"); + std::string buf_str; MsgVector msglist = parse_msg(data); MsgVector::iterator it_msg; for(it_msg = msglist.begin(); it_msg != msglist.end(); it_msg++) { - msg_t m = *it_msg; - switch(m.cmd) { + msg_t m = *it_msg; + switch(m.cmd) { case cmd::add: { printf("Handling add cmd\n"); - -// task_t t = create_task(m.add.title, m.add.desc, -// m.add.x, m.add.y); + + // task_t t = create_task(m.add.title, m.add.desc, + // m.add.x, m.add.y); task_t t = create_task(m.add.title, m.add.desc, m.add.parent_id); - tasklist.push_back(t); -// buf_len = sprintf(buf, "add %d %s %s %d %d;", -// t.id, t.title.c_str(), t.desc.c_str(), -// t.x, t.y); - -// msg_t tm = create_msg(cmd::add, t); -// std::string str = msg_tostring(tm); + tasklist.insert(t); + // buf_len = sprintf(buf, "add %d %s %s %d %d;", + // t.id, t.title.c_str(), t.desc.c_str(), + // t.x, t.y); + + // msg_t tm = create_msg(cmd::add, t); + // std::string str = msg_tostring(tm); buf_str = msg_tostring(create_msg(cmd::add, t)); printf("Adding task: %s\n", buf_str.c_str()); @@ -205,14 +216,15 @@ int callback_lws_task(struct libwebsocket_context * context, printf("Deleting task with id %d\n", m.del.id); // todo: delete all children recursively - task_t del_task; + task_t deleted_task; + // tasklist.erase(m.del.id, &deleted_task); bool id_found = false; TaskList::iterator it; for(it = tasklist.begin(); it != tasklist.end(); it++) { task_t &t = *it; if(t.id == m.del.id) { id_found = true; - del_task = t; + deleted_task = t; tasklist.erase(it); break; } @@ -223,7 +235,7 @@ int callback_lws_task(struct libwebsocket_context * context, } else { // buf_len = sprintf(buf, "del %d;", m.del.id); - buf_str = msg_tostring(create_msg(cmd::del, del_task)); + buf_str = msg_tostring(create_msg(cmd::del, deleted_task)); printf("Deleting task: %s\n", buf_str.c_str()); } break; @@ -235,18 +247,19 @@ int callback_lws_task(struct libwebsocket_context * context, bool id_found = false; TaskList::iterator it; - -// int x = m.move.x / 300 * 300; - + + // int x = m.move.x / 300 * 300; + task_t moved_task; for(it = tasklist.begin(); it != tasklist.end(); it++) { task_t &t = *it; if(t.id == m.move.id) { id_found = true; -// t.x = x; -// t.y = m.move.y; + // t.x = x; + // t.y = m.move.y; t.parent_id = m.move.parent_id; - moved_task = t; + moved_task = t; + tasklist.move(t); break; } } @@ -255,7 +268,7 @@ int callback_lws_task(struct libwebsocket_context * context, printf("\t!!!Could not locate task with id %d\n", m.move.id); } -// buf_len = sprintf(buf, "move %d %d %d;", m.move.id, x, m.move.y); + // buf_len = sprintf(buf, "move %d %d %d;", m.move.id, x, m.move.y); buf_str = msg_tostring(create_msg(cmd::move, moved_task)); printf("Moving task: %s\n", buf_str.c_str()); break; @@ -263,85 +276,104 @@ int callback_lws_task(struct libwebsocket_context * context, case cmd::update: { printf("Updating %d\n", m.update.id); - bool id_found = false; - TaskList::iterator it; + bool id_found = false; + TaskList::iterator it; - task_t updated_task; + task_t updated_task; for(it = tasklist.begin(); it != tasklist.end(); it++) { task_t &t = *it; - if(t.id == m.update.id) { - id_found = true; - t.title = m.update.title; + if(t.id == m.update.id) { + id_found = true; + t.title = m.update.title; t.desc = m.update.desc; - updated_task = t; - break; - } - } + updated_task = t; + break; + } + } - if(!id_found) { + if(!id_found) { printf("\t!!!Could not locate task with id %d\n", m.update.id); - } + } + + buf_str = msg_tostring(create_msg(cmd::update, updated_task)); + printf("Updating task: %s\n", buf_str.c_str()); - buf_str = msg_tostring(create_msg(cmd::update, updated_task)); - printf("Updating task: %s\n", buf_str.c_str()); - break; - } + } default: - printf("Wrong command :(\n"); - break; - } - -// msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING); -// msg.len = len; -// memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, in, len); -// if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; -// else ringbuffer_head++; -/* - msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + buf_len - + LWS_SEND_BUFFER_POST_PADDING); - msg.len = buf_len; - memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, - buf, buf_len); - if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; - else ringbuffer_head++; -*/ - std::string msg; - msg.append((size_t)LWS_SEND_BUFFER_PRE_PADDING, ' '); -// msg.append(buf, buf_len); - msg.append(buf_str); - msg.append((size_t)LWS_SEND_BUFFER_POST_PADDING, ' '); + printf("Wrong command :(\n"); + break; + } - std::map >::iterator it = msgqueue.begin(); - while(it != msgqueue.end()) { - printf("!!\n"); - it->second.push(msg); - it++; + if(!save_tasklist_to_file(tasklist, "/tmp/muniad.db")) { + printf("Could not flush db to file\n"); + } + else { + // XmlParser xml("/tmp/muniad.db"); + // xml.parse(); + // tasklist = xml.tasklist; + } + + // print tasklist + TaskList::iterator it_taskend; + printf("<--["); + for(it_taskend = tasklist.begin(); + it_taskend != tasklist.end(); + it_taskend++) { + printf(" %d", it_taskend->id); } - /* - if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10)) - libwebsocket_rx_flow_control(wsi, 0); - */ - libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi)); - //libwebsocket_rx_flow_control(wsi, 0); - } + printf("]\n"); + + // msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING); + // msg.len = len; + // memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, in, len); + // if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; + // else ringbuffer_head++; + /* + msg.payload = malloc(LWS_SEND_BUFFER_PRE_PADDING + buf_len + + LWS_SEND_BUFFER_POST_PADDING); + msg.len = buf_len; + memcpy((char *)msg.payload + LWS_SEND_BUFFER_PRE_PADDING, + buf, buf_len); + if(ringbuffer_head == (MAX_MESSAGE_QUEUE - 1)) ringbuffer_head = 0; + else ringbuffer_head++; + */ + std::string msg; + msg.append((size_t)LWS_SEND_BUFFER_PRE_PADDING, ' '); + // msg.append(buf, buf_len); + msg.append(buf_str); + msg.append((size_t)LWS_SEND_BUFFER_POST_PADDING, ' '); + + std::map >::iterator it = msgqueue.begin(); + while(it != msgqueue.end()) { + printf("!!\n"); + it->second.push(msg); + it++; + } + /* + if(((ringbuffer_head - pss->ringbuffer_tail) % MAX_MESSAGE_QUEUE) > (MAX_MESSAGE_QUEUE - 10)) + libwebsocket_rx_flow_control(wsi, 0); + */ + libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi)); + //libwebsocket_rx_flow_control(wsi, 0); } - break; - /* - * this just demonstrates how to use the protocol filter. If you won't - * study and reject connections based on header content, you don't need - * to handle this callback - */ - - case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: + } + break; + /* + * this just demonstrates how to use the protocol filter. If you won't + * study and reject connections based on header content, you don't need + * to handle this callback + */ + + case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: printf("LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION\n"); - dump_handshake_info((struct lws_tokens *)(long)user); - /* you could return non-zero here and kill the connection */ - break; + dump_handshake_info((struct lws_tokens *)(long)user); + /* you could return non-zero here and kill the connection */ + break; - default: - break; - } + default: + break; + } - return 0; + return 0; } -- cgit v1.2.3