zenXML
Straightforward C++ XML Processing
|
00001 // ************************************************************************** 00002 // * This file is part of the zenXML project. It is distributed under the * 00003 // * Boost Software License, Version 1.0. See accompanying file * 00004 // * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt. * 00005 // * Copyright (C) 2011 ZenJu (zhnmju123 AT gmx.de) * 00006 // ************************************************************************** 00007 00008 #ifndef ZEN_XML_IO_HEADER_8917640501480763248343343 00009 #define ZEN_XML_IO_HEADER_8917640501480763248343343 00010 00011 #include "string_tools.h" 00012 #include "loki/ScopeGuard.h" 00013 #include "zenxml_error.h" 00014 #include "string_utf8.h" 00015 #include <cerrno> 00016 00017 namespace zen 00018 { 00024 #if !defined(ZEN_PLATFORM_WINDOWS) && !defined(ZEN_PLATFORM_OTHER) 00025 #error Please specify your platform: #define ZEN_PLATFORM_WINDOWS or ZEN_PLATFORM_OTHER 00026 #endif 00027 00029 struct XmlFileError : public XmlError 00030 { 00031 typedef int ErrorCode; 00032 00033 XmlFileError(ErrorCode ec) : lastError(ec) {} 00035 ErrorCode lastError; 00036 }; 00037 00038 #ifdef ZEN_PLATFORM_WINDOWS 00039 template <class String> inline 00040 std::wstring toWideString(const String& str, char) { return utf8ToWide<std::wstring>(str); } //convert UTF8 to wide character string 00041 00042 template <class String> inline 00043 const String& toWideString(const String& str, wchar_t) { return str; } //directly process string without conversion 00044 #endif 00045 00047 00053 template <class String> 00054 void saveStream(const std::string& stream, const String& filename) //throw XmlFileError 00055 { 00056 #ifdef ZEN_PLATFORM_WINDOWS 00057 FILE* handle = ::_wfopen(strBegin(toWideString(filename, typename StringTraits<String>::CharType())), L"wb"); 00058 #else 00059 FILE* handle = ::fopen(toStdString(filename).c_str(), "w"); 00060 #endif 00061 if (handle == NULL) 00062 throw XmlFileError(errno); 00063 00064 Loki::ScopeGuard dummy = Loki::MakeGuard(::fclose, handle); 00065 (void)dummy; 00066 00067 const size_t bytesWritten = ::fwrite(stream.c_str(), 1, stream.size(), handle); 00068 if (::ferror(handle) != 0) 00069 throw XmlFileError(errno); 00070 00071 assert(bytesWritten == stream.size()); 00072 } 00073 00074 00076 00082 template <class String> 00083 std::string loadStream(const String& filename) //throw XmlFileError 00084 { 00085 #ifdef ZEN_PLATFORM_WINDOWS 00086 FILE* handle = ::_wfopen(strBegin(toWideString(filename, typename StringTraits<String>::CharType())), L"rb"); 00087 #else 00088 FILE* handle = ::fopen(toStdString(filename).c_str(), "r"); 00089 #endif 00090 if (handle == NULL) 00091 throw XmlFileError(errno); 00092 00093 Loki::ScopeGuard dummy = Loki::MakeGuard(::fclose, handle); 00094 (void)dummy; 00095 00096 std::string stream; 00097 do 00098 { 00099 const size_t BLOCK_SIZE = 10 * 1024; 00100 char buffer[BLOCK_SIZE]; 00101 00102 const size_t bytesRead = ::fread(buffer, 1, BLOCK_SIZE, handle); 00103 if (::ferror(handle)) 00104 throw XmlFileError(errno); 00105 00106 assert(bytesRead <= BLOCK_SIZE); 00107 00108 stream.append(buffer, bytesRead); 00109 } 00110 while (!::feof(handle)); 00111 00112 return stream; 00113 } 00114 } 00115 00116 #endif //ZEN_XML_IO_HEADER_8917640501480763248343343