#include "pytextserializer.h" DictObject* PyTextSerializer::load(string filename) { // XXX need to check for exceptions in file handling. ifstream in; in.open(filename.c_str()); string PyDict; char ch; while (in.get(ch)) PyDict += ch; // XXX this needs to be more efficient. in.close(); return parsePyDict(PyDict); } string PyTextSerializer::format(DictObject *da, string indent) { string fmt; if (da->isScalar()) { fmt = da->getValue(); } else { map &dict = da->getDict(); map::iterator it = dict.begin(); fmt = "{\n"; while (it != dict.end()) { string fmtValue = format(it->second, indent + "\t"); string key = it->first; fmt += "\t" + indent + "\'" + key + "\' : " + fmtValue + ",\n"; ++it; } fmt += indent + "}"; return fmt; } } void PyTextSerializer::write(DictObject *da, string filename) { ofstream out; // XXX need to check for file exceptions. out.open(filename.c_str()); string PyDict = format(da); out << PyDict; out.close(); } // removes whitespace off the left side of a string. string ltrim(string s) { string ns; // new string char c; bool in_word = false; for (int i = 0; i < s.length(); i++) { c = s[i]; if (isspace(c) && !in_word) continue; else in_word = true; ns += c; } return ns; } // removes whitespace off the right side of a string. string rtrim(string s) { string ns; char c; bool in_word = false; for (int i = s.length()-1; i >= 0; i--) { c = s[i]; if (isspace(c) && !in_word) continue; else in_word = true; ns = c + ns; } return ns; } // removes whitespace off both sides of a string. string trim(string s) { string ns = rtrim(ltrim(s)); return ns; } // turns a python formatted string into a C++ string. string extractPyString(string s) { s = trim(s); if (s[0] == '\'' || s[0] == '"') return s.substr(1, s.length()-2); return s; } // abstracts the extraction of a // python value of any time from a given string. // currently just trims whitespace but maybe // one day it will do more (i.e. type conversion). DictObject* extractPyValue(string s) { s = trim(s); if (s[0] == '{') return parsePyDict(s); return new DictObject(s); } // returns the python formatted dictionary // in a given string. string extractPyDict(string s) { char c; int nbracket = 0; bool start = true; string dict; for(int i = 0; i < s.length(); i++) { c = s[i]; if (c == '\n') continue; if (c == '{') { nbracket++; if (start) { start = false; continue; } } else if (c == '}') { nbracket--; if (nbracket == 0) continue; } if (nbracket == 0 && !start) break; dict += c; } return dict; } DictObject* parsePyDict(string s) { string dict = extractPyDict(s); bool in_key = true; bool in_val = false; DictObject *hashtbl = new DictObject(DictObject::Dict); char c; string key, value; bool in_word = false; int ndict = 0; int nlist = 0; for (int i = 0; i < dict.length(); i++) { c = dict[i]; if (c == ':' && ndict == 0) { in_key = false; in_val = true; continue; } if (c == '[') nlist++; if (c == ']') nlist--; if (c == '{') ndict++; if (c == '}') ndict--; if (c == '\'' || c == '"') in_word = in_word == true ? false : true; if (c == ',' && !in_word && nlist == 0 && ndict == 0) { in_key = true; in_val = false; (*hashtbl).setValue(extractPyString(key), extractPyValue(value)); key = ""; value = ""; continue; } if (in_key) key += c; if (in_val) value += c; } if (key != "") (*hashtbl).setValue(extractPyString(key), extractPyValue(value)); return hashtbl; } // Unit Test #ifdef UNITTEST int main(int argc, char* argv[]) { if (argc == 2) { cout << "Processing: "<< argv[1] << endl; PyTextSerializer pos; DictObject *root = pos.load(argv[1]); pos.write(root, "out.txt"); } else { cout << "Usage: unittest filename" << endl; } return 0; } #endif