Page MenuHomePhabricator (Chris)

No OneTemporary

Authored By
Unknown
Size
31 KB
Referenced Files
None
Subscribers
None
diff --git a/src/ITreeSerializer.h b/src/ITreeSerializer.h
index 517bd35..09fd24e 100644
--- a/src/ITreeSerializer.h
+++ b/src/ITreeSerializer.h
@@ -1,77 +1,81 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ITREESERIALIZER_H
#define ITREESERIALIZER_H
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include "ITreeStorage.h"
+//An abstract class which is used to read/write data from TreeStorage to various file formats.
+//Currently only one file format is implemented, i.e. POASerializer. (Theoretically you can write a XMLSerializer.)
class ITreeSerializer{
public:
//Method used to read a node from an inputstream.
//fin: The inputstream to read from.
//objOut: The TreeStorageNode in which the result will come.
//loadSubNodeOnly: Boolean if only the subNodes should be loaded.
//Returns: False if there's an error while reading the node.
virtual bool readNode(std::istream& fin,ITreeStorageBuilder* objOut,bool loadSubNodeOnly=false)=0;
+
//Method used to write to an outputstream.
//obj: Pointer to the TreeStorageNode containing the data.
//fout: The output stream to write to.
- //writeHeader: TODO: ???
+ //writeHeader: Write the header to the file (e.g. XML file; not that POA file doesn't have a header).
//saveSubNodeOnly: Boolean if only the subNodes should be saved.
virtual void writeNode(ITreeStorageReader* obj,std::ostream& fout,bool writeHeader=true,bool saveSubNodeOnly=false)=0;
public:
//Method used to load a node from a file.
//fileName: The file to load from.
//objOut: The object to place the result in.
//loadSubNodeOnly: Boolean if only the subNodes should be loaded.
//Returns: False if there's an error while reading the node.
bool loadNodeFromFile(const char* fileName,ITreeStorageBuilder* objOut,bool loadSubNodeOnly=false){
//Open an inputstream.
std::ifstream f(fileName);
//If it failed then we return.
if(!f)
return false;
//It didn't fail so let the readNode method handle the rest.
return readNode(f,objOut,loadSubNodeOnly);
}
+
//Method used to write a node to a file.
//fileName: The file to save to.
//obj: Pointer to the TreeStorageNode containing the data.
- //writeHeader: TODO: ???
+ //writeHeader: Write the header to the file (e.g. XML file; not that POA file doesn't have a header).
//saveSubNodeOnly: Boolean if only the subNodes should be saved.
bool saveNodeToFile(const char* fileName,ITreeStorageReader* obj,bool writeHeader=true,bool saveSubNodeOnly=false){
//Open an outputstream.
std::ofstream f(fileName);
//If it failed then we return.
if(!f)
return false;
//It didn't fail so let the writeNode method handle the rest.
writeNode(obj,f,writeHeader,saveSubNodeOnly);
return true;
}
};
#endif
diff --git a/src/ITreeStorage.h b/src/ITreeStorage.h
index aa115b8..f6c7ff1 100644
--- a/src/ITreeStorage.h
+++ b/src/ITreeStorage.h
@@ -1,71 +1,86 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ITREESTORAGE_H
#define ITREESTORAGE_H
#include <string>
#include <vector>
+//An abstract class which is used to transfer the data from file to TreeStorage.
+//NOTE: Usually you should simply use the TreeStorageNode class.
+//You only need to use this class when you want to store the data in a customized way.
+//Another use case is you only want to read some of the property in the file, by using early exit feature.
class ITreeStorageBuilder{
public:
//Destructor.
virtual ~ITreeStorageBuilder(){}
//Set the name of the TreeStorageNode.
//name: The name to give.
- virtual void setName(std::string& name)=0;
+ //return value: true means early exit, i.e. doesn't read the file further.
+ virtual bool setName(std::string& name)=0;
+
//Set the value of the TreeStorageNode.
//value: The value to give.
- virtual void setValue(std::vector<std::string>& value)=0;
+ //return value: true means early exit, i.e. doesn't read the file further.
+ virtual bool setValue(std::vector<std::string>& value) = 0;
//Method that should create a new node in the TreeStorageNode and add it to it's subnodes.
- //Returns a pointer to the new TreeStorageNode.
+ //Returns a pointer to the new TreeStorageNode. NULL means early exit, i.e. doesn't read the file further.
virtual ITreeStorageBuilder* newNode()=0;
+
//Method that should add a new attribute to the TreeStorageNode.
//name: The name of the new attribute.
//value: The value(s) of the new attribute.
- virtual void newAttribute(std::string& name,std::vector<std::string>& value)=0;
-
+ //return value: true means early exit, i.e. doesn't read the file further.
+ virtual bool newAttribute(std::string& name, std::vector<std::string>& value) = 0;
};
+//An abstract class which is used to transfer the data from TreeStorage to file.
+//NOTE: Usually you should simply use the TreeStorageNode class.
+//You only need to use this class when you want to store the data in a customized way.
class ITreeStorageReader{
public:
//Destructor.
virtual ~ITreeStorageReader(){}
//Sets the parameter name to the name of the TreeStorageNode.
//name: The string to fill with the name;
virtual void getName(std::string& name)=0;
+
//Sets the parameter value to the value(s) of the TreeStorageNode.
//value: The vector to fill with the value(s);
virtual void getValue(std::vector<std::string>& value)=0;
//Method used for iterating through the attributes of the TreeStorageNode.
- //pUserData: Pointer TODO???
+ //pUserData: A user pointer, usually stores information about the iterator itself. NULL means get the first attribute.
//name: The string fill with the name of the attribute.
//value: Vector to fill with the value(s) of the attribute.
+ //return value: The new value of the user pointer. NULL means there are no more attributes.
virtual void* getNextAttribute(void* pUserData,std::string& name,std::vector<std::string>& value)=0;
+
//Method used for iterating through the subnodes of the TreeStorageNode.
- //pUserData: Pointer TODO???
+ //pUserData: A user pointer, usually stores information about the iterator itself. NULL means get the first node.
//obj: Pointer that will be pointed to the nextNode, if present.
+ //return value: The new value of the user pointer. NULL means there are no more nodes.
virtual void* getNextNode(void* pUserData,ITreeStorageReader*& obj)=0;
-
};
+
#endif
diff --git a/src/POASerializer.cpp b/src/POASerializer.cpp
index f7097d4..0f19f34 100644
--- a/src/POASerializer.cpp
+++ b/src/POASerializer.cpp
@@ -1,485 +1,504 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#include "POASerializer.h"
#include <sstream>
using namespace std;
static void readString(std::istream& fin,std::string& string){
//This method is used for reading a string from an input stream.
//fin: The input stream to read from.
//string: String to place the result in.
//The current character.
int c;
c=fin.get();
//Check if there's a '"'.
if(c=='\"'){
//There's a '"' so place every character we encounter in the string without parsing.
while((!fin.eof()) & (!fin.fail())){
//First we get the next character to prevent putting the '"' in the string.
c=fin.get();
//Check if there's a '"' since that could mean the end of the string.
if(c=='\"'){
//Get the next character and check if that's also an '"'.
c=fin.get();
if(c!='\"'){
//We have two '"' after each other meaning an escaped '"'.
//We unget one so there will be one '"' placed in the string.
fin.unget();
return;
}
}
//Every other character can be put in the string.
string.push_back(c);
}
}else{
//There are no quotes around the string so we need to be carefull detecting if the string has ended.
do{
switch(c){
//Check for characters that mean the end of the string.
case EOF:
case ' ':
case '\r':
case '\n':
case '\t':
return;
//Check for characters that are part of the POA file format.
//If so we first unget one character to prevent problems parsing the rest of the file.
case ',':
case '=':
case '(':
case ')':
case '{':
case '}':
case '#':
fin.unget();
return;
default:
//In any other case the character is normal so we put it in the string.
string.push_back(c);
}
//Get the next character.
c=fin.get();
}while((!fin.eof()) & (!fin.fail()));
}
}
static void skipWhitespaces(std::istream& fin){
//This function will read from the input stream until there's something else than whitespaces.
//fin: The input stream to read from.
//The current character.
int c;
while((!fin.eof()) & (!fin.fail())){
//Get the character.
c=fin.get();
//Check if it's one of the whitespace characters.
switch(c){
case EOF:
case ' ':
case '\r':
case '\n':
case '\t':
break;
default:
//Anything other means that the whitespaces have ended.
//Unget the last character and return.
fin.unget();
return;
}
}
}
static void skipComment(std::istream& fin){
//This function will read from the input stream until the end of a line (also end of the comment).
//fin: The input stream to read from.
//The current character.
int c;
while((!fin.eof()) & (!fin.fail())){
//Get the character.
c=fin.get();
//Check if it's a new line (end of comment).
if(c=='\r'||c=='\n'){
fin.unget();
break;
}
}
}
bool POASerializer::readNode(std::istream& fin,ITreeStorageBuilder* objOut,bool loadSubNodeOnly){
//The current character.
int c;
//The current mode of reading.
- //0=read name
- //1=read attribute value
- //2=read subnode value
- //16=add attribute
- //17=add subnode
- int mode;
+ enum ReadMode {
+ ReadName = 0,
+ ReadAttributeValue = 1,
+ ReadSubnodeValue = 2,
+ AddFirst = 16,
+ AddAttribute = 16,
+ AddSubnode = 17,
+ } mode = ReadName;
//Before reading make sure that the input stream isn't null.
if(!fin) return false;
//Vector containing the stack of TreeStorageNodes.
vector<ITreeStorageBuilder*> stack;
//A vector for the names and a vector for the values.
vector<string> names,values;
//Check if we only need to load subNodes.
//If so then put the objOut as the first TreeStorageNode.
if(loadSubNodeOnly) stack.push_back(objOut);
//Loop through the files.
while((!fin.eof()) && (!fin.fail())){
//Get a character.
c=fin.get();
//Check what it is and what to do with that character.
switch(c){
case EOF:
case ' ':
case '\r':
case '\n':
case '\t':
//We skip whitespaces.
break;
case '#':
//A comment so skip it.
skipComment(fin);
break;
case '}':
//A closing bracket so do one step back in the stack.
//There must be a TreeStorageNode left if not return false.
if(stack.empty()) return false;
//Remove the last entry of the stack.
stack.pop_back();
//Check if the stack is empty, if so than the reading of the node is done.
if(stack.empty()) return true;
objOut=stack.back();
break;
default:
//It isn't a special character but part of a name/value, so unget it.
fin.unget();
{
//Clear the names and values vectors, start reading new names/values.
names.clear();
values.clear();
//Set the mode to the read name mode.
- mode=0;
+ mode=ReadName;
//Keep reading characters, until we break out the while loop or there's an error.
while((!fin.eof()) & (!fin.fail())){
//The string containing the name.
string s;
//First skip the whiteSpaces.
skipWhitespaces(fin);
//Now get the string.
readString(fin,s);
//Check the mode.
switch(mode){
- case 0:
+ case ReadName:
//Mode is 0(read names) so put the string in the names vector.
names.push_back(s);
break;
- case 1:
- case 2:
+ case ReadAttributeValue:
+ case ReadSubnodeValue:
//Mode is 1 or 2 so put the string in the values vector.
values.push_back(s);
break;
}
//Again skip whitespaces.
skipWhitespaces(fin);
//Now read the next character.
c=fin.get();
switch(c){
case ',':
//A comma means one more name or value.
break;
case '=':
//An '=' can only occur after a name (mode=0).
- if(mode==0){
+ if(mode==ReadName){
//The next string will be a value so set mode to 1.
- mode=1;
+ mode=ReadAttributeValue;
}else{
//In any other case there's something wrong so return false.
return false;
}
break;
case '(':
//An '(' can only occur after a name (mode=0).
- if(mode==0){
+ if(mode==ReadName){
//The next string will be a value of a block so set mode to 2.
- mode=2;
+ mode=ReadSubnodeValue;
}else{
//In any other case there's something wrong so return false.
return false;
}
break;
case ')':
//A ')' can only occur after an attribute (mode=2).
- if(mode==2){
+ if(mode==ReadSubnodeValue){
//The next will be a new subNode so set mode to 17.
- mode=17;
+ mode=AddSubnode;
}else{
//In any other case there's something wrong so return false.
return false;
}
break;
case '{':
//A '{' can only mean a new subNode (mode=17).
fin.unget();
- mode=17;
+ mode=AddSubnode;
break;
default:
//The character is not special so unget it.
fin.unget();
- mode=16;
+ mode=AddAttribute;
break;
}
//We only need to break out if the mode is 16(add attribute) or 17(add subnode)
- if(mode>=16) break;
+ if(mode>=AddFirst) break;
}
//Check the mode.
switch(mode){
- case 16:
+ case AddAttribute:
//The mode is 16 so we need to change the names and values into attributes.
//The stack mustn't be empty.
if(stack.empty()) return false;
//Make sure that the result TreeStorageNode isn't null.
if(objOut!=NULL){
//Check if the names vector is empty, if so add an empty name.
if(names.empty()) names.push_back("");
//Put an empty value for every valueless name.
while(values.size()<names.size()) values.push_back("");
//Now loop through the names.
for(unsigned int i=0;i<names.size()-1;i++){
//Temp vector that will contain the values.
vector<string> v;
v.push_back(values[i]);
//And add the attribute.
- objOut->newAttribute(names[i],v);
+ if (objOut->newAttribute(names[i], v)) {
+ //Early exit.
+ return true;
+ }
}
if(names.size()>1) values.erase(values.begin(),values.begin()+(names.size()-1));
- objOut->newAttribute(names.back(),values);
+ if (objOut->newAttribute(names.back(), values)) {
+ //Early exit.
+ return true;
+ }
}
break;
- case 17:
+ case AddSubnode:
//The mode is 17 so we need to add a subNode.
{
//Check if the names vector is empty, if so add an empty name.
if(names.empty()) names.push_back("");
else if(names.size()>1){
if(stack.empty()) return false;
while(values.size()<names.size()) values.push_back("");
for(unsigned int i=0;i<names.size()-1;i++){
vector<string> v;
v.push_back(values[i]);
- objOut->newAttribute(names[i],v);
+ if (objOut->newAttribute(names[i], v)) {
+ //Early exit.
+ return true;
+ }
}
values.erase(values.begin(),values.begin()+(names.size()-1));
}
//Create a new subNode.
ITreeStorageBuilder* objNew=NULL;
//If the stack is empty the new subNode will be the result TreeStorageNode.
if(stack.empty()) objNew=objOut;
//If not the new subNode will be a subNode of the result TreeStorageNode.
- else if(objOut!=NULL) objNew=objOut->newNode();
+ else if (objOut != NULL) {
+ objNew = objOut->newNode();
+ if (objNew == NULL) {
+ //Early exit.
+ return true;
+ }
+ }
//Add it to the stack.
stack.push_back(objNew);
if(objNew!=NULL){
//Add the name and the values.
- objNew->setName(names.back());
- objNew->setValue(values);
+ if (objNew->setName(names.back()) || objNew->setValue(values)) {
+ //Early exit.
+ return true;
+ }
}
objOut=objNew;
//Skip the whitespaces.
skipWhitespaces(fin);
//And get the next character.
c=fin.get();
if(c!='{'){
//The character isn't a '{' meaning the block hasn't got a body.
fin.unget();
stack.pop_back();
//Check if perhaps we're done, stack=empty.
if(stack.empty()) return true;
objOut=stack.back();
}
}
break;
default:
//The mode isn't 16 or 17 but still broke out the while loop.
//Something's wrong so return false.
return false;
}
}
break;
}
}
return true;
}
static void writeString(std::ostream& fout,std::string& s){
//This method will write a string.
//fout: The output stream to write to.
//s: The string to write.
//new: check if the string is empty
if(s.empty()){
//because of the new changes of loader, we should output 2 quotes '""'
fout<<"\"\"";
}else
//Check if the string contains any special character that needs escaping.
if(s.find_first_of(" \r\n\t,=(){}#\"")!=string::npos){
//It does so we put '"' around them.
fout<<'\"';
//The current character.
int c;
//Loop through the characters.
for(unsigned int i=0;i<s.size();i++){
c=s[i];
//If there's a '"' character it needs to be counter escaped. ("")
if(c=='\"'){
fout<<"\"\"";
}else{
//If it isn't we can just write away the character.
fout<<(char)c;
}
}
fout<<'\"';
}else{
//It doesn't contain any special characters so we can write it away.
fout<<s;
}
}
static void writeStringArray(std::ostream& fout,std::vector<std::string>& s){
//This method will write a away an array of strings.
//fout: The output stream to write to.
//s: Vector containing the strings to write.
//Loop the strings.
for(unsigned int i=0;i<s.size();i++){
//If it's the second or more there must be a ",".
if(i>0) fout<<',';
//Now write the string.
writeString(fout,s[i]);
}
}
static void pWriteNode(ITreeStorageReader* obj,std::ostream& fout,int indent,bool saveSubNodeOnly){
//Write the TreeStorageNode to the given output stream.
//obj: The TreeStorageNode to write away.
//fout: The output stream to write to.
//indent: Integer containing the number of indentations are needed.
//saveSubNodeOnly: Boolean if only the subNodes need to be saved.
//Boolean if the node has subNodes.
bool haveSubNodes=false;
void* lpUserData=NULL;
ITreeStorageReader* objSubNode=NULL;
string s;
vector<string> v;
//---
if(obj==NULL) return;
//---
if(!saveSubNodeOnly){
for(int i=0;i<indent;i++) fout<<'\t';
s.clear();
obj->getName(s);
writeString(fout,s);
fout<<'(';
v.clear();
obj->getValue(v);
writeStringArray(fout,v);
fout<<')';
indent++;
}
//attributes
lpUserData=NULL;
for(;;){
s.clear();
v.clear();
lpUserData=obj->getNextAttribute(lpUserData,s,v);
if(lpUserData==NULL) break;
if(!haveSubNodes && !saveSubNodeOnly) fout<<"{\n";
haveSubNodes=true;
for(int i=0;i<indent;i++) fout<<'\t';
writeString(fout,s);
fout<<'=';
writeStringArray(fout,v);
fout<<'\n';
}
//subnodes
lpUserData=NULL;
for(;;){
lpUserData=obj->getNextNode(lpUserData,objSubNode);
if(lpUserData==NULL) break;
if(objSubNode!=NULL){
if(!haveSubNodes && !saveSubNodeOnly) fout<<"{\n";
haveSubNodes=true;
pWriteNode(objSubNode,fout,indent,false);
}
}
//---
if(!saveSubNodeOnly){
indent--;
if(haveSubNodes){
for(int i=0;i<indent;i++) fout<<'\t';
fout<<'}';
}
fout<<'\n';
}
}
void POASerializer::writeNode(ITreeStorageReader* obj,std::ostream& fout,bool writeHeader,bool saveSubNodeOnly){
//Make sure that the output stream isn't null.
if(!fout) return;
//It isn't so start writing the node.
pWriteNode(obj,fout,0,saveSubNodeOnly);
}
diff --git a/src/TreeStorageNode.cpp b/src/TreeStorageNode.cpp
index 1a06d10..e220978 100644
--- a/src/TreeStorageNode.cpp
+++ b/src/TreeStorageNode.cpp
@@ -1,156 +1,159 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WIN32
#include <stdint.h>
#include <unistd.h>
#endif
#include "TreeStorageNode.h"
#include "MD5.h"
#include <string.h>
using namespace std;
TreeStorageNode::~TreeStorageNode(){
//The deconstructor will just calls destroy().
destroy();
}
void TreeStorageNode::destroy(){
//Loop through the subnodes and delete them.
for(unsigned int i=0;i<subNodes.size();i++){
delete subNodes[i];
}
//Now clear some stuff.
name.clear();
value.clear();
attributes.clear();
subNodes.clear();
}
-void TreeStorageNode::setName(std::string& name){
+bool TreeStorageNode::setName(std::string& name){
this->name=name;
+ return false;
}
void TreeStorageNode::getName(std::string& name){
name=this->name;
}
-void TreeStorageNode::setValue(std::vector<std::string>& value){
+bool TreeStorageNode::setValue(std::vector<std::string>& value){
this->value=value;
+ return false;
}
void TreeStorageNode::getValue(std::vector<std::string>& value){
value=this->value;
}
ITreeStorageBuilder* TreeStorageNode::newNode(){
TreeStorageNode* obj=new TreeStorageNode;
subNodes.push_back(obj);
return obj;
}
-void TreeStorageNode::newAttribute(std::string& name,std::vector<std::string>& value){
+bool TreeStorageNode::newAttribute(std::string& name,std::vector<std::string>& value){
//Put the attribute in the attributes map.
attributes[name]=value;
+ return false;
}
void* TreeStorageNode::getNextAttribute(void* pUserData,std::string& name,std::vector<std::string>& value){
if(pUserData==NULL) objAttrIterator=attributes.begin();
if(objAttrIterator!=attributes.end()){
name=objAttrIterator->first;
value=objAttrIterator->second;
++objAttrIterator;
return &objAttrIterator;
}else{
return NULL;
}
}
void* TreeStorageNode::getNextNode(void* pUserData,ITreeStorageReader*& obj){
intptr_t i=(intptr_t)pUserData;
//Check if the pointer is in range of the subNodes vector.
if(i<(int)subNodes.size()){
obj=subNodes[i];
return (void*)(i+1);
}else{
return NULL;
}
}
static void md5AppendString(Md5& md5,const string& s){
unsigned int sz=s.size();
unsigned char c[4];
c[0]=sz;
c[1]=sz>>8;
c[2]=sz>>16;
c[3]=sz>>24;
md5.update(c,4);
if(sz>0) md5.update(s.c_str(),sz);
}
static void md5AppendVector(Md5& md5,const vector<string>& v){
unsigned int sz=v.size();
unsigned char c[4];
c[0]=sz;
c[1]=sz>>8;
c[2]=sz>>16;
c[3]=sz>>24;
md5.update(c,4);
for(unsigned int i=0;i<sz;i++){
md5AppendString(md5,v[i]);
}
}
static void md5AppendMap(Md5& md5,const map<string,vector<string> >& m){
unsigned int sz=m.size();
unsigned char c[4];
c[0]=sz;
c[1]=sz>>8;
c[2]=sz>>16;
c[3]=sz>>24;
md5.update(c,4);
for(map<string,vector<string> >::const_iterator it=m.begin();it!=m.end();++it){
md5AppendString(md5,it->first);
md5AppendVector(md5,it->second);
}
}
unsigned char* TreeStorageNode::calcMD5(unsigned char* md){
unsigned char digest[16];
Md5 md5;
md5.init();
md5AppendString(md5,name);
md5AppendVector(md5,value);
md5AppendMap(md5,attributes);
for(unsigned int i=0;i<subNodes.size();i++){
TreeStorageNode *node=subNodes[i];
if(node==NULL){
memset(digest,0,16);
}else{
node->calcMD5(digest);
}
md5.update(digest,16);
}
return md5.final(md);
}
diff --git a/src/TreeStorageNode.h b/src/TreeStorageNode.h
index 49b0ccc..ca6a3fc 100644
--- a/src/TreeStorageNode.h
+++ b/src/TreeStorageNode.h
@@ -1,93 +1,93 @@
/*
* Copyright (C) 2011-2012 Me and My Shadow
*
* This file is part of Me and My Shadow.
*
* Me and My Shadow is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Me and My Shadow is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Me and My Shadow. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TREESTORAGENODE_H
#define TREESTORAGENODE_H
#include "ITreeStorage.h"
#include <map>
#include <vector>
#include <string>
//This class is used to store data in a tree-structured way.
//Every (TreeStorage)Node has a vector with subNodes and every Node contains a hashmap with attributes.
class TreeStorageNode:public ITreeStorageBuilder,public ITreeStorageReader{
private:
//Iterator used to iterate the hashmap with attributes.
//Used by the methods getNextAttribute and getNextNode.
std::map<std::string,std::vector<std::string> >::iterator objAttrIterator;
public:
//Vector containing the subnodes of the TreeStorageNode.
std::vector<TreeStorageNode*> subNodes;
//String containing the name of the TreeStorageNode.
std::string name;
//Vector containing the value(s) of the TreeStorageNode.
std::vector<std::string> value;
//Hashmap containing the attributes of the TreeStorageNode.
std::map<std::string,std::vector<std::string> > attributes;
//Constructor.
TreeStorageNode(){}
//Destructor.
virtual ~TreeStorageNode();
//This method is used to destroy the TreeStorageNode.
//Also called when the deconstructor is called.
void destroy();
//Set the name of the TreeStorageNode.
//name: The name to give.
- virtual void setName(std::string& name);
+ virtual bool setName(std::string& name);
//Sets the parameter name to the name of the TreeStorageNode.
//name: The string to fill with the name;
virtual void getName(std::string& name);
//Set the value of the TreeStorageNode.
//value: The value to give.
- virtual void setValue(std::vector<std::string>& value);
+ virtual bool setValue(std::vector<std::string>& value);
//Sets the parameter value to the value of the TreeStorageNode.
//value: The string to fill with the name;
virtual void getValue(std::vector<std::string>& value);
//Creates a new node in the TreeStorageNode.
//The new node will be added to the subnodes.
//Returns: a pointer to the new node.
virtual ITreeStorageBuilder* newNode();
//Creates a new attribute in the TreeStorageNode.
//The attribute will be added to the attributes map.
//name: The name for the new attribute.
//value: The value for the new attribute.
- virtual void newAttribute(std::string& name,std::vector<std::string>& value);
+ virtual bool newAttribute(std::string& name,std::vector<std::string>& value);
//Method used for iterating through the attributes of the TreeStorageNode.
- //pUserData: Pointer TODO???
+ //pUserData: Pointer to the iterator.
//name: The string fill with the name of the attribute.
//value: Vector to fill with the value(s) of the attribute.
virtual void* getNextAttribute(void* pUserData,std::string& name,std::vector<std::string>& value);
//Method used for iterating through the subnodes of the TreeStorageNode.
- //pUserData: Pointer TODO???
+ //pUserData: Pointer to the iterator.
//obj: Pointer that will be pointed to the nextNode, if present.
virtual void* getNextNode(void* pUserData,ITreeStorageReader*& obj);
//Calculate the MD5 of node based on the data structure.
//places the message digest in md,
//which must have space for 16 bytes of output (or NULL).
unsigned char* calcMD5(unsigned char* md);
};
#endif

File Metadata

Mime Type
text/x-diff
Expires
Sat, May 16, 8:29 PM (1 d, 17 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
63813
Default Alt Text
(31 KB)

Event Timeline