source: trunk/src/byteplex.c @ 178

Last change on this file since 178 was 178, checked in by cameron, 11 years ago

Removing excess inlines.

File size: 17.9 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
121inline void 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                p0[pk] = simd_pack_16_ll(s1, s0);
129                p1[pk] = simd_pack_16_hh(s1, s0);
130#endif
131#if (BYTE_ORDER == BIG_ENDIAN)
132                p0[pk] = simd_pack_16_hh(s0, s1);
133                p1[pk] = simd_pack_16_ll(s0, s1);
134#endif
135        }
136}
137
138void U16LE_Buffer::DoByteplex() {
139        DoDuplex(src_buffer, packs_in_buffer, x16lo, x16hi);
140}
141
142void U16BE_Buffer::DoByteplex() {
143        DoDuplex(src_buffer, packs_in_buffer, x16hi, x16lo);
144}
145
146void DoQuadplex(BytePack * src_data, int packs_in_buffer,
147                                BytePack * p0, BytePack * p1, BytePack * p2, BytePack * p3) {
148
149        for (int pk = 0; pk < packs_in_buffer; pk++) {
150                BytePack s0 = src_data[4*pk];
151                BytePack s1 = src_data[4*pk+1];
152                BytePack s2 = src_data[4*pk+2];
153                BytePack s3 = src_data[4*pk+3];
154#if (BYTE_ORDER == LITTLE_ENDIAN)
155                BytePack p02_0 = simd_pack_16_ll(s1, s0);
156                BytePack p13_0 = simd_pack_16_hh(s1, s0);
157                BytePack p02_1 = simd_pack_16_ll(s3, s2);
158                BytePack p13_1 = simd_pack_16_hh(s3, s2);
159                p0[pk] = simd_pack_16_ll(p02_1, p02_0);
160                p1[pk] = simd_pack_16_ll(p13_1, p13_0);
161                p2[pk] = simd_pack_16_hh(p02_1, p02_0);
162                p3[pk] = simd_pack_16_hh(p13_1, p13_0);
163#endif
164#if (BYTE_ORDER == BIG_ENDIAN)
165                BytePack p02_0 = simd_pack_16_hh(s0, s1);
166                BytePack p13_0 = simd_pack_16_ll(s0, s1);
167                BytePack p02_1 = simd_pack_16_hh(s2, s3);
168                BytePack p13_1 = simd_pack_16_ll(s2, s3);
169                p0[pk] = simd_pack_16_hh(p02_0, p02_1);
170                p1[pk] = simd_pack_16_hh(p13_0, p13_1);
171                p2[pk] = simd_pack_16_ll(p02_0, p02_1);
172                p3[pk] = simd_pack_16_ll(p13_0, p13_1);
173#endif
174        }
175}
176
177void U32LE_Buffer::DoByteplex() {
178        DoQuadplex(src_buffer, packs_in_buffer, x32ll, x32lh, x32hl, x32hh);
179}
180
181void U32BE_Buffer::DoByteplex() {
182        DoQuadplex(src_buffer, packs_in_buffer, x32hh, x32hl, x32lh, x32ll);
183}
184
185void U32_2143_Buffer::DoByteplex() {
186        DoQuadplex(src_buffer, packs_in_buffer, x32hl, x32hh, x32ll, x32lh);
187}
188
189void U32_3412_Buffer::DoByteplex() {
190        DoQuadplex(src_buffer, packs_in_buffer, x32lh, x32ll, x32hh, x32hl);
191}
192
193
194/* Pseudo-ASCII stream methods */
195
196template <CodeUnit_Base C>
197void X8_Buffer<C>::PreparePseudoASCII_Stream() {
198        x8data = src_buffer;
199}
200
201void U16_Buffer::PreparePseudoASCII_Stream() {
202        for (int pk = 0; pk < packs_in_buffer; pk++) {
203                x8data[pk] = simd_or(x16lo[pk],
204                                     simd_andc(simd_const_8(0x80),
205                                               simd_eq_8(x16hi[pk], simd_const_8(0))));
206        }
207}
208
209void U32_Buffer::PreparePseudoASCII_Stream() {
210        for (int pk = 0; pk < packs_in_buffer; pk++) {
211                BytePack hi = simd_or(simd_or(x32hh[pk], x32hl[pk]), x32lh[pk]);
212                x8data[pk] = simd_or(x32ll[pk],
213                                     simd_andc(simd_const_8(0x80),
214                                               simd_eq_8(hi, simd_const_8(0))));
215        }
216}
217
218
219int Byteplex::CopyAndFill(unsigned char * bytes_to_copy, int lgth, int bytes_to_read) {
220        memcpy(src_buffer, bytes_to_copy, lgth);
221#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == FILE_READING)
222        code_clocker->cc_start_interval();
223#endif
224        unsigned char * end_ptr = &((unsigned char *)src_buffer)[lgth];
225        int bytes_read = fread(end_ptr, 1, bytes_to_read, infile);
226        if (bytes_read < bytes_to_read) end_ptr[bytes_read] = '\0'; /* sentinel */
227#if defined(PAPI) and defined(CODE_CLOCKING) and (CODE_CLOCKING == FILE_READING)
228        code_clocker->cc_end_interval(bytes_read);
229#endif
230        return bytes_read;
231}
232
233void Byteplex::Set_limits(int units) {
234        units_in_buffer = units;
235        packs_in_buffer = (units_in_buffer + PACKSIZE -1)/PACKSIZE;
236        //buffer_limit_pos = min(units_in_buffer, BUFFER_SIZE);
237}
238
239template <CodeUnit_Base C>
240void X8_Buffer<C>::InitializeBuffer(unsigned char * src, int lgth){
241        int byte_advance = BYTEPLEX_SIZE - lgth;
242        int bytes_read = CopyAndFill(src, lgth, byte_advance);
243        Set_limits(bytes_read + lgth);
244}
245
246void U16_Buffer::InitializeBuffer(unsigned char * src, int lgth){
247        int byte_advance = BYTEPLEX_SIZE * 2 - lgth;
248        int bytes_read = CopyAndFill(src, lgth, byte_advance);
249        if (bytes_read % 2 != 0) {
250                IncompleteCodeUnitError();
251        }
252        Set_limits((bytes_read + lgth)/2);
253}
254
255void U32_Buffer::InitializeBuffer(unsigned char * src, int lgth){
256        int byte_advance = BYTEPLEX_SIZE * 4 - lgth;
257        int bytes_read = CopyAndFill(src, lgth, byte_advance);
258        if (bytes_read % 4 != 0) {
259                IncompleteCodeUnitError();
260        }
261        Set_limits((bytes_read + lgth)/4);
262}
263
264
265
266template <CodeUnit_Base C>
267void X8_Buffer<C>::AdvanceInputBuffer(int advance_amt){
268        int bytes_to_keep = units_in_buffer - advance_amt;
269        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt],
270                                        bytes_to_keep, advance_amt);
271        Set_limits(bytes_read + bytes_to_keep);
272}
273
274void U16_Buffer::AdvanceInputBuffer(int advance_amt){
275        int bytes_to_keep = (units_in_buffer - advance_amt)*2;
276        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt*2],
277                                        bytes_to_keep, advance_amt*2);
278        if (bytes_read % 2 != 0) {
279                IncompleteCodeUnitError();
280        }
281        Set_limits((bytes_read + bytes_to_keep)/2);
282}
283
284void U32_Buffer::AdvanceInputBuffer(int advance_amt){
285        int bytes_to_keep = (units_in_buffer - advance_amt)*4;
286        int bytes_read = CopyAndFill(&((unsigned char *)src_buffer)[advance_amt*4],
287                                        bytes_to_keep, advance_amt*4);
288        if (bytes_read % 4 != 0) {
289                IncompleteCodeUnitError();
290        }
291        Set_limits((bytes_read + bytes_to_keep)/4);
292}
293
294void U16_Buffer::Validate_UTF16() {
295        BytePack surrogate_select;
296        BytePack hi_surrogate;
297        BytePack lo_surrogate;
298        BytePack hi_surrogate_pending = simd_const_8(0);
299        BytePack surrogate_scope;
300        BytePack u16_surrogate_error;
301//      BytePack u16_surrogate_accum = simd_const_8(0);
302//      BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
303        BytePack u16_FFFE_FFFF;
304        for (int pk = 0; pk < packs_in_buffer; pk++) {
305                /* UTF-16 code units in the range D800-DBFF and DC00-DFFF are
306                   reserved for the first and second elements, respectively
307                   of surrogate pairs.  Validation requires that these values
308                   only occur in well-formed pairs. */
309                surrogate_select = simd_and(x16hi[pk], simd_const_8(0xDC));
310                hi_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xD8));
311                lo_surrogate = simd_eq_8(surrogate_select, simd_const_8(0xDC));
312                surrogate_scope = simd_or(hi_surrogate_pending,
313                                          sisd_sfli(hi_surrogate, 8));
314
315                u16_surrogate_error = simd_xor(surrogate_scope, lo_surrogate);
316                hi_surrogate_pending = sisd_sbli(hi_surrogate, 8 * (PACKSIZE-1));
317                /* The values FFFE and FFFF are excluded. */
318                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
319                                                   simd_or(x16lo[pk], simd_const_8(1))),
320                                          simd_const_8(0xFF));
321//              u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
322                u16_surrogate_error = simd_or(u16_surrogate_error, u16_FFFE_FFFF);
323
324                if (bitblock_has_bit(u16_surrogate_error)) {
325                        CharSetValidationError("UTF-16 (relative position reported)",
326                                                pk * PACKSIZE + count_forward_zeroes(u16_surrogate_error)/8);
327                }
328        }
329};
330
331
332void U16_Buffer::Validate_UCS2() {
333#ifdef X16HILO_ACCESS
334        int packs = (buffer_units - 1)/PACKSIZE + 1;
335        BytePack u16_surrogate_accum = simd_const_8(0);
336        BytePack u16_FFFE_FFFF_accum = simd_const_8(0);
337        BytePack u16_FFFE_FFFF;
338        for (int pk = 0; pk < packs; pk++) {
339                /* The high byte of UCS-2 code units cannot be in the range D8-DF.
340                   This corresponds to the D800-DFFF range of illegal codepoints
341                   reserved for UTF-16 surrogate pairs. Accumulate the results.
342                   To check, 0x20 is added to each such octet, mapping the D8-DF
343                   range to F8-FF and wrapping E0-FF values around.  The max value
344                   is then accumulated.  */
345                u16_surrogate_accum =
346                        simd_max_8(u16_surrogate_accum,
347                                   simd_add_8(x16hi[pk], simd_const_8(0x20)));
348                /* The values FFFE and FFFF are excluded. */
349                u16_FFFE_FFFF = simd_eq_8(simd_and(x16hi[pk],
350                                                   simd_or(x16lo[pk], simd_const_8(1))),
351                                          simd_const_8(0xFF));
352                u16_FFFE_FFFF_accum = simd_or(u16_FFFE_FFFF_accum, u16_FFFE_FFFF);
353        }
354        u16_surrogate_accum = simd_eq_8(simd_or(u16_surrogate_accum, simd_const_8(0x07)),
355                                        simd_const_8(0xFF));
356        if (bitblock_has_bit(simd_or(u16_surrogate_accum, u16_FFFE_FFFF_accum)))
357                CharSetValidationError("UCS-2");
358        }
359#endif
360#ifndef X16HILO_ACCESS
361        printf("UCS_2_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
362#endif
363};
364
365
366void U32_Buffer::Validate_UTF32() {
367#ifdef X32BYTEPLEX_ACCESS
368        int packs = (buffer_units - 1)/PACKSIZE + 1;
369        BytePack u32hh_accum = simd_const_8(0);
370        BytePack u32hl_accum = simd_const_8(0);
371        BytePack u32_surrogate_accum = simd_const_8(0);
372        BytePack u32_FFFE_FFFF_accum = simd_const_8(0);
373        BytePack u32_BMP_select;
374        BytePack u32l_FFFE_FFFF;
375        for (int pk = 0; pk < packs; pk++) {
376                /* There can be no bits set in the high octet; "or" together
377                   all octet values to check for any bit set. */
378                u32hh_accum = simd_or(u32hh_accum, x32hh[pk]);
379                /* The second octet has a max value of 0x10, corresponding to the
380                   maximum Unicode code point value of 0x10FFFF.  Accumulate the
381                   maximum of all u32hl values observed. */
382                u32hl_accum = simd_max_8(u32hl_accum, x32hl[pk]);
383                /* The third octet cannot be in the range D8-DF if the second octet
384                   is 0.  This corresponds to the D800-DFFF range of illegal codepoints
385                   reserved for UTF-16 surrogate pairs. Accumulate the results.
386                   To check, 0x20 is added to each such octet, mapping the D8-DF
387                   range to F8-FF and wrapping E0-FF values around.  The max value
388                   is then accumulated.  */
389                u32_BMP_select = simd_eq_8(x32hl[pk], simd_const_8(0));
390                u32_surrogate_accum =
391                        simd_max_8(u32_surrogate_accum,
392                                   simd_and(u32_BMP_select,
393                                            simd_add_8(x32lh[pk], simd_const_8(0x20))));
394                /* The low two octets cannot have the value FFFE or FFFF if
395                   we're in the BMP (second octet is 0). */
396                u32l_FFFE_FFFF = simd_eq_8(simd_and(x32lh[pk],
397                                                    simd_or(x32ll[pk], simd_const_8(1))),
398                                           simd_const_8(0xFF));
399                u32_FFFE_FFFF_accum = simd_or(u32_FFFE_FFFF_accum,
400                                              simd_and(u32_BMP_select, u32l_FFFE_FFFF));
401        }
402        u32hl_accum = simd_gt_8(u32hl_accum, simd_const_8(0x10));
403        u32_surrogate_accum = simd_eq_8(simd_or(u32_surrogate_accum, simd_const_8(0x07)),
404                                        simd_const_8(0xFF));
405        if (bitblock_has_bit(simd_or(simd_or(u32hh_accum, u32hl_accum),
406                                         simd_or(u32_surrogate_accum, u32_FFFE_FFFF_accum)))) {
407                CharSetValidationError("UTF-32");
408        }
409#endif
410#ifndef X32BYTEPLEX_ACCESS
411        printf("UTF_32_Lexer::Do_CharsetValidation not yet complete; assuming OK.\n");
412#endif
413};
414
415Byteplex * Byteplex::ByteplexFactory(Entity_Info * e) {
416        Byteplex * b;
417        if (likely(e->code_unit_size == SingleByte)) {
418                if (likely(e->code_unit_base == ASCII))
419                        b = new X8_Buffer<ASCII>();
420                else b = new X8_Buffer<EBCDIC>();
421        }
422        else if (likely(e->code_unit_size == DoubleByte)) {
423                if (likely(e->byte_order == BigEndian))
424                        b = new U16BE_Buffer();
425                else b = new U16LE_Buffer();
426        }
427        else switch (e->byte_order) {
428                case BigEndian: b = new U32BE_Buffer(); break;
429                case LittleEndian: b = new U32LE_Buffer(); break;
430                case Unusual_2143: b = new U32_2143_Buffer(); break;
431                case Unusual_3412: b = new U32_3412_Buffer(); break;
432        }
433        return b;
434}
435
436Byteplex * Byteplex::ByteplexFactory(Entity_Info * e, FILE * inputfile) {
437        Byteplex * b = ByteplexFactory(e);
438        b->infile = inputfile;
439        return b;
440}
441
442Byteplex * Byteplex::ByteplexFactory(Entity_Info * e, unsigned char * buffer_bytes, int buffer_size) {
443        Byteplex * b = ByteplexFactory(e);
444        memcpy(b->src_buffer, buffer_bytes, buffer_size);
445//printf("buffer_bytes = %s\n", buffer_bytes);
446        b->units_in_buffer = buffer_size / e->code_unit_size;
447        b->packs_in_buffer = (b->units_in_buffer + PACKSIZE -1)/PACKSIZE;
448        return b;
449}
450
451template <>
452int X8_Buffer<EBCDIC>::UTF8_Length(int name_pos, int lgth){
453        int u8_lgth = 0;
454        for (int i = name_pos; i < name_pos+lgth; i++) {
455                u8_lgth += /*TEMPORARY - NEED TO USE A TABLE FOR LOOKUP*/ 2;
456        }
457        return u8_lgth;
458}
459
460template <>
461int X8_Buffer<ASCII>::UTF8_Length(int name_pos, int lgth){
462        int u8_lgth = 0;
463        for (int i = name_pos; i < name_pos+lgth; i++) {
464                if (((unsigned char *)x8data)[i] < 0x80) u8_lgth += 1;
465                else u8_lgth += /*TEMPORARY - NEED TO USE A TABLE FOR LOOKUP*/ 1;
466        }
467        return u8_lgth;
468}
469
470int UTF8_Buffer::UTF8_Length(int name_pos, int lgth){
471        return lgth;
472}
473
474int U16_Buffer::UTF8_Length(int name_pos, int lgth){
475        int u8_lgth = 0;
476        for (int i = name_pos; i < name_pos+lgth; i++) {
477                if (((unsigned char *)x8data)[i] < 0x80) u8_lgth += 1;
478                else if(((unsigned char *)x16hi)[i]<=0x7 || (((unsigned char *)x16hi)[i] >= 0xD8 &&((unsigned char *)x16hi)[i]<= 0xDF))
479                        u8_lgth += 2;
480                else
481                        u8_lgth += 3;
482        }
483        return u8_lgth;
484}
485
486int U32_Buffer::UTF8_Length(int name_pos, int lgth){
487        int u8_lgth = 0;
488        unsigned char * u32hl = (unsigned char *) x32hl;
489        unsigned char * u32lh = (unsigned char *) x32lh;
490        for (int i = name_pos; i < name_pos+lgth; i++) {
491                if (((unsigned char *)x8data)[i] < 0x80)  {
492                        u8_lgth += 1;
493                }
494                else if(u32hl[i] > 0)
495                        u8_lgth += 4;
496                else if(u32lh[i]<=0x7)
497                        u8_lgth += 2;
498                else
499                        u8_lgth += 3;
500        }
501        return u8_lgth;
502}
503
504template <>
505void X8_Buffer<ASCII>::to_UTF8(int name_pos, int lgth, char * u8_ptr){
506        memcpy(u8_ptr, &((char *)x8data)[name_pos], lgth);
507        u8_ptr[lgth] = '\0';
508//      u8_ptr = copy_name(&((char *)x8data)[name_pos], lgth);
509}
510
511template <>
512void X8_Buffer<EBCDIC>::to_UTF8(int name_pos, int lgth, char * u8_ptr){
513
514}
515void U16_Buffer::to_UTF8(int name_pos, int lgth, char * u8_ptr){
516        int u8_lgth = 0;
517        unsigned char * u16h = (unsigned char *) x16hi;
518        unsigned char * u16l = (unsigned char *) x16lo;
519        for (int i = name_pos; i < name_pos+lgth; i++) {
520                if (((unsigned char *)x8data)[i] < 0x80) {
521                        u8_ptr[u8_lgth] = ((unsigned char *)x8data)[i];
522                        u8_lgth += 1;
523                }
524                else if (u16h[i]<=0x7) {
525                        u8_ptr[u8_lgth] = 0xC0 + (u16h[i] << 2) + (u16l[i] >> 6);
526                        u8_ptr[u8_lgth+1] = 0x80 + (u16l[i] & 0x3F);
527                        u8_lgth += 2;
528                }
529                else if ((u16h[i] >= 0xD8) && (u16h[i]<= 0xDB)){
530                        char temp =  ((u16h[i] & 0x03) << 2) + (u16l[i] >> 6) + 1;
531                        u8_ptr[u8_lgth] = 0xF0 + (temp >> 2);
532                        u8_ptr[u8_lgth+1] = 0x80 + ((temp & 0x03) << 4) + ((u16l[i] & 0x3F) >> 2);
533                        u8_ptr[u8_lgth+2] = 0x80 + ((u16l[i] & 0x03) << 4) + ((u16h[i+1] & 0x03) << 2) + (u16l[i+1] >> 6);
534                        u8_ptr[u8_lgth+3] = 0x80 + (u16l[i+1] & 0x3F);
535                        i++;
536                        u8_lgth += 4;
537                }
538                else{
539                        u8_ptr[u8_lgth] = 0xE0 + (u16h[i] >> 4);
540                        u8_ptr[u8_lgth+1] = 0x80 + ((u16h[i] & 0x0F) << 2) + (u16l[i] >> 6);
541                        u8_ptr[u8_lgth+2] = 0x80 + (u16l[i] & 0x3F);
542                        u8_lgth += 3;
543                }
544        }
545        u8_ptr[u8_lgth] = '\0';
546}
547
548
549
550void U32_Buffer::to_UTF8(int name_pos, int lgth, char * u8_ptr){
551        int u8_lgth = 0;
552        unsigned char * u32hl = (unsigned char *) x32hl;
553        unsigned char * u32lh = (unsigned char *) x32lh;
554        unsigned char * u32ll = (unsigned char *) x32ll;
555        for (int i = name_pos; i < name_pos+lgth; i++) {
556                if (((unsigned char *)x8data)[i] < 0x80)  {
557                        u8_ptr[u8_lgth] = ((unsigned char *)x8data)[i];
558                        u8_lgth += 1;
559                }
560                else if(u32hl[i] > 0) {
561                        u8_ptr[u8_lgth] = 0xF0 + (u32hl[i] >> 2);
562                        u8_ptr[u8_lgth+1] = 0x80 + ((u32hl[i] & 0x03) << 4) + (u32lh[i] >> 4);
563                        u8_ptr[u8_lgth+2] = 0x80 + ((u32lh[i] & 0x0F) << 2) + (u32ll[i] >> 6);
564                        u8_ptr[u8_lgth+3] = 0x80 + (u32ll[i] & 0x3F);
565                        u8_lgth += 4;
566                }
567                else if(u32lh[i]<=0x7) {
568                        u8_ptr[u8_lgth] = 0xC0 + (u32lh[i] << 2) + (u32ll[i] >> 6);
569                        u8_ptr[u8_lgth+1] = 0x80 + (u32ll[i] & 0x3F);
570                        u8_lgth += 2;
571                }
572                else {
573                        u8_ptr[u8_lgth] = 0xE0 + (u32lh[i] >> 4);
574                        u8_ptr[u8_lgth+1] = 0x80 + ((u32lh[i] & 0x0F) << 2) + (u32ll[i] >> 6);
575                        u8_ptr[u8_lgth+2] = 0x80 + (u32ll[i] & 0x3F);
576                        u8_lgth += 3;
577                }
578        }
579        u8_ptr[u8_lgth] = '\0';
580}
581
582
Note: See TracBrowser for help on using the repository browser.