LINUX.ORG.RU

История изменений

Исправление saahriktu, (текущая версия) :

Что значит «И пользоваться тем, что является стандартом по-сути.» в контексте побайтного низкоуровневого разбора текста?

Вот читаем по одному байту и собираем из прочитанного символы/кодепоинты.

Что в этом контексте удобнее? KOI8-R, UTF-8 или UTF-32?

Чтение текста в KOI8-R как раз и входит в дефолтный стандарт и осуществляется через побайтное чтение. Один байт - один символ. И наоборот.

С UTF-32 чуть сложнее:

        // BE/LE mode guess
        if (MODE_BELEG) {
                rcharrb = 0;
                for (rcptr = 0; rcptr < 4; rcptr++) {
                        if ((rcbuf = getchar()) == EOF) {
                                printf("Error: broken stream\n");
                                return 1;
                        }
                        rcharrb += (1 << 8 * rcptr) * rcbuf;
                }
                if (rcharrb == 4294836224) {
                        MODE_BE = 1;
                        printf("[UTF-32BE]");
                } else {
                        MODE_BE = 0;
                        printf("[UTF-32LE]");
                }
...
        }
        // stream process
        rcptr = -1;
        while ((rcbuf = getchar()) != EOF) {
                rcptr++;
                if (rcptr == 0)
                        rcharrb = 0;
                if (MODE_BE == 0)
                        rcharrb += (1 << 8 * rcptr) * rcbuf;
                else
                        rcharrb += (16777216 >> 8 * rcptr) * rcbuf;
                if (rcptr == 3) {
                        rcptr = -1;     // Reset pointer
...
                }
        }
А с UTF-8?
int sizeoffatc(int headbyte)
{
    if (headbyte >= 0 && headbyte <= 0x7f)
        return 1;
    else if (headbyte >= 0xc0 && headbyte <= 0xdf)
        return 2;
    else if (headbyte >= 0xe0 && headbyte <= 0xef)
        return 3;
    else if (headbyte >= 0xf0 && headbyte <= 0xf7)
        return 4;
    else if (headbyte >= 0xf8 && headbyte <= 0xff)
        return -1;              // error
    return -1;                  // error
}
...
int decodefatc(int fcdt0, int fcdt1, int fcdt2, int fcdt3, int fcmaxk)
{
    if (fcmaxk == 1)
        return (fcdt0 & 0x3f) << 0x6 | (fcdt1 & 0x7f);
    if (fcmaxk == 2)
        return (fcdt0 & 0xe0) << 0xc | (fcdt1 & 0x7f) << 0x6 | (fcdt2 &
                                                                  0x7f);
    return ((fcdt0 & 0xf0) << 0x12) | (((fcdt1 & 0x7f) << 0xc) +
        ((fcdt2 & 0x7f) << 0x6)) | (fcdt3 & 0x7f);
}

int fgetfatc(FILE * fatstream)
{
    int cdbuf, cdt[4];
    int cdindx = 0, maxk;
    for (;;) {
        cdbuf = fgetc(fatstream);
        if (cdindx == 0) {
            if (cdbuf == -1)
                return EOF;
            if (cdbuf < 0x80)
                return cdbuf;   // ASCII
            else
                maxk = sizeoffatc(cdbuf) - 1;
            if (maxk == -2)
                return -2;
        }
        cdt[cdindx] = cdbuf;
        cdindx++;
        if (cdindx > maxk)
            break;
    }
    return decodefatc(cdt[0], cdt[1], cdt[2], cdt[3], maxk);
}

Исходная версия saahriktu, :

Что значит «И пользоваться тем, что является стандартом по-сути.» в контексте побайтного низкоуровневого разбора текста?

Вот читаем по одному байту и собираем из прочитанного символы/кодепоинты.

Что в этом контексте удобнее? KOI8-R, UTF-8 или UTF-32?

Чтение текста в KOI8-R как раз и входит в дефолтный стандарт и осуществляется через побайтное чтение. Один байт - один символ. И наоборот.

С UTF-32 чуть сложнее:

        // stream process
        rcptr = -1;
        while ((rcbuf = getchar()) != EOF) {
                rcptr++;
                if (rcptr == 0)
                        rcharrb = 0;
                if (MODE_BE == 0)
                        rcharrb += (1 << 8 * rcptr) * rcbuf;
                else
                        rcharrb += (16777216 >> 8 * rcptr) * rcbuf;
                if (rcptr == 3) {
                        rcptr = -1;     // Reset pointer
...
                }
        }
А с UTF-8?
int sizeoffatc(int headbyte)
{
    if (headbyte >= 0 && headbyte <= 0x7f)
        return 1;
    else if (headbyte >= 0xc0 && headbyte <= 0xdf)
        return 2;
    else if (headbyte >= 0xe0 && headbyte <= 0xef)
        return 3;
    else if (headbyte >= 0xf0 && headbyte <= 0xf7)
        return 4;
    else if (headbyte >= 0xf8 && headbyte <= 0xff)
        return -1;              // error
    return -1;                  // error
}
...
int decodefatc(int fcdt0, int fcdt1, int fcdt2, int fcdt3, int fcmaxk)
{
    if (fcmaxk == 1)
        return (fcdt0 & 0x3f) << 0x6 | (fcdt1 & 0x7f);
    if (fcmaxk == 2)
        return (fcdt0 & 0xe0) << 0xc | (fcdt1 & 0x7f) << 0x6 | (fcdt2 &
                                                                  0x7f);
    return ((fcdt0 & 0xf0) << 0x12) | (((fcdt1 & 0x7f) << 0xc) +
        ((fcdt2 & 0x7f) << 0x6)) | (fcdt3 & 0x7f);
}

int fgetfatc(FILE * fatstream)
{
    int cdbuf, cdt[4];
    int cdindx = 0, maxk;
    for (;;) {
        cdbuf = fgetc(fatstream);
        if (cdindx == 0) {
            if (cdbuf == -1)
                return EOF;
            if (cdbuf < 0x80)
                return cdbuf;   // ASCII
            else
                maxk = sizeoffatc(cdbuf) - 1;
            if (maxk == -2)
                return -2;
        }
        cdt[cdindx] = cdbuf;
        cdindx++;
        if (cdindx > maxk)
            break;
    }
    return decodefatc(cdt[0], cdt[1], cdt[2], cdt[3], maxk);
}