00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "addon/addon.hpp"
00018
00019 #include <physfs.h>
00020 #include <stdexcept>
00021 #include <sstream>
00022
00023 #include "addon/md5.hpp"
00024 #include "lisp/parser.hpp"
00025 #include "util/reader.hpp"
00026 #include "util/writer.hpp"
00027 #include "util/log.hpp"
00028
00029 std::string
00030 Addon::get_md5() const
00031 {
00032 if (!installed) {
00033 if (stored_md5 == "") log_warning << "Add-on not installed and no stored MD5 available" << std::endl;
00034 return stored_md5;
00035 }
00036
00037 if (calculated_md5 != "") return calculated_md5;
00038
00039 if (installed_physfs_filename == "") throw std::runtime_error("Tried to calculate MD5 of Add-on with unknown filename");
00040
00041
00042
00043
00044
00045 MD5 md5;
00046 PHYSFS_file* file;
00047 file = PHYSFS_openRead(installed_physfs_filename.c_str());
00048 unsigned char buffer[1024];
00049 while (true) {
00050 PHYSFS_sint64 len = PHYSFS_read(file, buffer, 1, sizeof(buffer));
00051 if (len <= 0) break;
00052 md5.update(buffer, len);
00053 }
00054 PHYSFS_close(file);
00055
00056 calculated_md5 = md5.hex_digest();
00057 log_debug << "MD5 of " << title << ": " << calculated_md5 << std::endl;
00058
00059 return calculated_md5;
00060 }
00061
00062 void
00063 Addon::parse(const Reader& lisp)
00064 {
00065 try {
00066 lisp.get("kind", kind);
00067 lisp.get("title", title);
00068 lisp.get("author", author);
00069 lisp.get("license", license);
00070 lisp.get("http-url", http_url);
00071 lisp.get("file", suggested_filename);
00072 lisp.get("md5", stored_md5);
00073 } catch(std::exception& e) {
00074 std::stringstream msg;
00075 msg << "Problem when parsing addoninfo: " << e.what();
00076 throw std::runtime_error(msg.str());
00077 }
00078 }
00079
00080 void
00081 Addon::parse(std::string fname)
00082 {
00083 try {
00084 lisp::Parser parser;
00085 const lisp::Lisp* root = parser.parse(fname);
00086 const lisp::Lisp* addon = root->get_lisp("supertux-addoninfo");
00087 if(!addon) throw std::runtime_error("file is not a supertux-addoninfo file.");
00088 parse(*addon);
00089 } catch(std::exception& e) {
00090 std::stringstream msg;
00091 msg << "Problem when reading addoninfo '" << fname << "': " << e.what();
00092 throw std::runtime_error(msg.str());
00093 }
00094 }
00095
00096 void
00097 Addon::write(lisp::Writer& writer) const
00098 {
00099 writer.start_list("supertux-addoninfo");
00100 if (kind != "") writer.write("kind", kind);
00101 if (title != "") writer.write("title", title);
00102 if (author != "") writer.write("author", author);
00103 if (license != "") writer.write("license", license);
00104 if (http_url != "") writer.write("http-url", http_url);
00105 if (suggested_filename != "") writer.write("file", suggested_filename);
00106 if (stored_md5 != "") writer.write("md5", stored_md5);
00107 writer.end_list("supertux-addoninfo");
00108 }
00109
00110 void
00111 Addon::write(std::string fname) const
00112 {
00113 lisp::Writer writer(fname);
00114 write(writer);
00115 }
00116
00117 bool
00118 Addon::operator==(Addon addon2) const
00119 {
00120 std::string s1 = this->get_md5();
00121 std::string s2 = addon2.get_md5();
00122
00123 if ((s1 != "") && (s2 != "")) return (s1 == s2);
00124
00125 if (this->title != addon2.title) return false;
00126 if (this->author != addon2.author) return false;
00127 if (this->kind != addon2.kind) return false;
00128 return true;
00129 }
00130
00131