source: icGREP/icgrep-devel/icgrep/utf8_encoder.cpp @ 5346

Last change on this file since 5346 was 5278, checked in by cameron, 3 years ago

Alphabet class: initial check-in

File size: 2.5 KB
RevLine 
[3850]1/*
2 *  Copyright (c) 2014 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
[4249]7#include <utf8_encoder.h>
[4187]8#include <assert.h>
[4203]9#include <algorithm>
[4187]10#include <stdexcept>
11
[5278]12using namespace UCD;
[3850]13
[4249]14namespace cc {
15
[4615]16bool UTF8_Encoder::isPrefix(const codepoint_t cp) {
[4249]17    return (cp >= 0xC2) && (cp <= 0xF4);
[3961]18}
19
[4615]20codepoint_t UTF8_Encoder::encodingByte(const codepoint_t cp, const unsigned n) {
[4612]21    codepoint_t retVal = 0;
[4615]22    const unsigned len = length(cp);
[4249]23    if (n == 1) {
24        switch (len) {
[4614]25            case 1: retVal = cp; break;
26            case 2: retVal = 0xC0 | (cp >> 6); break;
27            case 3: retVal = 0xE0 | (cp >> 12); break;
28            case 4: retVal = 0xF0 | (cp >> 18); break;
[3850]29        }
30    }
[4249]31    else {
[4614]32        retVal = 0x80 | ((cp >> (6 * (len - n))) & 0x3F);
[3850]33    }
34    return retVal;
35}
36
[4615]37unsigned UTF8_Encoder::length(const codepoint_t cp) {
[4249]38    if (cp <= 0x7F) {
[3850]39        return 1;
40    }
[4249]41    else if (cp <= 0x7FF) {
[3850]42        return 2;
43    }
[4249]44    else if (cp <= 0xFFFF) {
[3850]45        return 3;
46    }
[4249]47    else {
[3850]48        return 4;
49    }
50}
51
[4615]52codepoint_t UTF8_Encoder::maxCodePoint(const unsigned length) {
[4249]53    if (length == 1) {
[3850]54        return 0x7F;
55    }
[4249]56    else if (length == 2) {
[3850]57        return 0x7FF;
58    }
[4249]59    else if (length == 3) {
[3850]60        return 0xFFFF;
61    }
[4249]62    else if (length == 4) {
[3850]63        return 0x10FFFF;
64    }
[4249]65    throw std::runtime_error("Unexpected UTF8 Length: " + std::to_string(length));
[3850]66}
67
[4615]68bool UTF8_Encoder::isLowCodePointAfterByte(const codepoint_t cp, const unsigned n) {
69    const auto l = length(cp);
70    for (auto i = n; i != l; ++i) {
71        if (encodingByte(cp, i + 1) != 0x80) {
[4614]72            return false;
73        }
74    }
75    return true;
76}
77
[4615]78bool UTF8_Encoder::isHighCodePointAfterByte(const codepoint_t cp, const unsigned n) {
79    const auto l = length(cp);
80    for (auto i = n; i != l; ++i) {
81        if (encodingByte(cp, i + 1) != 0xBF) {
[4614]82            return false;
83        }
84    }
85    return true;
86}
87
[5278]88codepoint_t UTF8_Encoder::minCodePointWithCommonBytes(const UCD::codepoint_t cp, const unsigned n) {
[4615]89    const auto len = length(cp);
90    const auto mask = (static_cast<codepoint_t>(1) << (len - n) * 6) - 1;
91    const auto lo_cp = cp &~ mask;
92    return (lo_cp == 0) ? mask + 1 : lo_cp;
93}
[4614]94
[5278]95codepoint_t UTF8_Encoder::maxCodePointWithCommonBytes(const UCD::codepoint_t cp, const unsigned n) {
[4615]96    const auto len = length(cp);
97    const auto mask = (static_cast<codepoint_t>(1) << (len - n) * 6) - 1;
98    return cp | mask;
99}
100
[4249]101}
Note: See TracBrowser for help on using the repository browser.