/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: AuUTF16.hpp Date: 2021-10-31 Author: Reece ***/ #pragma once namespace Aurora::Locale::Encoding::UTF16 { static void SwapU16(void *base, AuUInt32 count) { count *= 2; for (int i = 0; i < count; i += 2) { AuWriteU16BE(base, i, AuReadU16LE(base, i)); } } #define AU_HIGH_SURROGATE_START 0xd800 #define AU_HIGH_SURROGATE_END 0xdbff #define AU_LOW_SURROGATE_START 0xdc00 #define AU_LOW_SURROGATE_END 0xdfff #define AU_IS_HIGH_SURROGATE(wch) (((wch) >= AU_HIGH_SURROGATE_START) && ((wch) <= AU_HIGH_SURROGATE_END)) #define AU_IS_LOW_SURROGATE(wch) (((wch) >= AU_LOW_SURROGATE_START) && ((wch) <= AU_LOW_SURROGATE_END)) static int GetLenUC2CodePoint(const AuUInt8 *in, AuUInt32 len) { if (len < 2) return 0; auto a = *reinterpret_cast(in); if (!AU_IS_HIGH_SURROGATE(a)) return 2; if (len < 4) return 0; auto b = *reinterpret_cast(in + 2); return AU_IS_LOW_SURROGATE(b) ? 4 : 0; } static int Count16(const void *base, AuUInt32 length, bool bytes = false) { AuUInt32 i {}, cps {}; for (; i < length; ) { auto next = GetLenUC2CodePoint(((const AuUInt8 *)base) + i, length - i); if (next == 0) return i; i += next; cps++; } return bytes ? i : cps; } }