1 /* 2 * Copyright 2007-2013, Axel Dörfler, axeld@pinc-software.de. 3 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "utility.h" 10 11 #include <string.h> 12 13 #ifndef _BOOT_MODE 14 # include <utf8_functions.h> 15 #endif 16 17 #include "gpt_known_guids.h" 18 19 20 const guid_t kEmptyGUID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; 21 22 23 static void 24 put_utf8_byte(char*& to, size_t& left, char c) 25 { 26 if (left <= 1) 27 return; 28 29 *(to++) = c; 30 left--; 31 } 32 33 34 // #pragma mark - 35 36 37 size_t 38 to_utf8(const uint16* from, size_t maxFromLength, char* to, size_t toSize) 39 { 40 const char* start = to; 41 for (uint32 i = 0; i < maxFromLength; i++) { 42 // Decoding UTF-16LE 43 uint32 c = 0; 44 uint16 w1 = B_LENDIAN_TO_HOST_INT16(from[i]); 45 if (!w1) 46 break; 47 48 bool valid = false; 49 if (w1 < 0xD800 || w1 > 0xDFFF) { 50 c = w1; 51 valid = true; 52 } 53 54 if (!valid && (w1 >= 0xD800 && w1 <= 0xDBFF)) { 55 if (i + 1 < maxFromLength) { 56 uint16 w2 = B_LENDIAN_TO_HOST_INT16(from[i + 1]); 57 if (w2 >= 0xDC00 && w2 <= 0xDFFF) { 58 c = ((w1 & 0x3FF) << 10) | (w2 & 0x3FF); 59 c += 0x10000; 60 ++i; 61 valid = true; 62 } 63 } 64 } 65 66 if (!valid) break; 67 68 if (c < 0x80) 69 put_utf8_byte(to, toSize, c); 70 else if (c < 0x800) { 71 put_utf8_byte(to, toSize, 0xc0 | (c >> 6)); 72 put_utf8_byte(to, toSize, 0x80 | (c & 0x3f)); 73 } else if (c < 0x10000) { 74 put_utf8_byte(to, toSize, 0xe0 | (c >> 12)); 75 put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f)); 76 put_utf8_byte(to, toSize, 0x80 | (c & 0x3f)); 77 } else if (c <= 0x10ffff) { 78 put_utf8_byte(to, toSize, 0xf0 | (c >> 18)); 79 put_utf8_byte(to, toSize, 0x80 | ((c >> 12) & 0x3f)); 80 put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f)); 81 put_utf8_byte(to, toSize, 0x80 | (c & 0x3f)); 82 } 83 } 84 85 if (toSize > 0) 86 *to++ = '\0'; 87 88 return to - start; 89 } 90 91 92 #ifndef _BOOT_MODE 93 size_t 94 to_ucs2(const char* from, size_t fromLength, uint16* to, size_t maxToLength) 95 { 96 size_t index = 0; 97 while (from[0] != '\0' && index < maxToLength) { 98 uint32 c = UTF8ToCharCode(&from); 99 100 // Encoding UTF-16LE 101 if (c > 0x10FFFF) break; // invalid 102 if (c < 0x10000) { 103 to[index++] = B_HOST_TO_LENDIAN_INT16(c); 104 } else { 105 if (index + 1 >= maxToLength) break; 106 uint32 c2 = c - 0x10000; 107 uint16 w1 = 0xD800, w2 = 0xDC00; 108 w1 = w1 + ((c2 >> 10) & 0x3FF); 109 w2 = w2 + (c2 & 0x3FF); 110 to[index++] = B_HOST_TO_LENDIAN_INT16(w1); 111 to[index++] = B_HOST_TO_LENDIAN_INT16(w2); 112 } 113 } 114 115 if (index < maxToLength) 116 to[index++] = '\0'; 117 118 return index; 119 } 120 #endif // !_BOOT_MODE 121 122 123 const char* 124 get_partition_type(const guid_t& guid) 125 { 126 for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) { 127 if (kTypeMap[i].guid == guid) 128 return kTypeMap[i].type; 129 } 130 131 return NULL; 132 } 133 134 135 #ifndef _BOOT_MODE 136 bool 137 get_guid_for_partition_type(const char* type, guid_t& guid) 138 { 139 for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) { 140 if (strcmp(kTypeMap[i].type, type) == 0) { 141 guid = kTypeMap[i].guid; 142 return true; 143 } 144 } 145 146 return false; 147 } 148 #endif // !_BOOT_MODE 149