finished untested ModInfo, unfinished ModList

master
Phitherek 2013-04-06 00:10:05 +02:00
parent 8e728d5544
commit 2398d783fc
10 changed files with 532 additions and 10 deletions

15
3m.h
View File

@ -10,6 +10,8 @@
#include "ModListList.h"
#include "RepositoryModDescription.h"
#include "LocalModList.h"
#include "RepositoryModDescription.h"
#include "NetSocket++/NetSocketPP.h"
/// \file 3m.h
/// \brief A common header for 3m and definitions of helper functions.
/// \author Phitherek_
@ -34,5 +36,18 @@ std::string strip_endl(std::string s) {
}
return s;
}
/// \fn std::string strgetline(std::string *str)
/// \brief A function that gets line from the multiline string and erases it from this string.
/// \param[in,out] str A pointer to the string to get line from. The line is erased from the string.
/// \return Line from the string.
std::string strgetline(std::string *str) {
std::string line = "";
int i;
for(i = 0; (*str)[i] != '\n'; i++) {
line += (*str)[i];
}
return line;
}
}
#endif

View File

@ -41,14 +41,28 @@ const char* ParseException::what() const throw() {
return msg.c_str();
}
OutOfBoundsException::OutOfBoundsException(std::string what) {
BadResponseException::BadResponseException(std::string response) {
_response = response;
}
BadResponseException::~BadResponseException() throw() {
_response = "";
}
const char* BadResponseException::what() const throw() {
std::string what = "Got HTTP response: ";
what += _response;
return what.c_str();
}
NonEditableException::NonEditableException(std::string what) {
_what = what;
}
OutOfBoundsException::~OutOfBoundsException() throw() {
NonEditableException::~NonEditableException() throw() {
_what = "";
}
const char* OutOfBoundsException::what() const throw() {
const char* NonEditableException::what() const throw() {
return _what.c_str();
}

View File

@ -41,17 +41,29 @@ public:
const char* what() const throw(); ///< \brief A function, that returns the whole error.
///< \return Whole error message.
};
/// \class OutOfBoundsException
/// \brief An exception to be thrown when the iterator gets out of container bounds.
class OutOfBoundsException: public std::exception {
/// \class BadResponseException
/// \brief An exception to be thrown on not 200 HTTP response.
class BadResponseException: public std::exception {
private:
std::string _what;
std::string _response;
public:
OutOfBoundsException(std::string what); ///< \brief A constructor with parameters.
///< \param what Error message.
OutOfBoundsException(std::string response); ///< \brief A constructor with parameters.
///< \param response HTTP response that caused the exception.
~OutOfBoundsException() throw(); ///< A destructor, as needed by std::exception.
const char* what() const throw(); ///< \brief A function returning error message.
/// \return Error message.
};
/// \class NonEditableException
/// \brief An exception to be thrown when trying to write a remotely obtained, non-editable structure.
class NonEditableException: public std::exception {
private:
std::string _what;
public:
NonEditableException(std::string what); ///< \brief A constructor with parameters.
///< \param what Error message.
~NonEditableException() throw(); ///< A destructor, as needed by std::exception.
const char* what() const throw(); ///< \brief A function returning error message.
/// \return Error message.
};
}
#endif

349
ModInfo.cpp Normal file
View File

@ -0,0 +1,349 @@
#include "ModInfo.h"
#include "NetSocket++/NetSocketPP.h"
#include <fstream>
using namespace mmm;
ModInfo::ModInfo() {
ModInfoDescription emptymid;
_desc = emptymid;
_edit = false;
}
ModInfo::ModInfo(ModInfoDescription mid) {
_desc = mid;
_edit = false;
NetSocketPP::HTTPReply data;
try {
NetSocketPP::HTTPClientSocket conn(_desc.getServer(), "http", _desc.getPath());
std::cout << "Connection to " << conn.getIP() << " successful!" << std::endl;
data = conn.getReply();
} catch (NetSocketPP::SocketException &exc) {
std::cerr << "SocketException occured while getting remote modinfo: " << exc.what() << std::endl;
throw(exc);
} catch (NetSocketPP::NetworkException &exc) {
std::cerr << "NetworkException occured while getting remote modinfo: " << exc.what() << std::endl;
throw(exc);
}
if(data.getResponse() != "200 OK") {
throw BadResponseException(data.getResponse());
}
std::string modinfo = data.getContent();
std::string action = "detect";
for(unsigned int i = 0; i < modinfo.length(); i++) {
std::string line = "";
line = strgetline(&modinfo);
if(line[0] != NULL && line[0] != ' ' && line[0] != '\n' && line[0] != '\r') {
if(action == "detect") {
if(line[0] == '{') {
std::string name = "";
for(unsigned int i = 1; line[i] != '}' && i < line.length(); i++) {
name += line[i];
}
_name = name;
action = "parse";
} else {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although { was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(action == "parse") {
if(line[0] == '{') {
if(line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == '}') {
action = "detect";
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(line[0] == '[') {
std::string tmpact = "";
for(unsigned int i = 1; line[i] != ']' && i < line.length(); i++) {
tmpact += line[i];
}
if(tmpact == "description" || tmpact == "release" || tmpact == "deps" || tmpact == "repotype" || tmpact == "repoaddr") {
action = tmpact;
} else {
std::string msg = "";
msg += "Found ";
msg += tmpact;
msg += " although description/release/deps/repotype/repoaddr was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(action == "description") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_description = line;
action = "parse";
}
} else if(action == "release") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_release = atoi(line.c_str());
action = "parse";
}
} else if(action == "deps") {
if(line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string or [ was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else if(line[0] == '[') {
if(line[1] == 'd' && line[2] == 'e' && line[3] == 'p' && line[4] == 's' && line[5] == 'e' && line[6] == 'n' && line[7] == 'd' && line[8] == ']') {
if(_deps.empty()) {
_deps.push_back("none");
}
action = "parse";
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although string or [depsend] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else {
_deps.push_back(line);
}
} else if(action == "repotype") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_repotype = line;
action = "parse";
}
} else if(action == "repoaddr") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_repoaddr = line;
action = "parse";
}
} else {
throw ParseException(_desc.getServer() + _desc.getPath(), "The program should not reach this place!");
}
}
}
}
ModInfo::ModInfo(std::string path) {
_edit = true;
ModInfoDescription emptymid;
_desc = emptymid;
_localPath = path;
std::ifstream modinfo(_localPath.c_str());
if(!modinfo) {
throw FileException(_localPath, "reading", "Could not open file!");
}
std::string action = "detect";
while(!modinfo.eof()) {
std::string line = "";
char c;
do {
modinfo.get(c);
if(c != '\n');
line += c;
} while(c != '\n');
line = strip_endl(line);
if(modinfo) {
if(line[0] != NULL && line[0] != ' ' && line[0] != '\n' && line[0] != '\r') {
if(action == "detect") {
if(line[0] == '{') {
std::string name = "";
for(unsigned int i = 1; line[i] != '}' && i < line.length(); i++) {
name += line[i];
}
_name = name;
action = "parse";
} else {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although { was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(action == "parse") {
if(line[0] == '{') {
if(line[1] == 'e' && line[2] == 'n' && line[3] == 'd' && line[4] == '}') {
action = "detect";
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(line[0] == '[') {
std::string tmpact = "";
for(unsigned int i = 1; line[i] != ']' && i < line.length(); i++) {
tmpact += line[i];
}
if(tmpact == "description" || tmpact == "release" || tmpact == "deps" || tmpact == "repotype" || tmpact == "repoaddr") {
action = tmpact;
} else {
std::string msg = "";
msg += "Found ";
msg += tmpact;
msg += " although description/release/deps/repotype/repoaddr was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although {end} or action in [] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else if(action == "description") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_description = line;
action = "parse";
}
} else if(action == "release") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_release = atoi(line.c_str());
action = "parse";
}
} else if(action == "deps") {
if(line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string or [ was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else if(line[0] == '[') {
if(line[1] == 'd' && line[2] == 'e' && line[3] == 'p' && line[4] == 's' && line[5] == 'e' && line[6] == 'n' && line[7] == 'd' && line[8] == ']') {
if(_deps.empty()) {
_deps.push_back("none");
}
action = "parse";
} else {
std::string msg = "";
msg += "Found ";
msg += line;
msg += " although string or [depsend] was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
}
} else {
_deps.push_back(line);
}
} else if(action == "repotype") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_repotype = line;
action = "parse";
}
} else if(action == "repoaddr") {
if(line[0] == '[' || line[0] == '{') {
std::string msg = "";
msg += "Found ";
msg += line[0];
msg += " although string was expected.";
throw ParseException(_desc.getServer() + _desc.getPath(), msg);
} else {
_repoaddr = line;
action = "parse";
}
} else {
throw ParseException(_desc.getServer() + _desc.getPath(), "The program should not reach this place!");
}
}
}
}
}
void ModInfo::setPath(std::string path) {
_edit = true;
_localPath = path;
}
void ModInfo::write() {
if(!_edit) {
throw NonEditableException("Tried to write back remotely obtained modinfo file!");
}
std::ofstream modinfo(_localPath.c_str());
if(!ofstream) {
throw FileException(_localPath, "writing", "Could not open file!");
}
modinfo << "{" << _name << "}" << std::endl << "[description]" << std::endl << _description << std::endl << "[release]" << std::endl << _release << std::endl << "[deps]" << std::endl;
if(_deps.size() == 0) {
modinfo << "none" << std::endl;
} else {
for(unsigned int i = 0; i < _deps.size(); i++) {
modinfo << _deps[i] << std::endl;
}
}
modinfo << "[depsend]" << std::endl << "[repotype]" << std::endl << _repotype << std::endl << "[repoaddr]" << std::endl << _repoaddr << std::endl << "{end}" << std::endl;
modinfo.close();
}
void ModInfo::releaseInc() {
_release++;
}
void ModInfo::~ModInfo() {
ModInfoDescription emptymid;
_desc = emptymid;
_edit = false;
_localPath = "";
}
void ModInfo::clear() {
_name = "";
_description = "";
_release = 0;
_depsIterator = -1;
_depsAtEnd = true;
_repotype = "";
_repoaddr = "";
_deps.clear();
ModInfoDescription emptymid;
_desc = emptymid;
_edit = false;
_localPath = "";
}

37
ModInfo.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef _MODINFO_H
#define _MODINFO_H
#include "3m.h"
#include <string>
/// \file ModInfo.h
/// \brief A class that represents remote modinfo file.
/// \author Phitherek_
/// \date 2013
/// \version 0.1-pre
/// \namespace mmm
/// \brief A global namespace for 3m.
namespace mmm {
/// \class ModInfo
/// \brief A class that represents remote modinfo file
class ModInfo: public ModDescription {
private:
ModInfoDescription _desc;
bool _edit;
std::string _localPath;
public:
ModInfo(); ///< A constructor.
ModInfo(ModInfoDescripton mid); ///< \brief A constructor from ModInfoDescription object.
///< Tries to download and parse remote modinfo file.
///< \param mid A ModInfoDescription object.
ModInfo(std::string path); ///< \brief A construtor from the path to local modinfo file.
///< It tries to open and parse local modinfo file, opening it for editing.
///< \param path A path to local modinfo file.
void setPath(std::string path); ///< \brief A function that sets local modinfo file to edit.
///< \param path A path to local modinfo file.
void write(); ///< A function that writes the changes to local modinfo file.
void releaseInc(); ///< A function that increases modinfo release.
~ModInfo(); ///< A destructor.
void clear(); ///< A function that clears the object.
};
}
#endif

View File

@ -36,3 +36,9 @@ _server = server;
void ModInfoDescription::setPath(std::string path) {
_path = path;
}
void ModInfoDescription::clear() {
_name = "";
_server = "";
_path = "";
}

View File

@ -35,6 +35,7 @@ public:
///< \param server Server with modinfo.
void setPath(std::string path); ///< \brief A function setting modinfo path on server.
///< \param path Modinfo path on server.
void clear(); ///< A function clearing the object.
};
}
#endif

40
ModList.cpp Normal file
View File

@ -0,0 +1,40 @@
#include "ModList.h"
#include "NetSocket++/NetSocketPP.h"
#include "3mExceptions.h"
using namespace mmm;
ModList::ModList() {
ModListDescription emptymld;
_desc = emptymld;
_modinfos.clear();
_edit = false;
_localPath = "";
_modinfosIterator = -1;
_modinfosAtEnd = true;
}
ModList::ModList(ModListDescription mld) {
_desc = mld;
_modinfos.clear();
_edit = false;
_localPath = "";
_modinforIterator = -1;
_modinfosAtEnd = false;
NetSocketPP::HTTPReply data;
try {
NetSocketPP::HTTPClientSocket conn(_desc.getServer(), "http", _desc.getPath());
std::cout << "Connection to " << conn.getIP() << " successful!" << std::endl;
data = conn.getReply();
} catch (NetSocketPP::SocketException &exc) {
std::cerr << "SocketException occured while getting remote modlist: " << exc.what() << std::endl;
throw(exc);
} catch (NetSocketPP::NetworkException &exc) {
std::cerr << "NetworkException occured while getting remote modlist: " << exc.what() << std::endl;
throw(exc);
}
if(data.getResponse() != "200 OK") {
throw BadResponseException(data.getResponse());
}
std::string content = data.getContent();
}

49
ModList.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef _MODLIST_H
#define _MODLIST_H
#include "ModListDescription.h"
#include "ModInfoDescription.h"
#include <string>
#include <vector>
/// \file ModList.h
/// \brief A class representing a modlist.
/// \author Phitherek_
/// \date 2013
/// \version 0.1-pre
/// \namespace mmm
/// \brief A global namespace for 3m.
namespace mmm {
/// \class ModList
/// \brief A class representing a modlist.
class ModList {
private:
ModListDescription _desc;
std::vector<ModInfoDescription> _modinfos;
bool _edit;
std::string _localPath;
int _modinfosIterator;
bool _modinfosAtEnd;
public:
ModList(); ///< A constructor.
ModList(ModListDescription mld); ///< \brief A constructor from ModListDescription.
///< It tries to download and parse the remote modlist file. It throws ParseException or one of NetSocket++ exceptions.
///< \param mld A ModListDescription object.
ModList(std::string path); ///< \brief A constructor from std::string.
///< It tries to open and parse locally stored modlist file. It throws FileException or ParseException.
~ModList(); ///< A destructor.
ModInfoDescription getNextModInfoDescription(); ///< \brief A function that returns next ModInfoDescription from the modlist.
///< \return Next ModInfoDescription from the modlist or empty ModInfoDescription object if at the end of modlist.
ModInfoDescription getModInfoDescriptionByName(std::string name); ///< \brief A function that searches for modinfo name and returns its ModInfoDescription.
///< \param name Modinfo name.
///< \return ModInfoDescription of the modinfo or empty ModInfoDescription object on failure.
void insertModInfoDescription(ModInfoDescription mid); ///< \brief A function that inserts a ModInfoDescription to the modlist.
///< \param mid A ModInfoDescription to be inserted.
void deleteModInfoDescription(std::string name); ///< \brief A function that deletes ModInfoDescription of given name from the modlist.
///< \param name Modinfo name.
void resetModInfoDescriptionIterator(); ///< A function that resets modlist iterator.
bool modInfoDescriptionsAtEnd(); ///< \brief A function, that returns if modlist iterator reached its end.
///< \return True if modlist iterator reached its end, false otherwise.
void write(); ///< A function that writes modlist to local file.
};
}
#endif

View File

@ -14,4 +14,3 @@ SyncAction
InstallAction
UpdateAction
RemoveAction
InfoAction