source: icXML/icXML-devel/src/icxercesc/util/XMLUTF16Transcoder.cpp

Last change on this file was 3103, checked in by cameron, 6 years ago

Initial imports for icXML v0.9

File size: 9.5 KB
Line 
1/*
2 * Unless required by applicable law or agreed to in writing, software
3 * distributed under the License is distributed on an "AS IS" BASIS,
4 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 * See the License for the specific language governing permissions and
6 * limitations under the License.
7 */
8
9
10// ---------------------------------------------------------------------------
11//  Includes
12// ---------------------------------------------------------------------------
13#include <xercesc/util/BitOps.hpp>
14#include <icxercesc/util/XMLUTF16Transcoder.hpp>
15#include <xercesc/util/TranscodingException.hpp>
16#include <string.h>
17
18#include <xercesc/util/XMLUniDefs.hpp>
19#include <icxercesc/internal/XMLReader.hpp>
20#include <icxercesc/internal/XMLScanner.hpp>
21#include <icxercesc/util/XMLString.hpp>
22
23#include <simd-lib/s2p.hpp>
24#include <simd-lib/p2s.hpp>
25#include <simd-lib/carryQ.hpp>
26#include <simd-lib/bitblock_iterator.hpp>
27
28#include <icxmlc/XMLMultiliteral.h>
29#include <icxmlc/PopCounter.hpp>
30#include <icxmlc/BitTracker.hpp>
31#include <icxmlc/XMLScanIterator.hpp>
32#include <icxmlc/XMLStreamIterator.hpp>
33#include <icxmlc/XMLLineColTracker.hpp>
34#include <icxmlc/XMLReferenceTable.hpp>
35#include <icxmlc/XMLConfig.hpp>
36
37XERCES_CPP_NAMESPACE_BEGIN
38
39
40
41// ---------------------------------------------------------------------------
42//  XMLUTF16Transcoder: Constructors and Destructor
43// ---------------------------------------------------------------------------
44XMLUTF16Transcoder::XMLUTF16Transcoder( const   XMLCh* const    encodingName
45                                                                                , const XMLSize_t       blockSize
46                                                                                , const bool            swapped
47                                                                                , MemoryManager* const  manager) :
48
49        XMLTranscoder(encodingName, blockSize, manager)
50        , fSwapped(swapped)
51{
52}
53
54
55XMLUTF16Transcoder::~XMLUTF16Transcoder()
56{
57}
58
59
60// ---------------------------------------------------------------------------
61//  XMLUTF16Transcoder: Implementation of the transcoder API
62// ---------------------------------------------------------------------------
63XMLSize_t
64XMLUTF16Transcoder::transcodeFrom(  const   XMLByte* const       srcData
65                                                                        , const XMLSize_t            srcCount
66                                                                        ,       XMLCh* const         toFill
67                                                                        , const XMLSize_t            maxChars
68                                                                        ,       XMLSize_t&           bytesEaten
69                                                                        ,       unsigned char* const charSizes)
70{
71        //
72        //  Calculate the max chars we can do here. Its the lesser of the
73        //  max output chars and the number of chars in the source.
74        //
75        const XMLSize_t srcChars = srcCount / sizeof(UTF16Ch);
76        const XMLSize_t countToDo = srcChars < maxChars ? srcChars : maxChars;
77
78        // Look at the source data as UTF16 chars
79        const UTF16Ch* asUTF16 = (const UTF16Ch*)srcData;
80
81        // And get a mutable pointer to the output
82        XMLCh* outPtr = toFill;
83
84        //
85        //  If its swapped, we have to do a char by char swap and cast. Else
86        //  we have to check whether our XMLCh and UTF16Ch types are the same
87        //  size or not. If so, we can optimize by just doing a buffer copy.
88        //
89        if (fSwapped)
90        {
91                //
92                //  And then do the swapping loop for the count we precalculated. Note
93                //  that this also handles size conversion as well if XMLCh is not the
94                //  same size as UTF16Ch.
95                //
96                for (XMLSize_t index = 0; index < countToDo; index++)
97                        *outPtr++ = BitOps::swapBytes(*asUTF16++);
98        }
99         else
100        {
101                //
102                //  If the XMLCh type is the same size as a UTF16 value on this
103                //  platform, then we can do just a buffer copy straight to the target
104                //  buffer since our source chars are UTF-16 chars. If its not, then
105                //  we still have to do a loop and assign each one, in order to
106                //  implicitly convert.
107                //
108                if (sizeof(XMLCh) == sizeof(UTF16Ch))
109                {
110                        //  Notice we convert char count to byte count here!!!
111                        memcpy(toFill, srcData, countToDo * sizeof(UTF16Ch));
112                }
113                 else
114                {
115                        for (XMLSize_t index = 0; index < countToDo; index++)
116                                *outPtr++ = XMLCh(*asUTF16++);
117                }
118        }
119
120        // Set the bytes eaten
121        bytesEaten = countToDo * sizeof(UTF16Ch);
122
123        // Set the character sizes to the fixed size
124        memset(charSizes, sizeof(UTF16Ch), countToDo);
125
126        // Return the chars we transcoded
127        return countToDo;
128}
129
130XMLSize_t
131XMLUTF16Transcoder::transcodeFrom(  const   XMLByte* const       srcData
132                                    , const XMLSize_t            srcCount
133                                    ,       XMLCh* const         toFill
134                                    , const XMLSize_t            maxChars
135                                    ,       XMLSize_t&           bytesEaten)
136{
137    //
138    //  Calculate the max chars we can do here. Its the lesser of the
139    //  max output chars and the number of chars in the source.
140    //
141    const XMLSize_t srcChars = srcCount / sizeof(UTF16Ch);
142    const XMLSize_t countToDo = srcChars < maxChars ? srcChars : maxChars;
143
144    // Look at the source data as UTF16 chars
145    const UTF16Ch* asUTF16 = (const UTF16Ch*)srcData;
146
147    // And get a mutable pointer to the output
148    XMLCh* outPtr = toFill;
149
150    //
151    //  If its swapped, we have to do a char by char swap and cast. Else
152    //  we have to check whether our XMLCh and UTF16Ch types are the same
153    //  size or not. If so, we can optimize by just doing a buffer copy.
154    //
155    if (fSwapped)
156    {
157        //
158        //  And then do the swapping loop for the count we precalculated. Note
159        //  that this also handles size conversion as well if XMLCh is not the
160        //  same size as UTF16Ch.
161        //
162        for (XMLSize_t index = 0; index < countToDo; index++)
163            *outPtr++ = BitOps::swapBytes(*asUTF16++);
164    }
165     else
166    {
167        //
168        //  If the XMLCh type is the same size as a UTF16 value on this
169        //  platform, then we can do just a buffer copy straight to the target
170        //  buffer since our source chars are UTF-16 chars. If its not, then
171        //  we still have to do a loop and assign each one, in order to
172        //  implicitly convert.
173        //
174        if (sizeof(XMLCh) == sizeof(UTF16Ch))
175        {
176            //  Notice we convert char count to byte count here!!!
177            memcpy(toFill, srcData, countToDo * sizeof(UTF16Ch));
178        }
179         else
180        {
181            for (XMLSize_t index = 0; index < countToDo; index++)
182                *outPtr++ = XMLCh(*asUTF16++);
183        }
184    }
185
186    // Set the bytes eaten
187    bytesEaten = countToDo * sizeof(UTF16Ch);
188
189    // Return the chars we transcoded
190    return countToDo;
191}
192
193
194
195XMLSize_t
196XMLUTF16Transcoder::transcodeTo(const   XMLCh* const    srcData
197                                                                , const XMLSize_t       srcCount
198                                                                ,       XMLByte* const  toFill
199                                                                , const XMLSize_t       maxBytes
200                                                                ,       XMLSize_t&      charsEaten
201                                                                , const UnRepOpts)
202{
203        //
204        //  Calculate the max chars we can do here. Its the lesser of the
205        //  chars that we can fit into the output buffer, and the source
206        //  chars available.
207        //
208        const XMLSize_t maxOutChars = maxBytes / sizeof(UTF16Ch);
209        const XMLSize_t countToDo = srcCount < maxOutChars ? srcCount : maxOutChars;
210
211        //
212        //  Get a pointer tot he output buffer in the UTF-16 character format
213        //  that we need to work with. And get a mutable pointer to the source
214        //  character buffer.
215        //
216        UTF16Ch*        outPtr = (UTF16Ch*)toFill;
217        const XMLCh*    srcPtr = srcData;
218
219        //
220        //  If the target format is swapped from our native format, then handle
221        //  it one way, else handle it another.
222        //
223        if (fSwapped)
224        {
225                //
226                //  And then do the swapping loop for the count we precalculated. Note
227                //  that this also handles size conversion as well if XMLCh is not the
228                //  same size as UTF16Ch.
229                //
230                for (XMLSize_t index = 0; index < countToDo; index++)
231                {
232                        // To avoid flakey compilers, use a temp
233                        const UTF16Ch tmpCh = UTF16Ch(*srcPtr++);
234                        *outPtr++ = BitOps::swapBytes(tmpCh);
235                }
236        }
237        else
238        {
239                //
240                //  If XMLCh and UTF16Ch are the same size, we can just do a fast
241                //  memory copy. Otherwise, we have to do a loop and downcast each
242                //  character into its new 16 bit storage.
243                //
244                if (sizeof(XMLCh) == sizeof(UTF16Ch))
245                {
246                        //  Notice we convert char count to byte count here!!!
247                        memcpy(toFill, srcData, countToDo * sizeof(UTF16Ch));
248                }
249                 else
250                {
251                        for (XMLSize_t index = 0; index < countToDo; index++)
252                                *outPtr++ = UTF16Ch(*srcPtr++);
253                }
254        }
255
256        // Set the chars eaten to the calculated number we ate
257        charsEaten = countToDo;
258
259        //Return the bytes we ate. Note we convert to a byte count here!
260        return countToDo * sizeof(UTF16Ch);
261}
262
263XMLSize_t
264XMLUTF16Transcoder::transcodeFrom( const XMLByte* const         srcData
265                                                                 , const XMLSize_t              srcCount
266                                                                 ,       XMLBuffer &            toFill )
267{
268        // Watch for pathological scenario. Shouldn't happen, but...
269        if (!srcCount)
270                return 0;
271
272        const XMLCh * const src = reinterpret_cast<const XMLCh*>(srcData);
273
274        if (fSwapped)
275        {
276        XMLSize_t len = (srcCount / sizeof(UTF16Ch));
277
278        toFill.ensureCapacity(len);
279        XMLCh * outPtr = &toFill[toFill.getLen()];
280        toFill.setLen(toFill.getLen() + len);
281
282
283        //
284        //  And then do the swapping loop for the count we precalculated. Note
285        //  that this also handles size conversion as well if XMLCh is not the
286        //  same size as UTF16Ch.
287        //
288        for (XMLSize_t index = 0; len--; index++)
289        {
290            // To avoid flakey compilers, use a temp
291            UTF16Ch tmpCh = static_cast<const UTF16Ch>(src[index]);
292            outPtr[index] = BitOps::swapBytes(tmpCh);
293        }
294
295
296        }
297        else
298        {
299        toFill.append(src, (srcCount / sizeof(UTF16Ch)));
300        }
301
302        // Return the bytes eaten
303        return srcCount;
304}
305
306bool XMLUTF16Transcoder::canTranscodeTo(const unsigned int)
307{
308        // We can handle anything
309        return true;
310}
311
312bool XMLUTF16Transcoder::isSwapped() const
313{
314    return fSwapped;
315}
316
317XERCES_CPP_NAMESPACE_END
318
Note: See TracBrowser for help on using the repository browser.