in src/couch_quickjs/quickjs/libunicode.c [824:960]
static int unicode_decomp_entry(uint32_t *res, uint32_t c,
int idx, uint32_t code, uint32_t len,
uint32_t type)
{
uint32_t c1;
int l, i, p;
const uint8_t *d;
if (type == DECOMP_TYPE_C1) {
res[0] = unicode_decomp_table2[idx];
return 1;
} else {
d = unicode_decomp_data + unicode_decomp_table2[idx];
switch(type) {
case DECOMP_TYPE_L1:
case DECOMP_TYPE_L2:
case DECOMP_TYPE_L3:
case DECOMP_TYPE_L4:
case DECOMP_TYPE_L5:
case DECOMP_TYPE_L6:
case DECOMP_TYPE_L7:
l = type - DECOMP_TYPE_L1 + 1;
d += (c - code) * l * 2;
for(i = 0; i < l; i++) {
if ((res[i] = unicode_get16(d + 2 * i)) == 0)
return 0;
}
return l;
case DECOMP_TYPE_LL1:
case DECOMP_TYPE_LL2:
{
uint32_t k, p;
l = type - DECOMP_TYPE_LL1 + 1;
k = (c - code) * l;
p = len * l * 2;
for(i = 0; i < l; i++) {
c1 = unicode_get16(d + 2 * k) |
(((d[p + (k / 4)] >> ((k % 4) * 2)) & 3) << 16);
if (!c1)
return 0;
res[i] = c1;
k++;
}
}
return l;
case DECOMP_TYPE_S1:
case DECOMP_TYPE_S2:
case DECOMP_TYPE_S3:
case DECOMP_TYPE_S4:
case DECOMP_TYPE_S5:
l = type - DECOMP_TYPE_S1 + 1;
d += (c - code) * l;
for(i = 0; i < l; i++) {
if ((res[i] = unicode_get_short_code(d[i])) == 0)
return 0;
}
return l;
case DECOMP_TYPE_I1:
l = 1;
p = 0;
goto decomp_type_i;
case DECOMP_TYPE_I2_0:
case DECOMP_TYPE_I2_1:
case DECOMP_TYPE_I3_1:
case DECOMP_TYPE_I3_2:
case DECOMP_TYPE_I4_1:
case DECOMP_TYPE_I4_2:
l = 2 + ((type - DECOMP_TYPE_I2_0) >> 1);
p = ((type - DECOMP_TYPE_I2_0) & 1) + (l > 2);
decomp_type_i:
for(i = 0; i < l; i++) {
c1 = unicode_get16(d + 2 * i);
if (i == p)
c1 += c - code;
res[i] = c1;
}
return l;
case DECOMP_TYPE_B18:
l = 18;
goto decomp_type_b;
case DECOMP_TYPE_B1:
case DECOMP_TYPE_B2:
case DECOMP_TYPE_B3:
case DECOMP_TYPE_B4:
case DECOMP_TYPE_B5:
case DECOMP_TYPE_B6:
case DECOMP_TYPE_B7:
case DECOMP_TYPE_B8:
l = type - DECOMP_TYPE_B1 + 1;
decomp_type_b:
{
uint32_t c_min;
c_min = unicode_get16(d);
d += 2 + (c - code) * l;
for(i = 0; i < l; i++) {
c1 = d[i];
if (c1 == 0xff)
c1 = 0x20;
else
c1 += c_min;
res[i] = c1;
}
}
return l;
case DECOMP_TYPE_LS2:
d += (c - code) * 3;
if (!(res[0] = unicode_get16(d)))
return 0;
res[1] = unicode_get_short_code(d[2]);
return 2;
case DECOMP_TYPE_PAT3:
res[0] = unicode_get16(d);
res[2] = unicode_get16(d + 2);
d += 4 + (c - code) * 2;
res[1] = unicode_get16(d);
return 3;
case DECOMP_TYPE_S2_UL:
case DECOMP_TYPE_LS2_UL:
c1 = c - code;
if (type == DECOMP_TYPE_S2_UL) {
d += c1 & ~1;
c = unicode_get_short_code(*d);
d++;
} else {
d += (c1 >> 1) * 3;
c = unicode_get16(d);
d += 2;
}
if (c1 & 1)
c = unicode_get_lower_simple(c);
res[0] = c;
res[1] = unicode_get_short_code(*d);
return 2;
}
}
return 0;
}