| // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef VM_UNICODE_H_ |
| #define VM_UNICODE_H_ |
| |
| #include "vm/allocation.h" |
| #include "vm/globals.h" |
| |
| namespace dart { |
| |
| class String; |
| |
| class Utf8 : AllStatic { |
| public: |
| static const intptr_t kMaxOneByteChar = 0x7F; |
| static const intptr_t kMaxTwoByteChar = 0x7FF; |
| static const intptr_t kMaxThreeByteChar = 0xFFFF; |
| static const intptr_t kMaxFourByteChar = 0x10FFFF; |
| |
| static intptr_t CodePointCount(const char* str, intptr_t* width); |
| |
| static bool IsValid(const char* src); |
| |
| static intptr_t Length(int32_t ch); |
| static intptr_t Length(const String& str); |
| |
| static intptr_t Encode(int32_t ch, char* dst); |
| static intptr_t Encode(const String& src, char* dst, intptr_t len); |
| |
| static intptr_t Decode(const char*, int32_t* ch); |
| static bool Decode(const char* src, uint8_t* dst, intptr_t len); |
| static bool Decode(const char* src, uint16_t* dst, intptr_t len); |
| static bool Decode(const char* src, uint32_t* dst, intptr_t len); |
| }; |
| |
| |
| class CaseMapping : AllStatic { |
| public: |
| // Maps a code point to uppercase. |
| static int32_t ToUpper(int32_t code_point) { |
| return Convert(code_point, kUppercase); |
| } |
| |
| // Maps a code point to lowercase. |
| static int32_t ToLower(int32_t code_point) { |
| return Convert(code_point, kLowercase); |
| } |
| |
| private: |
| // Property is a delta to the uppercase mapping. |
| static const int32_t kUppercase = 1; |
| |
| // Property is a delta to the uppercase mapping. |
| static const int32_t kLowercase = 2; |
| |
| // Property is an index into the exception table. |
| static const int32_t kException = 3; |
| |
| // Type bit-field parameters |
| static const int32_t kTypeShift = 2; |
| static const int32_t kTypeMask = 3; |
| |
| // The size of the stage 1 index. |
| // TODO(cshapiro): improve indexing so this value is unnecessary. |
| static const int kStage1Size = 261; |
| |
| // The size of a stage 2 block in bytes. |
| static const int kBlockSizeLog2 = 8; |
| static const int kBlockSize = 1 << kBlockSizeLog2; |
| |
| static int32_t Convert(int32_t ch, int32_t mapping) { |
| if (ch <= 0xFF) { |
| int32_t info = stage2_[ch]; |
| if ((info & kTypeMask) == mapping) { |
| ch += info >> kTypeShift; |
| } |
| } else if (ch <= (kStage1Size << kBlockSizeLog2)) { |
| int16_t offset = stage1_[ch >> kBlockSizeLog2] << kBlockSizeLog2; |
| int32_t info = stage2_[offset + (ch & (kBlockSize - 1))]; |
| int32_t type = info & kTypeMask; |
| if (type == mapping) { |
| ch += (info >> kTypeShift); |
| } else if (type == kException) { |
| ch += stage2_exception_[info >> kTypeShift][mapping - 1]; |
| } |
| } |
| return ch; |
| } |
| |
| // Index into the data array. |
| static const uint8_t stage1_[]; |
| |
| // Data for small code points with one mapping |
| static const int16_t stage2_[]; |
| |
| // Data for large code points or code points with both mappings. |
| static const int32_t stage2_exception_[][2]; |
| }; |
| |
| } // namespace dart |
| |
| #endif // VM_UNICODE_H_ |