327cadca888d48bc5b5a8364c62d42f7bcb98d52
[shibboleth/cpp-xmltooling.git] / xmltooling / unicode.h
1 /*
2  *  Copyright 2001-2010 Internet2
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  * @file xmltooling/unicode.h
19  *
20  * Helper classes and types for manipulating Unicode
21  */
22
23 #ifndef __xmltooling_unicode_h__
24 #define __xmltooling_unicode_h__
25
26 #include <xmltooling/base.h>
27
28 #ifndef HAVE_GOOD_STL
29 # include <xmltooling/char_traits.h>
30 #endif
31
32 #include <string>
33 #include <iostream>
34 #include <xercesc/util/XMLString.hpp>
35
36 namespace xmltooling {
37
38 #ifdef HAVE_GOOD_STL
39         /**
40          * An STL string type that supports 16-bit Unicode.
41          */
42         typedef std::basic_string<XMLCh> xstring;
43 #else
44         /**
45          * An STL string type that supports 16-bit Unicode.
46          */
47         typedef std::basic_string< XMLCh,char_traits<XMLCh> > xstring;
48 #endif
49
50     /**
51      * Transcodes a 16-bit Unicode string into UTF-8.
52      *
53      * @param src           the 16-bit string to transcode
54      * @param use_malloc    true iff the result should be allocated with malloc, false to use new
55      * @return      a UTF-8 string allocated by the Xerces memory manager
56      */
57     extern XMLTOOL_API char* toUTF8(const XMLCh* src, bool use_malloc=false);
58
59     /**
60      * Transcodes a UTF-8 string into 16-bit Unicode.
61      *
62      * @param src           the UTF-8 string to transcode
63      * @param use_malloc    true iff the result should be allocated with malloc, false to use new
64      * @return      a 16-bit Unicode string allocated by the Xerces memory manager
65      */
66     extern XMLTOOL_API XMLCh* fromUTF8(const char* src, bool use_malloc=false);
67
68     /**
69      * Writes a Unicode string to an ASCII stream by transcoding to UTF8.
70      *
71      * @param ostr  stream to write to
72      * @param s     string to write
73      * @return      reference to output stream
74      */
75     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLCh* s);
76
77     /**
78      * Writes a Unicode string to an ASCII stream by transcoding to UTF8.
79      *
80      * @param ostr  stream to write to
81      * @param s     string to write
82      * @return      reference to output stream
83      */
84     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const xstring& s);
85
86     /**
87      * A minimal auto_ptr-like class that can copy or transcode a buffer into
88      * the local code page and free the result automatically.
89      *
90      * Needed because a standard auto_ptr would use delete on the resulting
91      * pointer.
92      */
93     class XMLTOOL_API auto_ptr_char
94     {
95         MAKE_NONCOPYABLE(auto_ptr_char);
96     public:
97         /**
98          * Default constructor.
99          */
100         auto_ptr_char() : m_buf(nullptr) {
101         }
102
103         /**
104          * Constructor transcodes a 16-bit Unicode string into the local code page (NOT UTF-8) and wraps the result.
105          * @param src   the 16-bit string to transcode and wrap
106          * @param trim  trims leading/trailing whitespace from the result (defaults to true)
107          */
108         auto_ptr_char(const XMLCh* src, bool trim=true) : m_buf(xercesc::XMLString::transcode(src)) {
109             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
110         }
111
112         /**
113          * Constructor copies a local code page (NOT UTF-8) string and wraps the result.
114          * @param src   the local string to copy and wrap
115          * @param trim  trims leading/trailing whitespace from the result (defaults to true)
116          */
117         auto_ptr_char(const char* src, bool trim=true) : m_buf(xercesc::XMLString::replicate(src)) {
118             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
119         }
120
121         /**
122          * Destructor frees the wrapped buffer using the Xerces memory manager.
123          */
124         ~auto_ptr_char() {
125             xercesc::XMLString::release(&m_buf);
126         }
127
128         /**
129          * Returns the wrapped buffer.
130          * @return a null-terminated local code page string
131          */
132         const char* get() const {
133             return m_buf;
134         }
135
136         /**
137          * Returns the wrapped buffer and transfers ownership of it to the caller.
138          * @return a null-terminated local code page string
139          */
140         char* release() {
141             char* temp=m_buf; m_buf=nullptr; return temp;
142         }
143
144     private:
145         char* m_buf;
146     };
147
148     /**
149      * A minimal auto_ptr-like class that can copy or transcode a buffer into
150      * 16-bit Unicode and free the result automatically.
151      *
152      * Needed because a standard auto_ptr would use delete on the resulting
153      * pointer.
154      */
155     class XMLTOOL_API auto_ptr_XMLCh
156     {
157         MAKE_NONCOPYABLE(auto_ptr_XMLCh);
158     public:
159         /**
160          * Default constructor.
161          */
162         auto_ptr_XMLCh() : m_buf(nullptr) {
163         }
164
165         /**
166          * Constructor transcodes a local code page (NOT UTF-8) string into 16-bit Unicode and wraps the result.
167          * @param src   the local string to transcode and wrap
168          * @param trim  trims leading/trailing whitespace from the result (defaults to true)
169          */
170         auto_ptr_XMLCh(const char* src, bool trim=true) : m_buf(xercesc::XMLString::transcode(src)) {
171             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
172         }
173
174         /**
175          * Constructor copies a 16-bit Unicode string and wraps the result.
176          * @param src   the Unicode string to copy and wrap
177          * @param trim  trims leading/trailing whitespace from the result (defaults to true)
178          */
179         auto_ptr_XMLCh(const XMLCh* src, bool trim=true) : m_buf(xercesc::XMLString::replicate(src)) {
180             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
181         }
182
183         /**
184          * Destructor frees the wrapped buffer using the Xerces memory manager.
185          */
186         ~auto_ptr_XMLCh() {
187             xercesc::XMLString::release(&m_buf);
188         }
189
190         /**
191          * Returns the wrapped buffer.
192          * @return a null-terminated Unicode string
193          */
194         const XMLCh* get() const {
195             return m_buf;
196         }
197
198         /**
199          * Returns the wrapped buffer and transfers ownership of it to the caller.
200          * @return a null-terminated Unicode string
201          */
202         XMLCh* release() {
203             XMLCh* temp=m_buf; m_buf=nullptr; return temp;
204         }
205
206     private:
207         XMLCh* m_buf;
208     };
209
210     /**
211      * An auto_ptr that uses array delete on its contents.
212      *
213      * @param T type of pointer to wrap
214      */
215     template <typename T> class auto_arrayptr
216     {
217         T* m_ptr;
218
219         auto_arrayptr(const auto_arrayptr<T>&);
220         auto_arrayptr<T>& operator=(const auto_arrayptr<T>&);
221     public:
222         /**
223          * Constructor.
224          *
225          * @param ptr pointer to wrap
226          */
227         auto_arrayptr(T* ptr) : m_ptr(ptr) {
228         }
229
230         /**
231          * Destructor, uses array delete operation on wrapped pointer.
232          */
233         ~auto_arrayptr() {
234             delete[] m_ptr;
235         }
236
237         /**
238          * Returns the wrapped pointer.
239          * @return the wrapped pointer
240          */
241         const T* get() const {
242             return m_ptr;
243         }
244
245         /**
246          * Returns the wrapped pointer and transfers ownership of it to the caller.
247          * @return the wrapped pointer
248          */
249         T* release() {
250             T* temp=m_ptr; m_ptr=nullptr; return temp;
251         }
252     };
253 };
254
255 #endif /* __xmltooling_unicode_h__ */