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

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

Fix imports in icXML modified Xerces files

File size: 7.3 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
130
131XMLSize_t
132XMLUTF16Transcoder::transcodeTo(const   XMLCh* const    srcData
133                                                                , const XMLSize_t       srcCount
134                                                                ,       XMLByte* const  toFill
135                                                                , const XMLSize_t       maxBytes
136                                                                ,       XMLSize_t&      charsEaten
137                                                                , const UnRepOpts)
138{
139        //
140        //  Calculate the max chars we can do here. Its the lesser of the
141        //  chars that we can fit into the output buffer, and the source
142        //  chars available.
143        //
144        const XMLSize_t maxOutChars = maxBytes / sizeof(UTF16Ch);
145        const XMLSize_t countToDo = srcCount < maxOutChars ? srcCount : maxOutChars;
146
147        //
148        //  Get a pointer tot he output buffer in the UTF-16 character format
149        //  that we need to work with. And get a mutable pointer to the source
150        //  character buffer.
151        //
152        UTF16Ch*        outPtr = (UTF16Ch*)toFill;
153        const XMLCh*    srcPtr = srcData;
154
155        //
156        //  If the target format is swapped from our native format, then handle
157        //  it one way, else handle it another.
158        //
159        if (fSwapped)
160        {
161                //
162                //  And then do the swapping loop for the count we precalculated. Note
163                //  that this also handles size conversion as well if XMLCh is not the
164                //  same size as UTF16Ch.
165                //
166                for (XMLSize_t index = 0; index < countToDo; index++)
167                {
168                        // To avoid flakey compilers, use a temp
169                        const UTF16Ch tmpCh = UTF16Ch(*srcPtr++);
170                        *outPtr++ = BitOps::swapBytes(tmpCh);
171                }
172        }
173        else
174        {
175                //
176                //  If XMLCh and UTF16Ch are the same size, we can just do a fast
177                //  memory copy. Otherwise, we have to do a loop and downcast each
178                //  character into its new 16 bit storage.
179                //
180                if (sizeof(XMLCh) == sizeof(UTF16Ch))
181                {
182                        //  Notice we convert char count to byte count here!!!
183                        memcpy(toFill, srcData, countToDo * sizeof(UTF16Ch));
184                }
185                 else
186                {
187                        for (XMLSize_t index = 0; index < countToDo; index++)
188                                *outPtr++ = UTF16Ch(*srcPtr++);
189                }
190        }
191
192        // Set the chars eaten to the calculated number we ate
193        charsEaten = countToDo;
194
195        //Return the bytes we ate. Note we convert to a byte count here!
196        return countToDo * sizeof(UTF16Ch);
197}
198
199XMLSize_t
200XMLUTF16Transcoder::transcodeFrom( const XMLByte* const         srcData
201                                                                 , const XMLSize_t              srcCount
202                                                                 ,       XMLBuffer &            toFill )
203{
204        // Watch for pathological scenario. Shouldn't happen, but...
205        if (!srcCount)
206                return 0;
207
208        const XMLCh * const src = reinterpret_cast<const XMLCh*>(srcData);
209
210        if (fSwapped)
211        {
212                enum { SCALE = CONST_LOG_2(sizeof(BytePack)) };
213
214                const XMLSize_t count = srcCount >> (SCALE);
215                const BytePack * const in = reinterpret_cast<const BytePack *>(src);
216
217                XMLSize_t i;
218                for (i = 0; i < count; i += 2)
219                {
220                        BytePack a = bitblock::load_unaligned(&in[i]);
221                        BytePack b = bitblock::load_unaligned(&in[i + 1]);
222                        BytePack h = hsimd<16>::packh(b, a);
223                        BytePack l = hsimd<16>::packl(b, a);
224                        a = esimd<16>::mergel(h, l);
225                        b = esimd<16>::mergeh(h, l);
226                        toFill.append(reinterpret_cast<const XMLCh*>(&a), 8);
227                        toFill.append(reinterpret_cast<const XMLCh*>(&b), 8);
228                }
229                for (i <<= SCALE; i < srcCount; i++)
230                {
231                        toFill.append(BitOps::swapBytes((XMLUInt16)src[i]));
232                }
233        }
234        else
235        {
236                toFill.append(src, (srcCount >> 1));
237        }
238
239        // Return the bytes eaten
240        return srcCount;
241}
242
243bool XMLUTF16Transcoder::canTranscodeTo(const unsigned int)
244{
245        // We can handle anything
246        return true;
247}
248
249XERCES_CPP_NAMESPACE_END
250
Note: See TracBrowser for help on using the repository browser.