1/*
2******************************************************************************
3*
4*   Copyright (C) 1999-2004, International Business Machines
5*   Corporation and others.  All Rights Reserved.
6*
7******************************************************************************
8*
9*   uconv_cnv.c:
10*   Implements all the low level conversion functions
11*   T_UnicodeConverter_{to,from}Unicode_$ConversionType
12*
13*   Change history:
14*
15*   06/29/2000  helena      Major rewrite of the callback APIs.
16*/
17
18#include "unicode/utypes.h"
19
20#if !UCONFIG_NO_CONVERSION
21
22#include "unicode/ucnv_err.h"
23#include "unicode/ucnv.h"
24#include "unicode/uset.h"
25#include "ucnv_cnv.h"
26#include "ucnv_bld.h"
27#include "cmemory.h"
28
29U_CFUNC void
30ucnv_getCompleteUnicodeSet(const UConverter *cnv,
31                   const USetAdder *sa,
32                   UConverterUnicodeSet which,
33                   UErrorCode *pErrorCode) {
34    sa->addRange(sa->set, 0, 0x10ffff);
35}
36
37U_CFUNC void
38ucnv_getNonSurrogateUnicodeSet(const UConverter *cnv,
39                               const USetAdder *sa,
40                               UConverterUnicodeSet which,
41                               UErrorCode *pErrorCode) {
42    sa->addRange(sa->set, 0, 0xd7ff);
43    sa->addRange(sa->set, 0xe000, 0x10ffff);
44}
45
46U_CFUNC void
47ucnv_fromUWriteBytes(UConverter *cnv,
48                     const char *bytes, int32_t length,
49                     char **target, const char *targetLimit,
50                     int32_t **offsets,
51                     int32_t sourceIndex,
52                     UErrorCode *pErrorCode) {
53    char *t=*target;
54    int32_t *o;
55
56    /* write bytes */
57    if(offsets==NULL || (o=*offsets)==NULL) {
58        while(length>0 && t<targetLimit) {
59            *t++=*bytes++;
60            --length;
61        }
62    } else {
63        /* output with offsets */
64        while(length>0 && t<targetLimit) {
65            *t++=*bytes++;
66            *o++=sourceIndex;
67            --length;
68        }
69        *offsets=o;
70    }
71    *target=t;
72
73    /* write overflow */
74    if(length>0) {
75        if(cnv!=NULL) {
76            t=(char *)cnv->charErrorBuffer;
77            cnv->charErrorBufferLength=(int8_t)length;
78            do {
79                *t++=(uint8_t)*bytes++;
80            } while(--length>0);
81        }
82        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
83    }
84}
85
86U_CFUNC void
87ucnv_toUWriteUChars(UConverter *cnv,
88                    const UChar *uchars, int32_t length,
89                    UChar **target, const UChar *targetLimit,
90                    int32_t **offsets,
91                    int32_t sourceIndex,
92                    UErrorCode *pErrorCode) {
93    UChar *t=*target;
94    int32_t *o;
95
96    /* write UChars */
97    if(offsets==NULL || (o=*offsets)==NULL) {
98        while(length>0 && t<targetLimit) {
99            *t++=*uchars++;
100            --length;
101        }
102    } else {
103        /* output with offsets */
104        while(length>0 && t<targetLimit) {
105            *t++=*uchars++;
106            *o++=sourceIndex;
107            --length;
108        }
109        *offsets=o;
110    }
111    *target=t;
112
113    /* write overflow */
114    if(length>0) {
115        if(cnv!=NULL) {
116            t=cnv->UCharErrorBuffer;
117            cnv->UCharErrorBufferLength=(int8_t)length;
118            do {
119                *t++=*uchars++;
120            } while(--length>0);
121        }
122        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
123    }
124}
125
126U_CFUNC void
127ucnv_toUWriteCodePoint(UConverter *cnv,
128                       UChar32 c,
129                       UChar **target, const UChar *targetLimit,
130                       int32_t **offsets,
131                       int32_t sourceIndex,
132                       UErrorCode *pErrorCode) {
133    UChar *t;
134    int32_t *o;
135
136    t=*target;
137
138    if(t<targetLimit) {
139        if(c<=0xffff) {
140            *t++=(UChar)c;
141            c=U_SENTINEL;
142        } else /* c is a supplementary code point */ {
143            *t++=U16_LEAD(c);
144            c=U16_TRAIL(c);
145            if(t<targetLimit) {
146                *t++=(UChar)c;
147                c=U_SENTINEL;
148            }
149        }
150
151        /* write offsets */
152        if(offsets!=NULL && (o=*offsets)!=NULL) {
153            *o++=sourceIndex;
154            if((*target+1)<t) {
155                *o++=sourceIndex;
156            }
157            *offsets=o;
158        }
159    }
160
161    *target=t;
162
163    /* write overflow from c */
164    if(c>=0) {
165        if(cnv!=NULL) {
166            int8_t i=0;
167            U16_APPEND_UNSAFE(cnv->UCharErrorBuffer, i, c);
168            cnv->UCharErrorBufferLength=i;
169        }
170        *pErrorCode=U_BUFFER_OVERFLOW_ERROR;
171    }
172}
173
174#endif
175