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

Last change on this file since 5997 was 5924, checked in by cameron, 19 months ago

Various cleanups

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