Blame src/utf8/unchecked.h

Packit Service 7770af
// Copyright 2006 Nemanja Trifunovic
Packit Service 7770af
Packit Service 7770af
/*
Packit Service 7770af
Permission is hereby granted, free of charge, to any person or organization
Packit Service 7770af
obtaining a copy of the software and accompanying documentation covered by
Packit Service 7770af
this license (the "Software") to use, reproduce, display, distribute,
Packit Service 7770af
execute, and transmit the Software, and to prepare derivative works of the
Packit Service 7770af
Software, and to permit third-parties to whom the Software is furnished to
Packit Service 7770af
do so, all subject to the following:
Packit Service 7770af
Packit Service 7770af
The copyright notices in the Software and this entire statement, including
Packit Service 7770af
the above license grant, this restriction and the following disclaimer,
Packit Service 7770af
must be included in all copies of the Software, in whole or in part, and
Packit Service 7770af
all derivative works of the Software, unless such copies or derivative
Packit Service 7770af
works are solely in the form of machine-executable object code generated by
Packit Service 7770af
a source language processor.
Packit Service 7770af
Packit Service 7770af
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit Service 7770af
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit Service 7770af
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
Packit Service 7770af
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
Packit Service 7770af
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
Packit Service 7770af
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Packit Service 7770af
DEALINGS IN THE SOFTWARE.
Packit Service 7770af
*/
Packit Service 7770af
Packit Service 7770af
Packit Service 7770af
#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
Packit Service 7770af
#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
Packit Service 7770af
Packit Service 7770af
#include "core.h"
Packit Service 7770af
Packit Service 7770af
namespace utf8
Packit Service 7770af
{
Packit Service 7770af
    namespace unchecked
Packit Service 7770af
    {
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        octet_iterator append(uint32_t cp, octet_iterator result)
Packit Service 7770af
        {
Packit Service 7770af
            if (cp < 0x80)                        // one octet
Packit Service 7770af
                *(result++) = static_cast<uint8_t>(cp);
Packit Service 7770af
            else if (cp < 0x800) {                // two octets
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp >> 6)          | 0xc0);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
Packit Service 7770af
            }
Packit Service 7770af
            else if (cp < 0x10000) {              // three octets
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp >> 12)         | 0xe0);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
Packit Service 7770af
            }
Packit Service 7770af
            else {                                // four octets
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp >> 18)         | 0xf0);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
Packit Service 7770af
                *(result++) = static_cast<uint8_t>((cp & 0x3f)        | 0x80);
Packit Service 7770af
            }
Packit Service 7770af
            return result;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        uint32_t next(octet_iterator& it)
Packit Service 7770af
        {
Packit Service 7770af
            uint32_t cp = utf8::internal::mask8(*it);
Packit Service 7770af
            typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
Packit Service 7770af
            switch (length) {
Packit Service 7770af
                case 1:
Packit Service 7770af
                    break;
Packit Service 7770af
                case 2:
Packit Service 7770af
                    it++;
Packit Service 7770af
                    cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
Packit Service 7770af
                    break;
Packit Service 7770af
                case 3:
Packit Service 7770af
                    ++it;
Packit Service 7770af
                    cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
Packit Service 7770af
                    ++it;
Packit Service 7770af
                    cp += (*it) & 0x3f;
Packit Service 7770af
                    break;
Packit Service 7770af
                case 4:
Packit Service 7770af
                    ++it;
Packit Service 7770af
                    cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
Packit Service 7770af
                    ++it;
Packit Service 7770af
                    cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
Packit Service 7770af
                    ++it;
Packit Service 7770af
                    cp += (*it) & 0x3f;
Packit Service 7770af
                    break;
Packit Service 7770af
            }
Packit Service 7770af
            ++it;
Packit Service 7770af
            return cp;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        uint32_t peek_next(octet_iterator it)
Packit Service 7770af
        {
Packit Service 7770af
            return utf8::unchecked::next(it);
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        uint32_t prior(octet_iterator& it)
Packit Service 7770af
        {
Packit Service 7770af
            while (utf8::internal::is_trail(*(--it))) ;
Packit Service 7770af
            octet_iterator temp = it;
Packit Service 7770af
            return utf8::unchecked::next(temp);
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        // Deprecated in versions that include prior, but only for the sake of consistency (see utf8::previous)
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        inline uint32_t previous(octet_iterator& it)
Packit Service 7770af
        {
Packit Service 7770af
            return utf8::unchecked::prior(it);
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator, typename distance_type>
Packit Service 7770af
        void advance (octet_iterator& it, distance_type n)
Packit Service 7770af
        {
Packit Service 7770af
            for (distance_type i = 0; i < n; ++i)
Packit Service 7770af
                utf8::unchecked::next(it);
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
        typename std::iterator_traits<octet_iterator>::difference_type
Packit Service 7770af
        distance (octet_iterator first, octet_iterator last)
Packit Service 7770af
        {
Packit Service 7770af
            typename std::iterator_traits<octet_iterator>::difference_type dist;
Packit Service 7770af
            for (dist = 0; first < last; ++dist)
Packit Service 7770af
                utf8::unchecked::next(first);
Packit Service 7770af
            return dist;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename u16bit_iterator, typename octet_iterator>
Packit Service 7770af
        octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
Packit Service 7770af
        {
Packit Service 7770af
            while (start != end) {
Packit Service 7770af
                uint32_t cp = utf8::internal::mask16(*start++);
Packit Service 7770af
            // Take care of surrogate pairs first
Packit Service 7770af
                if (utf8::internal::is_lead_surrogate(cp)) {
Packit Service 7770af
                    uint32_t trail_surrogate = utf8::internal::mask16(*start++);
Packit Service 7770af
                    cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
Packit Service 7770af
                }
Packit Service 7770af
                result = utf8::unchecked::append(cp, result);
Packit Service 7770af
            }
Packit Service 7770af
            return result;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename u16bit_iterator, typename octet_iterator>
Packit Service 7770af
        u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
Packit Service 7770af
        {
Packit Service 7770af
            while (start < end) {
Packit Service 7770af
                uint32_t cp = utf8::unchecked::next(start);
Packit Service 7770af
                if (cp > 0xffff) { //make a surrogate pair
Packit Service 7770af
                    *result++ = static_cast<uint16_t>((cp >> 10)   + internal::LEAD_OFFSET);
Packit Service 7770af
                    *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
Packit Service 7770af
                }
Packit Service 7770af
                else
Packit Service 7770af
                    *result++ = static_cast<uint16_t>(cp);
Packit Service 7770af
            }
Packit Service 7770af
            return result;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator, typename u32bit_iterator>
Packit Service 7770af
        octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
Packit Service 7770af
        {
Packit Service 7770af
            while (start != end)
Packit Service 7770af
                result = utf8::unchecked::append(*(start++), result);
Packit Service 7770af
Packit Service 7770af
            return result;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        template <typename octet_iterator, typename u32bit_iterator>
Packit Service 7770af
        u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
Packit Service 7770af
        {
Packit Service 7770af
            while (start < end)
Packit Service 7770af
                (*result++) = utf8::unchecked::next(start);
Packit Service 7770af
Packit Service 7770af
            return result;
Packit Service 7770af
        }
Packit Service 7770af
Packit Service 7770af
        // The iterator class
Packit Service 7770af
        template <typename octet_iterator>
Packit Service 7770af
          class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
Packit Service 7770af
            octet_iterator it;
Packit Service 7770af
            public:
Packit Service 7770af
            iterator () {}
Packit Service 7770af
            explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
Packit Service 7770af
            // the default "big three" are OK
Packit Service 7770af
            octet_iterator base () const { return it; }
Packit Service 7770af
            uint32_t operator * () const
Packit Service 7770af
            {
Packit Service 7770af
                octet_iterator temp = it;
Packit Service 7770af
                return utf8::unchecked::next(temp);
Packit Service 7770af
            }
Packit Service 7770af
            bool operator == (const iterator& rhs) const
Packit Service 7770af
            {
Packit Service 7770af
                return (it == rhs.it);
Packit Service 7770af
            }
Packit Service 7770af
            bool operator != (const iterator& rhs) const
Packit Service 7770af
            {
Packit Service 7770af
                return !(operator == (rhs));
Packit Service 7770af
            }
Packit Service 7770af
            iterator& operator ++ ()
Packit Service 7770af
            {
Packit Service 7770af
                ::std::advance(it, utf8::internal::sequence_length(it));
Packit Service 7770af
                return *this;
Packit Service 7770af
            }
Packit Service 7770af
            iterator operator ++ (int)
Packit Service 7770af
            {
Packit Service 7770af
                iterator temp = *this;
Packit Service 7770af
                ::std::advance(it, utf8::internal::sequence_length(it));
Packit Service 7770af
                return temp;
Packit Service 7770af
            }
Packit Service 7770af
            iterator& operator -- ()
Packit Service 7770af
            {
Packit Service 7770af
                utf8::unchecked::prior(it);
Packit Service 7770af
                return *this;
Packit Service 7770af
            }
Packit Service 7770af
            iterator operator -- (int)
Packit Service 7770af
            {
Packit Service 7770af
                iterator temp = *this;
Packit Service 7770af
                utf8::unchecked::prior(it);
Packit Service 7770af
                return temp;
Packit Service 7770af
            }
Packit Service 7770af
          }; // class iterator
Packit Service 7770af
Packit Service 7770af
    } // namespace utf8::unchecked
Packit Service 7770af
} // namespace utf8
Packit Service 7770af
Packit Service 7770af
Packit Service 7770af
#endif // header guard
Packit Service 7770af