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

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

Alphabet class: initial check-in

File size: 2.5 KB
Line 
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
7#include <utf8_encoder.h>
8#include <assert.h>
9#include <algorithm>
10#include <stdexcept>
11
12using namespace UCD;
13
14namespace cc {
15
16bool UTF8_Encoder::isPrefix(const codepoint_t cp) {
17    return (cp >= 0xC2) && (cp <= 0xF4);
18}
19
20codepoint_t UTF8_Encoder::encodingByte(const codepoint_t cp, const unsigned n) {
21    codepoint_t retVal = 0;
22    const unsigned len = length(cp);
23    if (n == 1) {
24        switch (len) {
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;
29        }
30    }
31    else {
32        retVal = 0x80 | ((cp >> (6 * (len - n))) & 0x3F);
33    }
34    return retVal;
35}
36
37unsigned UTF8_Encoder::length(const codepoint_t cp) {
38    if (cp <= 0x7F) {
39        return 1;
40    }
41    else if (cp <= 0x7FF) {
42        return 2;
43    }
44    else if (cp <= 0xFFFF) {
45        return 3;
46    }
47    else {
48        return 4;
49    }
50}
51
52codepoint_t UTF8_Encoder::maxCodePoint(const unsigned length) {
53    if (length == 1) {
54        return 0x7F;
55    }
56    else if (length == 2) {
57        return 0x7FF;
58    }
59    else if (length == 3) {
60        return 0xFFFF;
61    }
62    else if (length == 4) {
63        return 0x10FFFF;
64    }
65    throw std::runtime_error("Unexpected UTF8 Length: " + std::to_string(length));
66}
67
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) {
72            return false;
73        }
74    }
75    return true;
76}
77
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) {
82            return false;
83        }
84    }
85    return true;
86}
87
88codepoint_t UTF8_Encoder::minCodePointWithCommonBytes(const UCD::codepoint_t cp, const unsigned n) {
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}
94
95codepoint_t UTF8_Encoder::maxCodePointWithCommonBytes(const UCD::codepoint_t cp, const unsigned n) {
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
101}
Note: See TracBrowser for help on using the repository browser.