1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Copyright (C) 2002-2010, International Business Machines 5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* Corporation and others. All Rights Reserved. 6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)******************************************************************************* 8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* file name: punycode.c 9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* encoding: US-ASCII 10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* tab size: 8 (not used) 11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* indentation:4 12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* 13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created on: 2002jan31 14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)* created by: Markus W. Scherer 15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* This ICU code derived from: */ 19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)punycode.c 0.4.0 (2001-Nov-17-Sat) 21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)http://www.cs.berkeley.edu/~amc/idn/ 22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Adam M. Costello 23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)http://www.nicemice.net/amc/ 24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)Disclaimer and license 26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) Regarding this entire document or any portion of it (including 28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) the pseudocode and C code), the author makes no guarantees and 29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) is not responsible for any damage resulting from its use. The 30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) author grants irrevocable permission to anyone to use, modify, 31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) and distribute it in any way that does not diminish the rights 32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) of anyone else to use, modify, and distribute it, provided that 33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) redistributed derivative works do not contain misleading author or 34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) version information. Derivative works need not be licensed under 35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) similar terms. 36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)*/ 37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * ICU modifications: 39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - ICU data types and coding conventions 40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - ICU string buffer handling with implicit source lengths 41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and destination preflighting 42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * - UTF-16 handling 43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h" 46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_IDNA 48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ustr_imp.h" 50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h" 51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h" 52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "punycode.h" 53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h" 54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Punycode ----------------------------------------------------------------- */ 57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Punycode parameters for Bootstring */ 59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define BASE 36 60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TMIN 1 61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TMAX 26 62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define SKEW 38 63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DAMP 700 64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define INITIAL_BIAS 72 65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define INITIAL_N 0x80 66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* "Basic" Unicode/ASCII code points */ 68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _HYPHEN 0X2d 69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define DELIMITER _HYPHEN 70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _ZERO_ 0X30 72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _NINE 0x39 73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _SMALL_A 0X61 75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _SMALL_Z 0X7a 76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _CAPITAL_A 0X41 78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _CAPITAL_Z 0X5a 79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define IS_BASIC(c) ((c)<0x80) 81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define IS_BASIC_UPPERCASE(c) (_CAPITAL_A<=(c) && (c)<=_CAPITAL_Z) 82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * digitToBasic() returns the basic code point whose value 85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * (when used for representing integers) is d, which must be in the 86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * range 0 to BASE-1. The lowercase form is used unless the uppercase flag is 87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * nonzero, in which case the uppercase form is used. 88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_INLINE char 90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)digitToBasic(int32_t digit, UBool uppercase) { 91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 0..25 map to ASCII a..z or A..Z */ 92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 26..35 map to ASCII 0..9 */ 93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(digit<26) { 94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(uppercase) { 95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (char)(_CAPITAL_A+digit); 96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (char)(_SMALL_A+digit); 98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return (char)((_ZERO_-26)+digit); 101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/** 105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * basicToDigit[] contains the numeric value of a basic code 106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * point (for use in representing integers) in the range 0 to 107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * BASE-1, or -1 if b is does not represent a value. 108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int8_t 110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)basicToDigit[256]={ 111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, 116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, 122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}; 135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static U_INLINE char 137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)asciiCaseMap(char b, UBool uppercase) { 138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(uppercase) { 139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(_SMALL_A<=b && b<=_SMALL_Z) { 140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b-=(_SMALL_A-_CAPITAL_A); 141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(_CAPITAL_A<=b && b<=_CAPITAL_Z) { 144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b+=(_SMALL_A-_CAPITAL_A); 145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return b; 148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Punycode-specific Bootstring code ---------------------------------------- */ 151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* 153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The following code omits the {parts} of the pseudo-algorithm in the spec 154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * that are not used with the Punycode parameter set. 155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Bias adaptation function. */ 158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int32_t 159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)adaptBias(int32_t delta, int32_t length, UBool firstTime) { 160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t count; 161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(firstTime) { 163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta/=DAMP; 164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta/=2; 166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta+=delta/length; 169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(count=0; delta>((BASE-TMIN)*TMAX)/2; count+=BASE) { 170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta/=(BASE-TMIN); 171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return count+(((BASE-TMIN+1)*delta)/(delta+SKEW)); 174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define MAX_CP_COUNT 200 177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strToPunycode(const UChar *src, int32_t srcLength, 180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) const UBool *caseFlags, 182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t cpBuffer[MAX_CP_COUNT]; 185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t n, delta, handledCPCount, basicLength, destLength, bias, j, m, q, k, t, srcCPCount; 186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar c, c2; 187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* argument checking */ 189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) { 194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Handle the basic code points and 200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * convert extended ones to UTF-32 in cpBuffer (caseFlag in sign bit): 201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcCPCount=destLength=0; 203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength==-1) { 204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* NUL-terminated input */ 205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j=0; /* no condition */; ++j) { 206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((c=src[j])==0) { 207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcCPCount==MAX_CP_COUNT) { 210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* too many input code points */ 211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(IS_BASIC(c)) { 215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpBuffer[srcCPCount++]=0; 216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength<destCapacity) { 217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destLength]= 218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags!=NULL ? 219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) asciiCaseMap((char)c, caseFlags[j]) : 220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (char)c; 221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destLength; 223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n=(caseFlags!=NULL && caseFlags[j])<<31L; 225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UTF_IS_SINGLE(c)) { 226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n|=c; 227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(UTF_IS_LEAD(c) && UTF_IS_TRAIL(c2=src[j+1])) { 228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++j; 229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n|=(int32_t)UTF16_GET_PAIR_VALUE(c, c2); 230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* error: unmatched surrogate */ 232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INVALID_CHAR_FOUND; 233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpBuffer[srcCPCount++]=n; 236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* length-specified input */ 240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j=0; j<srcLength; ++j) { 241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcCPCount==MAX_CP_COUNT) { 242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* too many input code points */ 243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INDEX_OUTOFBOUNDS_ERROR; 244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) c=src[j]; 247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(IS_BASIC(c)) { 248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpBuffer[srcCPCount++]=0; 249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength<destCapacity) { 250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destLength]= 251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags!=NULL ? 252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) asciiCaseMap((char)c, caseFlags[j]) : 253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (char)c; 254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destLength; 256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n=(caseFlags!=NULL && caseFlags[j])<<31L; 258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(UTF_IS_SINGLE(c)) { 259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n|=c; 260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(UTF_IS_LEAD(c) && (j+1)<srcLength && UTF_IS_TRAIL(c2=src[j+1])) { 261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++j; 262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n|=(int32_t)UTF16_GET_PAIR_VALUE(c, c2); 263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* error: unmatched surrogate */ 265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INVALID_CHAR_FOUND; 266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpBuffer[srcCPCount++]=n; 269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Finish the basic string - if it is not empty - with a delimiter. */ 274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) basicLength=destLength; 275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(basicLength>0) { 276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength<destCapacity) { 277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destLength]=DELIMITER; 278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destLength; 280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * handledCPCount is the number of code points that have been handled 284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * basicLength is the number of basic code points 285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * destLength is the number of chars that have been output 286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Initialize the state: */ 289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n=INITIAL_N; 290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta=0; 291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bias=INITIAL_BIAS; 292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Main encoding loop: */ 294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(handledCPCount=basicLength; handledCPCount<srcCPCount; /* no op */) { 295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * All non-basic code points < n have been handled already. 297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Find the next larger one: 298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(m=0x7fffffff, j=0; j<srcCPCount; ++j) { 300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */ 301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(n<=q && q<m) { 302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) m=q; 303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Increase delta enough to advance the decoder's 308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * <n,i> state to <m,0>, but guard against overflow: 309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(m-n>(0x7fffffff-MAX_CP_COUNT-delta)/(handledCPCount+1)) { 311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INTERNAL_PROGRAM_ERROR; 312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta+=(m-n)*(handledCPCount+1); 315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n=m; 316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Encode a sequence of same code points n */ 318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j=0; j<srcCPCount; ++j) { 319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) q=cpBuffer[j]&0x7fffffff; /* remove case flag from the sign bit */ 320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(q<n) { 321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++delta; 322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(q==n) { 323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Represent delta as a generalized variable-length integer: */ 324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(q=delta, k=BASE; /* no condition */; k+=BASE) { 325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt 327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=k-bias; 329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(t<TMIN) { 330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMIN; 331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(t>TMAX) { 332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMAX; 333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=k-bias; 337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(t<TMIN) { 338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMIN; 339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(k>=(bias+TMAX)) { 340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMAX; 341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(q<t) { 344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength<destCapacity) { 348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destLength]=digitToBasic(t+(q-t)%(BASE-t), 0); 349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destLength; 351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) q=(q-t)/(BASE-t); 352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(destLength<destCapacity) { 355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[destLength]=digitToBasic(q, (UBool)(cpBuffer[j]<0)); 356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destLength; 358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bias=adaptBias(delta, handledCPCount+1, (UBool)(handledCPCount==basicLength)); 359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) delta=0; 360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++handledCPCount; 361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++delta; 365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++n; 366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, destLength, pErrorCode); 369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)U_CFUNC int32_t 372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)u_strFromPunycode(const UChar *src, int32_t srcLength, 373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar *dest, int32_t destCapacity, 374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UBool *caseFlags, 375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UErrorCode *pErrorCode) { 376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t n, destLength, i, bias, basicLength, j, in, oldi, w, k, digit, t, 377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destCPCount, firstSupplementaryIndex, cpLength; 378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UChar b; 379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* argument checking */ 381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) { 382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src==NULL || srcLength<-1 || (dest==NULL && destCapacity!=0)) { 386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_ARGUMENT_ERROR; 387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(srcLength==-1) { 391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) srcLength=u_strlen(src); 392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Handle the basic code points: 396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Let basicLength be the number of input code points 397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * before the last delimiter, or 0 if there is none, 398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * then copy the first basicLength code points to the output. 399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * The two following loops iterate backward. 401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(j=srcLength; j>0;) { 403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(src[--j]==DELIMITER) { 404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength=basicLength=destCPCount=j; 408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) while(j>0) { 410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) b=src[--j]; 411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(!IS_BASIC(b)) { 412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INVALID_CHAR_FOUND; 413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(j<destCapacity) { 417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[j]=(UChar)b; 418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(caseFlags!=NULL) { 420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags[j]=IS_BASIC_UPPERCASE(b); 421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Initialize the state: */ 426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n=INITIAL_N; 427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i=0; 428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bias=INITIAL_BIAS; 429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) firstSupplementaryIndex=1000000000; 430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Main decoding loop: 433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Start just after the last delimiter if any 434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * basic code points were copied; start at the beginning otherwise. 435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(in=basicLength>0 ? basicLength+1 : 0; in<srcLength; /* no op */) { 437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * in is the index of the next character to be consumed, and 439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * destCPCount is the number of code points in the output array. 440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Decode a generalized variable-length integer into delta, 442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * which gets added to i. The overflow checking is easier 443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * if we increase i as we go, then subtract off its starting 444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * value at the end to obtain delta. 445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) for(oldi=i, w=1, k=BASE; /* no condition */; k+=BASE) { 447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(in>=srcLength) { 448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_CHAR_FOUND; 449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) digit=basicToDigit[(uint8_t)src[in++]]; 453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(digit<0) { 454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_INVALID_CHAR_FOUND; 455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(digit>(0x7fffffff-i)/w) { 458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* integer overflow */ 459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_CHAR_FOUND; 460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i+=digit*w; 464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /** RAM: comment out the old code for conformance with draft-ietf-idn-punycode-03.txt 465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=k-bias; 466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(t<TMIN) { 467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMIN; 468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(t>TMAX) { 469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMAX; 470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=k-bias; 473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(t<TMIN) { 474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMIN; 475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else if(k>=(bias+TMAX)) { 476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) t=TMAX; 477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(digit<t) { 479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) break; 480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(w>0x7fffffff/(BASE-t)) { 483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* integer overflow */ 484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_CHAR_FOUND; 485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) w*=BASE-t; 488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Modification from sample code: 492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Increments destCPCount here, 493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * where needed instead of in for() loop tail. 494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++destCPCount; 496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) bias=adaptBias(i-oldi, destCPCount, (UBool)(oldi==0)); 497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * i was supposed to wrap around from (incremented) destCPCount to 0, 500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * incrementing n each time, so we'll fix that now: 501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i/destCPCount>(0x7fffffff-n)) { 503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* integer overflow */ 504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_CHAR_FOUND; 505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) n+=i/destCPCount; 509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) i%=destCPCount; 510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* not needed for Punycode: */ 511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* if (decode_digit(n) <= BASE) return punycode_invalid_input; */ 512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(n>0x10ffff || UTF_IS_SURROGATE(n)) { 514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Unicode code point overflow */ 515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) *pErrorCode=U_ILLEGAL_CHAR_FOUND; 516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return 0; 517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Insert n at position i of the output: */ 520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) cpLength=UTF_CHAR_LENGTH(n); 521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if((destLength+cpLength)<=destCapacity) { 522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) int32_t codeUnitIndex; 523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* 525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Handle indexes when supplementary code points are present. 526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * In almost all cases, there will be only BMP code points before i 528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * and even in the entire string. 529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * This is handled with the same efficiency as with UTF-32. 530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * 531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Only the rare cases with supplementary code points are handled 532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * more slowly - but not too bad since this is an insertion anyway. 533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) */ 534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(i<=firstSupplementaryIndex) { 535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) codeUnitIndex=i; 536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cpLength>1) { 537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) firstSupplementaryIndex=codeUnitIndex; 538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++firstSupplementaryIndex; 540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) codeUnitIndex=firstSupplementaryIndex; 543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) UTF_FWD_N(dest, codeUnitIndex, destLength, i-codeUnitIndex); 544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* use the UChar index codeUnitIndex instead of the code point index i */ 547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(codeUnitIndex<destLength) { 548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(dest+codeUnitIndex+cpLength, 549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest+codeUnitIndex, 550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) (destLength-codeUnitIndex)*U_SIZEOF_UCHAR); 551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(caseFlags!=NULL) { 552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) uprv_memmove(caseFlags+codeUnitIndex+cpLength, 553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags+codeUnitIndex, 554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength-codeUnitIndex); 555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cpLength==1) { 558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* BMP, insert one code unit */ 559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[codeUnitIndex]=(UChar)n; 560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } else { 561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* supplementary character, insert two code units */ 562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[codeUnitIndex]=UTF16_LEAD(n); 563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) dest[codeUnitIndex+1]=UTF16_TRAIL(n); 564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(caseFlags!=NULL) { 566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) /* Case of last character determines uppercase flag: */ 567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags[codeUnitIndex]=IS_BASIC_UPPERCASE(src[in-1]); 568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) if(cpLength==2) { 569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) caseFlags[codeUnitIndex+1]=FALSE; 570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) destLength+=cpLength; 574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ++i; 575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) } 576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) return u_terminateUChars(dest, destCapacity, destLength, pErrorCode); 578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} 579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* ### check notes on overflow handling - only necessary if not IDNA? are these Punycode functions to be public? */ 581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) 582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_IDNA */ 583