2 * Copyright (C) 2005-2011 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "XBMCTinyXML.h"
21 #include "filesystem/File.h"
24 #define MAX_ENTITY_LENGTH 8 // size of largest entity "&#xNNNN;"
25 #define BUFFER_SIZE 4096
27 CXBMCTinyXML::CXBMCTinyXML()
32 CXBMCTinyXML::CXBMCTinyXML(const char *documentName)
35 LoadFile(documentName);
38 CXBMCTinyXML::CXBMCTinyXML(const CStdString &documentName)
41 LoadFile(documentName);
44 bool CXBMCTinyXML::LoadFile(TiXmlEncoding encoding)
46 return TiXmlDocument::LoadFile(encoding);
49 bool CXBMCTinyXML::LoadFile(const char *_filename, TiXmlEncoding encoding)
51 CStdString filename(_filename);
52 return LoadFile(filename, encoding);
55 bool CXBMCTinyXML::LoadFile(const CStdString &_filename, TiXmlEncoding encoding)
57 // There was a really terrifying little bug here. The code:
59 // in the STL case, cause the assignment method of the std::string to
60 // be called. What is strange, is that the std::string had the same
61 // address as it's c_str() method, and so bad things happen. Looks
62 // like a bug in the Microsoft STL implementation.
63 // Add an extra string to avoid the crash.
64 CStdString filename(_filename);
67 XFILE::CFileStream file;
68 if (!file.Open(value))
70 SetError(TIXML_ERROR_OPENING_FILE, NULL, NULL, TIXML_ENCODING_UNKNOWN);
74 // Delete the existing data:
79 data.reserve(8 * 1000);
80 StreamIn(&file, &data);
83 Parse(data, NULL, encoding);
90 bool CXBMCTinyXML::LoadFile(FILE *f, TiXmlEncoding encoding)
93 char buf[BUFFER_SIZE];
94 int result, count = 0;
95 while ((result = fread(buf, 1, BUFFER_SIZE, f)) > 0)
97 data.reserve(BUFFER_SIZE * (++count));
100 return Parse(data, NULL, encoding) != NULL;
103 bool CXBMCTinyXML::SaveFile(const char *_filename) const
105 CStdString filename(_filename);
106 return SaveFile(filename);
109 bool CXBMCTinyXML::SaveFile(const CStdString &filename) const
112 if (file.OpenForWrite(filename, true))
114 TiXmlPrinter printer;
116 file.Write(printer.CStr(), printer.Size());
122 const char *CXBMCTinyXML::Parse(const char *_data, TiXmlParsingData *prevData, TiXmlEncoding encoding)
124 CStdString data(_data);
125 return Parse(data, prevData, encoding);
128 const char *CXBMCTinyXML::Parse(CStdString &data, TiXmlParsingData *prevData, TiXmlEncoding encoding)
130 // Preprocess string, replacing '&' with '& for invalid XML entities
133 re.RegComp("^&(amp|lt|gt|quot|apos|#x[a-fA-F0-9]{1,4}|#[0-9]{1,5});.*");
134 while ((pos = data.find("&", pos)) != CStdString::npos)
136 CStdString tmp = data.substr(pos, pos + MAX_ENTITY_LENGTH);
137 if (re.RegFind(tmp) < 0)
138 data.insert(pos + 1, "amp;");
141 return TiXmlDocument::Parse(data.c_str(), prevData, encoding);
144 bool CXBMCTinyXML::Test()
146 // scraper results with unescaped &
148 CStdString data("<details><url function=\"ParseTMDBRating\" "
149 "cache=\"tmdb-en-12244.json\">"
150 "http://api.themoviedb.org/3/movie/12244"
151 "?api_key=57983e31fb435df4df77afb854740ea9"
152 "&language=en???</url></details>");
153 doc.Parse(data.c_str());
154 TiXmlNode *root = doc.RootElement();
155 if (root && root->ValueStr() == "details")
157 TiXmlElement *url = root->FirstChildElement("url");
158 if (url && url->FirstChild())
160 return (url->FirstChild()->ValueStr() == "http://api.themoviedb.org/3/movie/12244?api_key=57983e31fb435df4df77afb854740ea9&language=en???");