/*************************************************************************
* UrBackup - Client/Server backup system
* Copyright (C) 2011-2016 Martin Raiber
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
**************************************************************************/
#include "TreeReader.h"
#include
#include
#include
#include
#include "../../stringtools.h"
#include "../../urbackupcommon/os_functions.h"
#include "../../Interface/Server.h"
#include
const size_t buffer_size=4096;
bool TreeReader::readTree(const std::string &fn)
{
std::fstream in;
in.open(fn.c_str(), std::ios::in | std::ios::binary );
if (!in.is_open())
{
Log("Cannot read file tree from file \"" + fn + "\"");
return false;
}
size_t read;
char buffer[buffer_size];
int state=0;
size_t lines=0;
size_t stringbuffer_size=0;
std::string name;
char ltype=0;
do
{
in.read(buffer, buffer_size);
read=(size_t)in.gcount();
for(size_t i=0;i0);
in.clear();
name.clear();
in.seekg(0, std::ios::beg);
size_t stringbuffer_pos=0;
stringbuffer.resize(stringbuffer_size+5);
state=0;
bool isdir=false;
std::string data;
std::stack parents;
std::stack lastNodes;
bool firstChild=true;
size_t idx=1;
nodes.resize(lines+1);
std::string root_str = "root";
memcpy(&stringbuffer[0], root_str.c_str(), root_str.size()+1);
stringbuffer_pos+=root_str.size()+1;
nodes[0].setName(&stringbuffer[0]);
parents.push(&nodes[0]);
lastNodes.push(&nodes[0]);
lines=0;
do
{
in.read(buffer, buffer_size);
read=(size_t)in.gcount();
for(size_t i=0;isetNextSibling(&nodes[idx]);
lastNodes.pop();
lastNodes.push(&nodes[idx]);
}
if(!parents.empty())
{
parents.top()->incrementNumChildren();
nodes[idx].setParent(parents.top());
}
if(ch=='d')
{
parents.push(&nodes[idx]);
firstChild=true;
}
++idx;
}
else
{
if(!parents.empty())
{
parents.pop();
}
else
{
Log("TreeReader: parents empty");
return false;
}
if(!firstChild)
{
if(lastNodes.empty())
{
Log("TreeReader: lastNodes empty");
return false;
}
lastNodes.top()->setNextSibling(NULL);
lastNodes.pop();
}
firstChild=false;
}
name.clear();
data.clear();
state=0;
++lines;
}
}
}
}
while(read==buffer_size);
assert(idx == nodes.size());
assert(stringbuffer_pos == stringbuffer.size());
nodes[0].setNextSibling(NULL);
return true;
}
void TreeReader::Log(const std::string &str)
{
Server->Log(str, LL_ERROR);
}
std::vector * TreeReader::getNodes(void)
{
return &nodes;
}