1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmXMLSafe.h"
16 #include <cmsys/ios/iostream>
17 #include <cmsys/ios/sstream>
22 //----------------------------------------------------------------------------
23 cmXMLSafe::cmXMLSafe(const char* s):
25 Size(static_cast<unsigned long>(strlen(s))),
30 //----------------------------------------------------------------------------
31 cmXMLSafe::cmXMLSafe(cmsys_stl::string const& s):
33 Size(static_cast<unsigned long>(s.length())),
38 //----------------------------------------------------------------------------
39 cmXMLSafe& cmXMLSafe::Quotes(bool b)
45 //----------------------------------------------------------------------------
46 cmsys_stl::string cmXMLSafe::str()
48 cmsys_ios::ostringstream ss;
53 //----------------------------------------------------------------------------
54 cmsys_ios::ostream& operator<<(cmsys_ios::ostream& os, cmXMLSafe const& self)
56 char const* first = self.Data;
57 char const* last = self.Data + self.Size;
61 if(const char* next = cm_utf8_decode_character(first, last, &ch))
63 // http://www.w3.org/TR/REC-xml/#NT-Char
64 if((ch >= 0x20 && ch <= 0xD7FF) ||
65 (ch >= 0xE000 && ch <= 0xFFFD) ||
66 (ch >= 0x10000 && ch <= 0x10FFFF) ||
67 ch == 0x9 || ch == 0xA || ch == 0xD)
71 // Escape XML control characters.
72 case '&': os << "&"; break;
73 case '<': os << "<"; break;
74 case '>': os << ">"; break;
75 case '"': os << (self.DoQuotes? """ : "\""); break;
76 case '\'': os << (self.DoQuotes? "'" : "'"); break;
77 case '\r': break; // Ignore CR
78 // Print the UTF-8 character.
79 default: os.write(first, next-first); break;
84 // Use a human-readable hex value for this invalid character.
86 sprintf(buf, "%X", ch);
87 os << "[NON-XML-CHAR-0x" << buf << "]";
94 ch = static_cast<unsigned char>(*first++);
95 // Use a human-readable hex value for this invalid byte.
97 sprintf(buf, "%X", ch);
98 os << "[NON-UTF-8-BYTE-0x" << buf << "]";