⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 utf8.c

📁 apache的软件linux版本
💻 C
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include "apr.h"#include "apr_private.h"#include "apr_errno.h"#include "apr_arch_utf8.h"/* Implement the design principal specified by RFC 2718 2.2.5  * Guidelines for new URL Schemes - within the APR. * * Since many architectures support unicode, and UCS2 is the most * efficient storage used by those archictures, these functions * exist to validate a UCS string.  It is up to the operating system * to determine the validitity of the string in the context of it's * native language support.  File systems that support filename  * characters of 0x80-0xff but have no support of Unicode will find  * this function useful only for validating the character sequences  * and rejecting poorly encoded strings, if RFC 2718 2.2.5 naming is * desired. * * from RFC 2279 UTF-8, a transformation format of ISO 10646 * *     UCS-4 range (hex.)    UTF-8 octet sequence (binary) * 1:2 0000 0000-0000 007F   0xxxxxxx * 2:2 0000 0080-0000 07FF   110XXXXx 10xxxxxx * 3:2 0000 0800-0000 FFFF   1110XXXX 10Xxxxxx 10xxxxxx * 4:4 0001 0000-001F FFFF   11110zXX 10XXxxxx 10xxxxxx 10xxxxxx * inv 0020 0000-03FF FFFF   111110XX 10XXXxxx 10xxxxxx 10xxxxxx 10xxxxxx * inv 0400 0000-7FFF FFFF   1111110X 10XXXXxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx * * One of the X values must be one for the encoding length to be legit. * Neither the z bit, nor the final two forms, are used for ucs-2 * *   "Pairs of UCS-2 values between D800 and DFFF (surrogate pairs in  *   Unicode parlance), being actually UCS-4 characters transformed  *   through UTF-16, need special treatment: the UTF-16 transformation  *   must be undone, yielding a UCS-4 character that is then transformed  *   as above." * * from RFC2781 UTF-16: the compressed ISO 10646 encoding bitmask * *  U' = U - 0x10000 *  U' = 000000000000yyyyyyyyyyxxxxxxxxxx *                  W1 = 110110yyyyyyyyyy *                  W2 = 110111xxxxxxxxxx * * apr_conv_utf8_to_ucs2 out bytes:sizeof(in) * 1 <= Req <= sizeof(in) * 2 * * apr_conv_ucs2_to_utf8 out words:sizeof(in) / 2 <= Req <= sizeof(in) * 3 / 2 */APR_DECLARE(apr_status_t) apr_conv_utf8_to_ucs2(const char *in,                                                 apr_size_t *inbytes,                                                apr_wchar_t *out,                                                 apr_size_t *outwords){    apr_int64_t newch, mask;    apr_size_t expect, eating;    int ch;        while (*inbytes && *outwords)     {        ch = (unsigned char)(*in++);        if (!(ch & 0200)) {            /* US-ASCII-7 plain text             */            --*inbytes;            --*outwords;            *(out++) = ch;        }        else        {            if ((ch & 0300) != 0300) {                 /* Multibyte Continuation is out of place                 */                return APR_EINVAL;            }            else            {                /* Multibyte Sequence Lead Character                 *                 * Compute the expected bytes while adjusting                 * or lead byte and leading zeros mask.                 */                mask = 0340;                expect = 1;                while ((ch & mask) == mask) {                    mask |= mask >> 1;                    if (++expect > 3) /* (truly 5 for ucs-4) */                        return APR_EINVAL;                }                newch = ch & ~mask;                eating = expect + 1;                if (*inbytes <= expect)                    return APR_INCOMPLETE;                /* Reject values of excessive leading 0 bits                 * utf-8 _demands_ the shortest possible byte length                 */                if (expect == 1) {                    if (!(newch & 0036))                        return APR_EINVAL;                }                else {                    /* Reject values of excessive leading 0 bits                     */                    if (!newch && !((unsigned char)*in & 0077 & (mask << 1)))                        return APR_EINVAL;                    if (expect == 2) {                        /* Reject values D800-DFFF when not utf16 encoded                         * (may not be an appropriate restriction for ucs-4)                         */                        if (newch == 0015 && ((unsigned char)*in & 0040))                            return APR_EINVAL;                    }                    else if (expect == 3) {                        /* Short circuit values > 110000                         */                        if (newch > 4)                            return APR_EINVAL;                        if (newch == 4 && ((unsigned char)*in & 0060))                            return APR_EINVAL;                    }                }                /* Where the boolean (expect > 2) is true, we will need                 * an extra word for the output.                 */                if (*outwords < (apr_size_t)(expect > 2) + 1)                     break; /* buffer full */                while (expect--)                {                    /* Multibyte Continuation must be legal */                    if (((ch = (unsigned char)*(in++)) & 0300) != 0200)                        return APR_EINVAL;                    newch <<= 6;                    newch |= (ch & 0077);                }                *inbytes -= eating;                /* newch is now a true ucs-4 character                 *                 * now we need to fold to ucs-2                 */                if (newch < 0x10000)                 {                    --*outwords;                    *(out++) = (apr_wchar_t) newch;                }                else                 {                    *outwords -= 2;                    newch -= 0x10000;                    *(out++) = (apr_wchar_t) (0xD800 | (newch >> 10));                    *(out++) = (apr_wchar_t) (0xDC00 | (newch & 0x03FF));                                    }            }        }    }    /* Buffer full 'errors' aren't errors, the client must inspect both     * the inbytes and outwords values     */    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_conv_ucs2_to_utf8(const apr_wchar_t *in,                                                 apr_size_t *inwords,                                                char *out,                                                 apr_size_t *outbytes){    apr_int64_t newch, require;    apr_size_t need;    char *invout;    int ch;        while (*inwords && *outbytes)     {        ch = (unsigned short)(*in++);        if (ch < 0x80)        {            --*inwords;            --*outbytes;            *(out++) = (unsigned char) ch;        }        else         {            if ((ch & 0xFC00) == 0xDC00) {                /* Invalid Leading ucs-2 Multiword Continuation Character                 */                return APR_EINVAL;            }            if ((ch & 0xFC00) == 0xD800) {                /* Leading ucs-2 Multiword Character                 */                if (*inwords < 2) {                    /* Missing ucs-2 Multiword Continuation Character                     */                    return APR_INCOMPLETE;                }                if (((unsigned short)(*in) & 0xFC00) != 0xDC00) {                    /* Invalid ucs-2 Multiword Continuation Character                     */                    return APR_EINVAL;                }                newch = (ch & 0x03FF) << 10 | ((unsigned short)(*in++) & 0x03FF);                newch += 0x10000;            }            else {                /* ucs-2 Single Word Character                 */                newch = ch;            }            /* Determine the absolute minimum utf-8 bytes required             */            require = newch >> 11;            need = 1;            while (require)                require >>= 5, ++need;            if (need >= *outbytes)                break; /* Insufficient buffer */            *inwords -= (need > 2) + 1;            *outbytes -= need + 1;            /* Compute the utf-8 characters in last to first order,             * calculating the lead character length bits along the way.             */            ch = 0200;            out += need + 1;            invout = out;            while (need--) {                ch |= ch >> 1;                *(--invout) = (unsigned char)(0200 | (newch & 0077));                newch >>= 6;            }            /* Compute the lead utf-8 character and move the dest offset             */            *(--invout) = (unsigned char)(ch | newch);        }    }    /* Buffer full 'errors' aren't errors, the client must inspect both     * the inwords and outbytes values     */    return APR_SUCCESS;    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -