zenXML
Straightforward C++ XML Processing
zenxml_io.h
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
 All Classes Namespaces Functions Variables