]> git.donarmstrong.com Git - flightcrew.git/blob - src/FlightCrew/Validators/Xml/UsesUnicode.cpp
Imported Upstream version 0.7.2+dfsg
[flightcrew.git] / src / FlightCrew / Validators / Xml / UsesUnicode.cpp
1 /************************************************************************\r
2 **\r
3 **  Copyright (C) 2010  Strahinja Markovic\r
4 **\r
5 **  This file is part of FlightCrew.\r
6 **\r
7 **  FlightCrew is free software: you can redistribute it and/or modify\r
8 **  it under the terms of the GNU Lesser General Public License as published\r
9 **  by the Free Software Foundation, either version 3 of the License, or\r
10 **  (at your option) any later version.\r
11 **\r
12 **  FlightCrew is distributed in the hope that it will be useful,\r
13 **  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 **  GNU Lesser General Public License for more details.\r
16 **\r
17 **  You should have received a copy of the GNU Lesser General Public License\r
18 **  along with FlightCrew.  If not, see <http://www.gnu.org/licenses/>.\r
19 **\r
20 *************************************************************************/\r
21 \r
22 #include <stdafx.h>\r
23 #include <fstream>\r
24 #include <utf8.h>\r
25 #include "UsesUnicode.h"\r
26 #include "Misc/Utilities.h"\r
27 #include "Result.h"\r
28 \r
29 \r
30 static const int NUM_PEEK_CHARS_FOR_XML_DECLARATION = 80;\r
31 \r
32 namespace FlightCrew\r
33 {\r
34 \r
35 std::vector< Result > UsesUnicode::ValidateFile( const fs::path &filepath )\r
36 {\r
37     std::vector< Result > results;\r
38 \r
39     try\r
40     {\r
41         std::string inital_chars = Util::GetFirstNumCharsFromFile( filepath, NUM_PEEK_CHARS_FOR_XML_DECLARATION );\r
42 \r
43         if ( FileIsValidUtf8( filepath ) )\r
44         {\r
45             if ( !FileDeclaresUtf8( inital_chars ) )\r
46             {\r
47                 results.push_back( Result( ERROR_XML_SPECIFIES_NEITHER_UTF8_NOR_UTF16 )\r
48                     .SetErrorLine( 1 )\r
49                     .AddMessageArgument( GetDeclaredEncoding( inital_chars ) ) );\r
50             }\r
51 \r
52             // else everything ok\r
53         }\r
54 \r
55         else\r
56         {            \r
57             if ( !inital_chars.empty() )\r
58             {\r
59                 // It's in UTF-16\r
60 \r
61                 if ( !FileDeclaresUtf16( inital_chars ) )\r
62                 {\r
63                     results.push_back( Result( ERROR_XML_SPECIFIES_NEITHER_UTF8_NOR_UTF16 )\r
64                         .SetErrorLine( 1 )\r
65                         .AddMessageArgument( GetDeclaredEncoding( inital_chars ) ) );\r
66                 }\r
67 \r
68                 // else everything ok\r
69             }\r
70 \r
71             else\r
72             {\r
73                 results.push_back( Result( ERROR_XML_BYTESTREAM_NEITHER_UTF8_NOR_UTF16 )\r
74                     .SetErrorLine( 1 ) );\r
75             }\r
76         }\r
77 \r
78         return results;\r
79     }\r
80 \r
81     catch ( ExceptionBase& )\r
82     {\r
83         results.clear();\r
84         results.push_back( Result( UNABLE_TO_PERFORM_VALIDATION ) );        \r
85     }  \r
86 \r
87     return Util::AddPathToResults( results, filepath );\r
88 }\r
89 \r
90 \r
91 bool UsesUnicode::FileIsValidUtf8( const fs::path &filepath )\r
92 {\r
93     fs::ifstream file( filepath, std::ios::in | std::ios::binary );\r
94     std::istreambuf_iterator<char> it( file.rdbuf() );\r
95     std::istreambuf_iterator<char> eos;\r
96 \r
97     return utf8::is_valid( it, eos );\r
98 }\r
99 \r
100 \r
101 bool UsesUnicode::FileDeclaresUtf8( const std::string &line )\r
102 {   \r
103     if ( HasXmlDeclaration( line ) )\r
104     {\r
105         std::string encoding = boost::to_upper_copy( GetDeclaredEncoding( line ) );\r
106 \r
107         // Empty still counts as utf-8 as per spec\r
108         if ( encoding.empty() || encoding == "UTF-8" )\r
109                 \r
110             return true;\r
111 \r
112         return false;\r
113     }\r
114 \r
115     // No xml declaration means\r
116     // UTF-8 according to the spec\r
117     return true;\r
118 }\r
119 \r
120 \r
121 bool UsesUnicode::FileDeclaresUtf16( const std::string &line )\r
122 {   \r
123     if ( HasXmlDeclaration( line ) )\r
124     {\r
125         if ( boost::to_upper_copy( GetDeclaredEncoding( line ) ) == "UTF-16" )\r
126                 \r
127             return true;\r
128 \r
129         return false;\r
130     }\r
131 \r
132     return false;\r
133 }\r
134 \r
135 \r
136 bool UsesUnicode::HasXmlDeclaration( const std::string &line )\r
137 {\r
138     return boost::contains( line, "<?" );\r
139 }\r
140 \r
141 \r
142 std::string UsesUnicode::GetDeclaredEncoding( const std::string &line )\r
143 {\r
144     boost::regex expression( "encoding\\s*=\\s*(?:\"|')([^\"']+)(?:\"|')" );\r
145     boost::match_results< std::string::const_iterator > matches;\r
146 \r
147     // FIXME: return only when regex_search returns true\r
148     boost::regex_search( line, matches, expression );\r
149     return matches[ 1 ];\r
150 }\r
151 \r
152 } //namespace FlightCrew\r