source: trunk/src/byteplex.c @ 179

Last change on this file since 179 was 179, checked in by lindanl, 11 years ago

Templated SIMD Library - initial version

File size: 22.0 KB
Line 
1/*  byteplex.c - Parallel byte stream module.
2    Copyright (c) 2008, Robert D. Cameron.
3    Licensed to the public under the Open Software License 3.0.
4    Licensed to International Characters, Inc., under the Academic
5    Free License 3.0.
6
7*/
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11#include <errno.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include "byteplex.h"
15#include "xml_error.h"
16#include "multiliteral.h"
17#include "bytelex.h"
18
19
20
21/*  Space for sentinels in bytescans of the pseudo-ASCII stream. */
22const int SENTINEL_PACKS = 1;
23
24
25
26template <CodeUnit_Base C>
27X8_Buffer<C>::X8_Buffer() : Byteplex() {
28        /* For 8-bit code units, the input buffer is a also used directly
29           as the pseudo-ASCII buffer; make sure that there is room for
30           sentinels. */
31        src_buffer = simd_new(BYTEPLEX_SIZE/PACKSIZE+SENTINEL_PACKS);
32        x8data = src_buffer;
33        // Set the sentinel for ScanToQuote,ScanWS in reading XML/text decls.
34        ((unsigned char *) x8data)[BYTEPLEX_SIZE] = Ord<C, '"'>::value;
35}
36
37
38template <CodeUnit_Base C>
39X8_Buffer<C>::~X8_Buffer() {
40  simd_delete((SIMD_type *) src_buffer);
41}
42
43U16_Buffer::U16_Buffer()
44        : Byteplex() {
45
46        src_buffer = simd_new((BYTEPLEX_SIZE/PACKSIZE)*2);
47        x16hi = simd_new(BYTEPLEX_SIZE/PACKSIZE);
48        x16lo = simd_new(BYTEPLEX_SIZE/PACKSIZE);
49        x8data = simd_new(BYTEPLEX_SIZE/PACKSIZE+SENTINEL_PACKS);
50        // Set the sentinel for ScanToQuote,ScanWS in reading XML/text decls.
51        ((unsigned char *) x8data)[BYTEPLEX_SIZE] = '"';
52}
53
54U16_Buffer::~U16_Buffer() {
55  simd_delete((SIMD_type *) x16hi);
56  simd_delete((SIMD_type *) x16lo);
57  simd_delete((SIMD_type *) x8data);
58  simd_delete((SIMD_type *) src_buffer);
59}
60
61U16LE_Buffer::U16LE_Buffer()
62        : U16_Buffer() {
63}
64
65U16BE_Buffer::U16BE_Buffer()
66        : U16_Buffer() {
67}
68
69U32_Buffer::U32_Buffer()
70        : Byteplex() {
71
72        src_buffer = simd_new((BYTEPLEX_SIZE/PACKSIZE)*4);
73        x32hh = simd_new(BYTEPLEX_SIZE/PACKSIZE);
74        x32hl = simd_new(BYTEPLEX_SIZE/PACKSIZE);
75        x32lh = simd_new(BYTEPLEX_SIZE/PACKSIZE);
76        x32ll = simd_new(BYTEPLEX_SIZE/PACKSIZE);
77        x8data = simd_new(BYTEPLEX_SIZE/PACKSIZE+SENTINEL_PACKS);
78        x8data = simd_new(BYTEPLEX_SIZE/PACKSIZE+SENTINEL_PACKS);
79        // Set the sentinel for ScanToQuote,ScanWS in reading XML/text decls.
80        ((unsigned char *) x8data)[BYTEPLEX_SIZE] = '"';
81}
82
83U32_Buffer::~U32_Buffer() {
84  simd_delete((SIMD_type *) x32hh);
85  simd_delete((SIMD_type *) x32hl);
86  simd_delete((SIMD_type *) x32lh);
87  simd_delete((SIMD_type *) x32ll);
88  simd_delete((SIMD_type *) x8data);
89  simd_delete((SIMD_type *) src_buffer);
90}
91
92U32LE_Buffer::U32LE_Buffer()
93        : U32_Buffer() {
94}
95
96U32BE_Buffer::U32BE_Buffer()
97        : U32_Buffer() {
98}
99
100U32_2143_Buffer::U32_2143_Buffer()
101        : U32_Buffer() {
102}
103
104U32_3412_Buffer::U32_3412_Buffer()
105        : U32_Buffer() {
106}
107
108
109/* Byteplex methods.
110
111   No byteplexing is required for 8-bit code units; byteplex methods are no-ops.
112
113*/
114
115template <CodeUnit_Base C>
116void X8_Buffer<C>::DoByteplex() {
117        x8data = src_buffer;
118}
119
120
121void DoDuplex(BytePack * src_data, int packs_in_buffer,
122                                         BytePack * p0, BytePack * p1) {
123
124        for (int pk = 0; pk < packs_in_buffer; pk++) {
125                BytePack s0 = src_data[2*pk];
126                BytePack s1 = src_data[2*pk+1];
127#if (BYTE_ORDER == LITTLE_ENDIAN)
128#ifdef TEMPLATED_SIMD_LIB
129                p0[pk] = simd_pack<16,l,l>(s1, s0);
130                p1[pk] = simd_pack<16,h,h>(s1, s0);
131#endif
132#ifndef TEMPLATED_SIMD_LIB
133                p0[pk] = simd_pack_16_ll(s1, s0);
134                p1[pk] = simd_pack_16_hh(s1, s0);
135#endif
136#endif
137#if (BYTE_ORDER == BIG_ENDIAN)
138#ifdef TEMPLATED_SIMD_LIB
139                p0[pk] = simd_pack<16,l,l>(s0, s1);
140                p1[pk] = simd_pack<16,h,h>(s0, s1);
141#endif
142#ifndef TEMPLATED_SIMD_LIB
143                p0[pk] = simd_pack_16_ll(s0, s1);
144                p1[pk] = simd_pack_16_hh(s0, s1);
145#endif
146#endif
147        }
148}
149                                         
150void U16LE_Buffer::DoByteplex() {
151        DoDuplex(src_buffer, packs_in_buffer, x16lo, x16hi);
152}
153
154void U16BE_Buffer::DoByteplex() {
155        DoDuplex(src_buffer, packs_in_buffer, x16hi, x16lo);
156}
157
158void DoQuadplex(BytePack * src_data, int packs_in_buffer,
159                                BytePack * p0, BytePack * p1, BytePack * p2, BytePack * p3) {
160
161        for (int pk = 0; pk < packs_in_buffer; pk++) {
162                BytePack s0 = src_data[4*pk];
163                BytePack s1 = src_data[4*pk+1];
164                BytePack s2 = src_data[4*pk+2];
165                BytePack s3 = src_data[4*pk+3];
166#if (BYTE_ORDER == LITTLE_ENDIAN)
167#ifdef TEMPLATED_SIMD_LIB
168                BytePack p02_0 = simd_pack<16,l,l>(s1, s0);
169                BytePack p13_0 = simd_pack<16,h,h>(s1, s0);
170                BytePack p02_1 = simd_pack<16,l,l>(s3, s2);
171                BytePack p13_1 = simd_pack<16,h,h>(s3, s2);
172                p0[pk] = simd_pack<16,l,l>(p02_1, p02_0);
173                p1[pk] = simd_pack<16,l,l>(p13_1, p13_0);
174                p2[pk] = simd_pack<16,h,h>(p02_1, p02_0);
175                p3[pk] = simd_pack<16,h,h>(p13_1, p13_0);
176#endif
177#ifndef TEMPLATED_SIMD_LIB
178                BytePack p02_0 = simd_pack_16_ll(s1, s0);
179                BytePack p13_0 = simd_pack_16_hh(s1, s0);
180                BytePack p02_1 = simd_pack_16_ll(s3, s2);
181                BytePack p13_1 = simd_pack_16_hh(s3, s2);
182                p0[pk] = simd_pack_16_ll(p02_1, p02_0);
183                p1[pk] = simd_pack_16_ll(p13_1, p13_0);
184                p2[pk] = simd_pack_16_hh(p02_1, p02_0);
185                p3[pk] = simd_pack_16_hh(p13_1, p13_0);
186#endif
187#endif
188#if (BYTE_ORDER == BIG_ENDIAN)
189#ifdef TEMPLATED_SIMD_LIB
190                BytePack p02_0 = simd_pack<16,h,h>(s0, s1);
191                BytePack p13_0 = simd_pack<16,l,l>(s0, s1);
192                BytePack p02_1 = simd_pack<16,h,h>(s2, s3);
193                BytePack p13_1 = simd_pack<16,l,l>(s2, s3);
194                p0[pk] = simd_pack<16,h,h>(p02_0, p02_1);
195                p1[pk] = simd_pack<16,h,h>(p13_0, p13_1);
196                p2[pk] = simd_pack<16,l,l>(p02_0, p02_1);
197                p3[pk] = simd_pack<16,l,l>(p13_0, p13_1);
198#endif
199#ifndef TEMPLATED_SIMD_LIB
200                BytePack p02_0 = simd_pack_16_hh(s0, s1);
201                BytePack p13_0 = simd_pack_16_ll(s0, s1);
202                BytePack p02_1 = simd_pack_16_hh(s2, s3);
203                BytePack p13_1 = simd_pack_16_ll(s2, s3);
204                p0[pk] = simd_pack_16_hh(p02_0, p02_1);
205                p1[pk] = simd_pack_16_hh(p13_0, p13_1);
206                p2[pk] = simd_pack_16_ll(p02_0, p02_1);
207                p3[pk] = simd_pack_16_ll(p13_0, p13_1);
208#endif
209#endif
210        }
211}
212
213void U32LE_Buffer::DoByteplex() {
214        DoQuadplex(src_buffer, packs_in_buffer, x32ll, x32lh, x32hl, x32hh);
215}
216
217void U32BE_Buffer::DoByteplex() {
218        DoQuadplex(src_buffer, packs_in_buffer, x32hh, x32hl, x32lh, x32ll);
219}
220
221void U32_2143_Buffer::DoByteplex() {
222        DoQuadplex(src_buffer, packs_in_buffer, x32hl, x32hh, x32ll, x32lh);
223}
224
225void U32_3412_Buffer::DoByteplex() {
226        DoQuadplex(src_buffer, packs_in_buffer, x32lh, x32ll, x32hh, x32hl);
227}
228
229
230/* Pseudo-ASCII stream methods */
231
232template <CodeUnit_Base C>
233void X8_Buffer<C>::PreparePseudoASCII_Stream() {
234        x8data = src_buffer;
235}
236
237void U16_Buffer::PreparePseudoASCII_Stream() {
238        for (int pk = 0; pk < packs_in_buffer; pk++) {
239#ifdef TEMPLATED_SIMD_LIB
240                x8data[pk] = simd_or(x16lo[pk], simd_andc(simd_const<8>(0x80), 
241                                               simd_eq<8>(x16hi[pk], simd_const<8>(0))));
242#endif
243#ifndef TEMPLATED_SIMD_LIB
244                x8data[pk] = simd_or(x16lo[pk], simd_andc(simd_const_8(0x80), 
245                                               simd_eq_8(x16hi[pk], simd_const_8(0))));
246#endif
247        }
248}
249
250void U32_Buffer::PreparePseudoASCII_Stream() {
251        for (int pk = 0; pk < packs_in_buffer; pk++) {
252                BytePack hi = simd_or(simd_or(x32hh[pk], x32hl[pk]), x32lh[pk]);
253#ifdef TEMPLATED_SIMD_LIB
254                x8data[pk] = simd_or(x32ll[pk], simd_andc(simd_const<8>(0x80), 
255                                               simd_eq<8>(hi, simd_const<8>(0))));
256#endif
257#ifndef TEMPLATED_SIMD_LIB
258                x8data[pk] = simd_or(x32ll[pk], simd_andc(simd_const_8(0x80), 
259                                               simd_eq_8(hi, simd_const_8(0))));
260#endif
261        }
262}
263
264
265int Byteplex::CopyAndFill(unsigned char * bytes_to_copy, int lgth, int bytes_to_read) {
266        memcpy(src_buffer, bytes_to_copy, lgth);
267#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == FILE_READING)
268        code_clocker->cc_start_interval();
269#endif
270        unsigned char * end_ptr = &((unsigned char *)src_buffer)[lgth];
271        int bytes_read = fread(end_ptr, 1, bytes_to_read, infile);
272        if (bytes_read < bytes_to_read) end_ptr[bytes_read] = '\0'; /* sentinel */
273#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == FILE_READING)
274        code_clocker->cc_end_interval(bytes_read);
275#endif
276        return bytes_read;
277}
278
279void Byteplex::Set_limits(int units) {
280        units_in_buffer = units;
281        packs_in_buffer = (units_in_buffer + PACKSIZE -1)/PACKSIZE;
282        //buffer_limit_pos = min(units_in_buffer, BUFFER_SIZE);
283}
284
285template <CodeUnit_Base C>
286void X8_Buffer<C>::InitializeBuffer(unsigned char * src, int lgth){     
287        int byte_advance = BYTEPLEX_SIZE - lgth;       
288        int bytes_read = CopyAndFill(src, lgth, byte_advance);
289        Set_limits(bytes_read + lgth);
290}
291
292void U16_Buffer::InitializeBuffer(unsigned char * src, int lgth){       
293        int byte_advance = BYTEPLEX_SIZE * 2 - lgth;   
294        int bytes_read = CopyAndFill(src, lgth, byte_advance);
295        if (bytes_read % 2 != 0) {
296                IncompleteCodeUnitError();
297        }
298        Set_limits((bytes_read + lgth)/2);
299}
300
301void U32_Buffer::InitializeBuffer(unsigned char * src, int lgth){       
302        int byte_advance = BYTEPLEX_SIZE * 4 - lgth;   
303        int bytes_read = CopyAndFill(src, lgth, byte_advance);
304        if (bytes_read % 4 != 0) {
305                IncompleteCodeUnitError();
306        }
307        Set_limits((bytes_read + lgth)/4);
308}
309
310
311
312template <CodeUnit_Base C>
313void X8_Buffer<C>::AdvanceInputBuffer(int advance_amt){ 
314        int bytes_to_keep = units_in_buffer - advance_amt;     
315        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt],
316                                        bytes_to_keep, advance_amt);
317        Set_limits(bytes_read + bytes_to_keep);
318}
319
320void U16_Buffer::AdvanceInputBuffer(int advance_amt){   
321        int bytes_to_keep = (units_in_buffer - advance_amt)*2; 
322        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt*2],
323                                        bytes_to_keep, advance_amt*2);
324        if (bytes_read % 2 != 0) {
325                IncompleteCodeUnitError();
326        }
327        Set_limits((bytes_read + bytes_to_keep)/2);
328}
329
330void U32_Buffer::AdvanceInputBuffer(int advance_amt){   
331        int bytes_to_keep = (units_in_buffer - advance_amt)*4; 
332        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt*4],
333                                        bytes_to_keep, advance_amt*4);
334        if (bytes_read % 4 != 0) {
335                IncompleteCodeUnitError();
336        }
337        Set_limits((bytes_read + bytes_to_keep)/4);
338}
339
340void U16_Buffer::Validate_UTF16() {
341        BytePack surrogate_select;
342        BytePack hi_surrogate;
343        BytePack lo_surrogate;
344#ifdef TEMPLATED_SIMD_LIB
345        BytePack hi_surrogate_pending = simd_const<8>(0);
346#endif
347#ifndef TEMPLATED_SIMD_LIB
348        BytePack hi_surrogate_pending = simd_const_8(0);
349#endif
350        BytePack surrogate_scope;
351        BytePack u16_surrogate_error;
352//      BytePack u16_surrogate_accum = simd_const<8>(0);
353//      BytePack u16_FFFE_FFFF_accum = simd_const<8>(0);
354        BytePack u16_FFFE_FFFF;
355        for (int pk = 0; pk < packs_in_buffer; pk++) {
356                /* UTF-16 code units in the range D800-DBFF and DC00-DFFF are
357                   reserved for the first and second elements, respectively
358                   of surrogate pairs.  Validation requires that these values
359                   only occur in well-formed pairs. */
360#ifdef TEMPLATED_SIMD_LIB
361                surrogate_select = simd_and(x16hi[pk], simd_const<8>(0xDC));
362                hi_surrogate = simd_eq<8>(surrogate_select, simd_const<8>(0xD8));
363                lo_surrogate = simd_eq<8>(surrogate_select, simd_const<8>(0xDC));
364                surrogate_scope = simd_or(hi_surrogate_pending,
365                                          sisd_sfli(hi_surrogate, 8));
366                                         
367                u16_surrogate_error = simd_xor(surrogate_scope, lo_surrogate);
368                hi_surrogate_pending = sisd_sbli(hi_surrogate, 8 * (PACKSIZE-1));
369                /* The values FFFE and FFFF are excluded. */
370                u16_FFFE_FFFF = simd_eq<8>(simd_and(x16hi[pk],
371                                                   simd_or(x16lo[pk], simd_const<8>(1))),
372                                          simd_const<8>(0xFF));
373#endif
374#ifndef TEMPLATED_SIMD_LIB
375                surrogate_select = simd_and(x16hi[pk], simd_const_8(0xDC));
376                hi_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xD8));
377                lo_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xDC));
378                surrogate_scope = simd_or(hi_surrogate_pending,
379                                          sisd_sfli(hi_surrogate, 8));
380                                         
381                u16_surrogate_error = simd_xor(surrogate_scope, lo_surrogate);
382                hi_surrogate_pending = sisd_sbli(hi_surrogate, 8 * (PACKSIZE-1));
383                /* The values FFFE and FFFF are excluded. */
384                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
385                                                   simd_or(x16lo[pk], simd_const_8(1))),
386                                          simd_const_8(0xFF));
387#endif
388//              u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
389                u16_surrogate_error = simd_or(u16_surrogate_error, u16_FFFE_FFFF);
390       
391                if (bitblock_has_bit(u16_surrogate_error)) {
392                        CharSetValidationError("UTF-16 (relative position reported)",
393                                                pk * PACKSIZE + count_forward_zeroes(u16_surrogate_error)/8);
394                }
395        }
396};
397
398
399void U16_Buffer::Validate_UCS2() {
400#ifdef X16HILO_ACCESS
401        int packs = (buffer_units - 1)/PACKSIZE + 1;
402#ifdef TEMPLATED_SIMD_LIB
403        BytePack u16_surrogate_accum = simd_const<8>(0);
404        BytePack u16_FFFE_FFFF_accum = simd_const<8>(0);
405#endif
406#ifndef TEMPLATED_SIMD_LIB
407        BytePack u16_surrogate_accum = simd_const_8(0);
408        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
409#endif
410        BytePack u16_FFFE_FFFF;
411        for (int pk = 0; pk < packs; pk++) {
412                /* The high byte of UCS-2 code units cannot be in the range D8-DF.
413                   This corresponds to the D800-DFFF range of illegal codepoints
414                   reserved for UTF-16 surrogate pairs. Accumulate the results.
415                   To check, 0x20 is added to each such octet, mapping the D8-DF
416                   range to F8-FF and wrapping E0-FF values around.  The max value
417                   is then accumulated.  */ 
418#ifdef TEMPLATED_SIMD_LIB
419                u16_surrogate_accum =
420                        simd_max_8(u16_surrogate_accum, simd_add<8>(x16hi[pk], simd_const<8>(0x20)));
421                /* The values FFFE and FFFF are excluded. */
422                u16_FFFE_FFFF = simd_eq<8>(simd_and(x16hi[pk],
423                                                   simd_or(x16lo[pk], simd_const<8>(1))), simd_const<8>(0xFF));
424                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
425#endif
426#ifndef TEMPLATED_SIMD_LIB
427                u16_surrogate_accum =
428                        simd_max_8(u16_surrogate_accum, simd_add_8(x16hi[pk], simd_const_8(0x20)));
429                /* The values FFFE and FFFF are excluded. */
430                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
431                                                   simd_or(x16lo[pk], simd_const_8(1))), simd_const_8(0xFF));
432                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
433#endif
434        }
435#ifdef TEMPLATED_SIMD_LIB
436        u16_surrogate_accum = simd_eq<8>(simd_or(u16_surrogate_accum, simd_const<8>(0x07)),
437                                        simd_const<8>(0xFF));
438#endif
439#ifndef TEMPLATED_SIMD_LIB
440        u16_surrogate_accum = simd_eq_8(simd_or(u16_surrogate_accum, simd_const_8(0x07)),
441                                        simd_const_8(0xFF));
442#endif
443
444        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
445                CharSetValidationError("UCS-2");
446        }
447#endif
448#ifndef X16HILO_ACCESS
449        printf("UCS_2_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
450#endif
451};
452
453
454void U32_Buffer::Validate_UTF32() {
455#ifdef X32BYTEPLEX_ACCESS
456        int packs = (buffer_units - 1)/PACKSIZE + 1;
457#ifdef TEMPLATED_SIMD_LIB
458        BytePack u32hh_accum = simd_const<8>(0);
459        BytePack u32hl_accum = simd_const<8>(0);
460        BytePack u32_surrogate_accum = simd_const<8>(0);
461        BytePack u32_FFFE_FFFF_accum = simd_const<8>(0);
462#endif
463#ifndef TEMPLATED_SIMD_LIB
464        BytePack u32hh_accum = simd_const_8(0);
465        BytePack u32hl_accum = simd_const_8(0);
466        BytePack u32_surrogate_accum = simd_const_8(0);
467        BytePack u32_FFFE_FFFF_accum = simd_const_8(0);
468#endif
469        BytePack u32_BMP_select;
470        BytePack u32l_FFFE_FFFF;
471        for (int pk = 0; pk < packs; pk++) {
472                /* There can be no bits set in the high octet; "or" together
473                   all octet values to check for any bit set. */
474                u32hh_accum = simd_or(u32hh_accum, x32hh[pk]);
475                /* The second octet has a max value of 0x10, corresponding to the
476                   maximum Unicode code point value of 0x10FFFF.  Accumulate the
477                   maximum of all u32hl values observed. */ 
478                u32hl_accum = simd_max_8(u32hl_accum, x32hl[pk]);
479                /* The third octet cannot be in the range D8-DF if the second octet
480                   is 0.  This corresponds to the D800-DFFF range of illegal codepoints
481                   reserved for UTF-16 surrogate pairs. Accumulate the results.
482                   To check, 0x20 is added to each such octet, mapping the D8-DF
483                   range to F8-FF and wrapping E0-FF values around.  The max value
484                   is then accumulated.  */
485#ifdef TEMPLATED_SIMD_LIB
486                u32_BMP_select = simd_eq<8>(x32hl[pk], simd_const<8>(0));
487                u32_surrogate_accum = simd_max_8(u32_surrogate_accum, 
488                                                                 simd_and(u32_BMP_select, simd_add<8>(x32lh[pk], simd_const<8>(0x20))));
489                /* The low two octets cannot have the value FFFE or FFFF if
490                   we're in the BMP (second octet is 0). */
491                u32l_FFFE_FFFF = simd_eq<8>(simd_and(x32lh[pk],
492                                                    simd_or(x32ll[pk], simd_const<8>(1))),simd_const<8>(0xFF));
493                u32_FFFE_FFFF_accum = simd_or(u32_FFFE_FFFF_accum,
494                                              simd_and(u32_BMP_select, u32l_FFFE_FFFF));
495#endif
496#ifndef TEMPLATED_SIMD_LIB
497                u32_BMP_select = simd_eq_8(x32hl[pk], simd_const_8(0));
498                u32_surrogate_accum = simd_max_8(u32_surrogate_accum, 
499                                                                 simd_and(u32_BMP_select, simd_add<8>(x32lh[pk], simd_const_8(0x20))));
500                /* The low two octets cannot have the value FFFE or FFFF if
501                   we're in the BMP (second octet is 0). */
502                u32l_FFFE_FFFF = simd_eq_8(simd_and(x32lh[pk],
503                                                    simd_or(x32ll[pk], simd_const_8(1))),simd_const_8(0xFF));
504                u32_FFFE_FFFF_accum = simd_or(u32_FFFE_FFFF_accum,
505                                              simd_and(u32_BMP_select, u32l_FFFE_FFFF));
506#endif
507        }
508#ifdef TEMPLATED_SIMD_LIB
509        u32hl_accum = simd_gt_8(u32hl_accum, simd_const<8>(0x10));
510        u32_surrogate_accum = simd_eq<8>(simd_or(u32_surrogate_accum, simd_const<8>(0x07)),
511                                        simd_const<8>(0xFF));
512#endif
513#ifndef TEMPLATED_SIMD_LIB
514        u32hl_accum = simd_gt_8(u32hl_accum, simd_const_8(0x10));
515        u32_surrogate_accum = simd_eq_8(simd_or(u32_surrogate_accum, simd_const_8(0x07)),
516                                        simd_const_8(0xFF));
517#endif
518        if (bitblock_has_bit(simd_or(simd_or(u32hh_accum, u32hl_accum),
519                                         simd_or(u32_surrogate_accum, u32_FFFE_FFFF_accum)))) {
520                CharSetValidationError("UTF-32");
521        }
522#endif
523#ifndef X32BYTEPLEX_ACCESS
524        printf("UTF_32_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
525#endif
526};
527
528Byteplex * Byteplex::ByteplexFactory(Entity_Info * e) {
529        Byteplex * b;
530        if (likely(e->code_unit_size == SingleByte)) {
531                if (likely(e->code_unit_base == ASCII)) 
532                        b = new X8_Buffer<ASCII>();
533                else b = new X8_Buffer<EBCDIC>();
534        }
535        else if (likely(e->code_unit_size == DoubleByte)) {
536                if (likely(e->byte_order == BigEndian))
537                        b = new U16BE_Buffer();
538                else b = new U16LE_Buffer();
539        }
540        else switch (e->byte_order) {
541                case BigEndian: b = new U32BE_Buffer(); break;
542                case LittleEndian: b = new U32LE_Buffer(); break;
543                case Unusual_2143: b = new U32_2143_Buffer(); break;
544                case Unusual_3412: b = new U32_3412_Buffer(); break;
545        }       
546        return b;
547}
548
549Byteplex * Byteplex::ByteplexFactory(Entity_Info * e, FILE * inputfile) {
550        Byteplex * b = ByteplexFactory(e);
551        b->infile = inputfile;
552        return b;
553}
554       
555Byteplex * Byteplex::ByteplexFactory(Entity_Info * e, unsigned char * buffer_bytes, int buffer_size) {
556        Byteplex * b = ByteplexFactory(e);
557        memcpy(b->src_buffer, buffer_bytes, buffer_size);
558//printf("buffer_bytes = %s\n", buffer_bytes);
559        b->units_in_buffer = buffer_size / e->code_unit_size;
560        b->packs_in_buffer = (b->units_in_buffer + PACKSIZE -1)/PACKSIZE;
561        return b;
562}
563
564template <>
565int X8_Buffer<EBCDIC>::UTF8_Length(int name_pos, int lgth){
566        int u8_lgth = 0;
567        for (int i = name_pos; i < name_pos+lgth; i++) {
568                u8_lgth += /*TEMPORARY - NEED TO USE A TABLE FOR LOOKUP*/ 2;
569        }
570        return u8_lgth;
571}
572
573template <>
574int X8_Buffer<ASCII>::UTF8_Length(int name_pos, int lgth){
575        int u8_lgth = 0;
576        for (int i = name_pos; i < name_pos+lgth; i++) {
577                if (((unsigned char *)x8data)[i] < 0x80) u8_lgth += 1;
578                else u8_lgth += /*TEMPORARY - NEED TO USE A TABLE FOR LOOKUP*/ 1;
579        }
580        return u8_lgth;
581}
582
583int UTF8_Buffer::UTF8_Length(int name_pos, int lgth){
584        return lgth;
585}
586
587int U16_Buffer::UTF8_Length(int name_pos, int lgth){
588        int u8_lgth = 0;
589        for (int i = name_pos; i < name_pos+lgth; i++) {
590                if (((unsigned char *)x8data)[i] < 0x80) u8_lgth += 1;
591                else if(((unsigned char *)x16hi)[i]<=0x7 || (((unsigned char *)x16hi)[i] >= 0xD8 &&((unsigned char *)x16hi)[i]<= 0xDF))
592                        u8_lgth += 2;
593                else
594                        u8_lgth += 3;
595        }
596        return u8_lgth;
597}
598
599int U32_Buffer::UTF8_Length(int name_pos, int lgth){
600        int u8_lgth = 0;
601        unsigned char * u32hl = (unsigned char *) x32hl;
602        unsigned char * u32lh = (unsigned char *) x32lh;
603        for (int i = name_pos; i < name_pos+lgth; i++) {
604                if (((unsigned char *)x8data)[i] < 0x80)  {
605                        u8_lgth += 1;
606                }
607                else if(u32hl[i] > 0)
608                        u8_lgth += 4;
609                else if(u32lh[i]<=0x7)
610                        u8_lgth += 2;
611                else
612                        u8_lgth += 3;
613        }
614        return u8_lgth;
615}
616
617template <>
618void X8_Buffer<ASCII>::to_UTF8(int name_pos, int lgth, char * u8_ptr){
619        memcpy(u8_ptr, &((char *)x8data)[name_pos], lgth);
620        u8_ptr[lgth] = '\0';
621//      u8_ptr = copy_name(&((char *)x8data)[name_pos], lgth);
622}
623
624template <>
625void X8_Buffer<EBCDIC>::to_UTF8(int name_pos, int lgth, char * u8_ptr){
626       
627}
628void U16_Buffer::to_UTF8(int name_pos, int lgth, char * u8_ptr){
629        int u8_lgth = 0;
630        unsigned char * u16h = (unsigned char *) x16hi;
631        unsigned char * u16l = (unsigned char *) x16lo;
632        for (int i = name_pos; i < name_pos+lgth; i++) {
633                if (((unsigned char *)x8data)[i] < 0x80) {
634                        u8_ptr[u8_lgth] = ((unsigned char *)x8data)[i];
635                        u8_lgth += 1;
636                }
637                else if (u16h[i]<=0x7) {
638                        u8_ptr[u8_lgth] = 0xC0 + (u16h[i] << 2) + (u16l[i] >> 6);
639                        u8_ptr[u8_lgth+1] = 0x80 + (u16l[i] & 0x3F);
640                        u8_lgth += 2;
641                }
642                else if ((u16h[i] >= 0xD8) && (u16h[i]<= 0xDB)){
643                        char temp =  ((u16h[i] & 0x03) << 2) + (u16l[i] >> 6) + 1;
644                        u8_ptr[u8_lgth] = 0xF0 + (temp >> 2);
645                        u8_ptr[u8_lgth+1] = 0x80 + ((temp & 0x03) << 4) + ((u16l[i] & 0x3F) >> 2);
646                        u8_ptr[u8_lgth+2] = 0x80 + ((u16l[i] & 0x03) << 4) + ((u16h[i+1] & 0x03) << 2) + (u16l[i+1] >> 6);
647                        u8_ptr[u8_lgth+3] = 0x80 + (u16l[i+1] & 0x3F);
648                        i++;
649                        u8_lgth += 4;
650                }
651                else{
652                        u8_ptr[u8_lgth] = 0xE0 + (u16h[i] >> 4);
653                        u8_ptr[u8_lgth+1] = 0x80 + ((u16h[i] & 0x0F) << 2) + (u16l[i] >> 6);
654                        u8_ptr[u8_lgth+2] = 0x80 + (u16l[i] & 0x3F);
655                        u8_lgth += 3;
656                }
657        }
658        u8_ptr[u8_lgth] = '\0';
659}
660
661
662
663void U32_Buffer::to_UTF8(int name_pos, int lgth, char * u8_ptr){
664        int u8_lgth = 0;
665        unsigned char * u32hl = (unsigned char *) x32hl;
666        unsigned char * u32lh = (unsigned char *) x32lh;
667        unsigned char * u32ll = (unsigned char *) x32ll;
668        for (int i = name_pos; i < name_pos+lgth; i++) {
669                if (((unsigned char *)x8data)[i] < 0x80)  {
670                        u8_ptr[u8_lgth] = ((unsigned char *)x8data)[i];
671                        u8_lgth += 1;
672                }
673                else if(u32hl[i] > 0) {
674                        u8_ptr[u8_lgth] = 0xF0 + (u32hl[i] >> 2);
675                        u8_ptr[u8_lgth+1] = 0x80 + ((u32hl[i] & 0x03) << 4) + (u32lh[i] >> 4);
676                        u8_ptr[u8_lgth+2] = 0x80 + ((u32lh[i] & 0x0F) << 2) + (u32ll[i] >> 6);
677                        u8_ptr[u8_lgth+3] = 0x80 + (u32ll[i] & 0x3F);           
678                        u8_lgth += 4;
679                }
680                else if(u32lh[i]<=0x7) {
681                        u8_ptr[u8_lgth] = 0xC0 + (u32lh[i] << 2) + (u32ll[i] >> 6);
682                        u8_ptr[u8_lgth+1] = 0x80 + (u32ll[i] & 0x3F);
683                        u8_lgth += 2;
684                }
685                else {
686                        u8_ptr[u8_lgth] = 0xE0 + (u32lh[i] >> 4);
687                        u8_ptr[u8_lgth+1] = 0x80 + ((u32lh[i] & 0x0F) << 2) + (u32ll[i] >> 6);
688                        u8_ptr[u8_lgth+2] = 0x80 + (u32ll[i] & 0x3F);
689                        u8_lgth += 3;
690                }
691        }
692        u8_ptr[u8_lgth] = '\0';
693}
694
695
Note: See TracBrowser for help on using the repository browser.