zen::Xml: io.h Source File

| zen::Xml Simple C++ XML Processing

- Main Page
- Namespaces
- Classes

All Classes Namespaces Functions Variables Pages
io.h
1 // *****************************************************************************
2 // * This file is part of the FreeFileSync project. It is distributed under *
3 // * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
4 // * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
5 // *****************************************************************************
6
7 #ifndef IO_H_8917640501480763248343343
8 #define IO_H_8917640501480763248343343
9
10 #include <cstdio>
11 #include <cerrno>
12 #include <zen/scope_guard.h>
13 #include <zen/utf.h>
14 #include "error.h"
15
16 namespace zen
17 {
23 #if !defined(ZEN_WIN) && !defined(ZEN_LINUX) && !defined(ZEN_MAC)
24 #error Please specify your platform: #define ZEN_WIN, ZEN_LINUX or ZEN_MAC
25 #endif
26
27
29 struct XmlFileError : public XmlError
30 {
31 using ErrorCode = int;
32
33 explicit XmlFileError(ErrorCode ec) : lastError(ec) {}
35 ErrorCode lastError;
36 };
37
38
39 #ifdef ZEN_WIN
40 namespace implemenation //sad but true
41 {
42 template <class String> inline
43 FILE* fopen(const String& filename, const wchar_t* mode)
44 {
45 #ifdef _MSC_VER
46 FILE* handle = nullptr;
47 errno_t rv = ::_wfopen_s(&handle, utfCvrtTo<std::wstring>(filename).c_str(), mode); //really more secure now?
48 (void)rv;
49 return handle;
50 #else
51 return ::_wfopen(utfCvrtTo<std::wstring>(filename).c_str(), mode);
52 #endif
53 }
54 }
55 #endif
56
57
59
65 template <class String>
66 void saveStream(const std::string& stream, const String& filename) //throw XmlFileError
67 {
68 #ifdef ZEN_WIN
69 FILE* handle = implemenation::fopen(utfCvrtTo<std::wstring>(filename).c_str(), L"wb");
70 #else
71 FILE* handle = ::fopen(utfCvrtTo<std::string>(filename).c_str(), "w");
72 #endif
73 if (!handle)
74 throw XmlFileError(errno);
75 ZEN_ON_SCOPE_EXIT(::fclose(handle));
76
77 const size_t bytesWritten = ::fwrite(stream.c_str(), 1, stream.size(), handle);
78 if (::ferror(handle) != 0)
79 throw XmlFileError(errno);
80
81 (void)bytesWritten;
82 assert(bytesWritten == stream.size());
83 }
84
85
87
93 template <class String>
94 std::string loadStream(const String& filename) //throw XmlFileError
95 {
96 #ifdef ZEN_WIN
97 FILE* handle = implemenation::fopen(utfCvrtTo<std::wstring>(filename).c_str(), L"rb");
98 #else
99 FILE* handle = ::fopen(utfCvrtTo<std::string>(filename).c_str(), "r");
100 #endif
101 if (!handle)
102 throw XmlFileError(errno);
103 ZEN_ON_SCOPE_EXIT(::fclose(handle));
104
105 std::string stream;
106 const size_t blockSize = 64 * 1024;
107 do
108 {
109 stream.resize(stream.size() + blockSize); //let's pray std::string implements exponential growth!
110
111 const size_t bytesRead = ::fread(&*(stream.end() - blockSize), 1, blockSize, handle);
112 if (::ferror(handle))
113 throw XmlFileError(errno);
114 if (bytesRead > blockSize)
115 throw XmlFileError(0);
116 if (bytesRead < blockSize)
117 stream.resize(stream.size() - blockSize + bytesRead); //caveat: unsigned arithmetics
118 }
119 while (!::feof(handle));
120
121 return stream;
122 }
123 }
124
125 #endif //IO_H_8917640501480763248343343
zen::saveStream
void saveStream(const std::string &stream, const String &filename)
Save byte stream to a file.
Definition: io.h:66
zen::loadStream
std::string loadStream(const String &filename)
Load byte stream from a file.
Definition: io.h:94
zen
The zen::Xml namespace.
Definition: bind.h:15
zen::XmlFileError::lastError
ErrorCode lastError
Native error code: errno.
Definition: io.h:35
zen::XmlFileError
Exception thrown due to failed file I/O.
Definition: io.h:29
zen::XmlError
Exception base class for zen::Xml.
Definition: error.h:13