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
20const guid_t kEmptyGUID = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
21
22
23static void
24put_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
37void
38to_utf8(const uint16* from, size_t maxFromLength, char* to, size_t toSize)
39{
40	for (uint32 i = 0; i < maxFromLength; i++) {
41		uint16 c = B_LENDIAN_TO_HOST_INT16(from[i]);
42		if (!c)
43			break;
44
45		if (c < 0x80)
46			put_utf8_byte(to, toSize, c);
47		else if (c < 0x800) {
48			put_utf8_byte(to, toSize, 0xc0 | (c >> 6));
49			put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
50		} else if (c < 0x10000) {
51			put_utf8_byte(to, toSize, 0xe0 | (c >> 12));
52			put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
53			put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
54		} else if (c <= 0x10ffff) {
55			put_utf8_byte(to, toSize, 0xf0 | (c >> 18));
56			put_utf8_byte(to, toSize, 0x80 | ((c >> 12) & 0x3f));
57			put_utf8_byte(to, toSize, 0x80 | ((c >> 6) & 0x3f));
58			put_utf8_byte(to, toSize, 0x80 | (c & 0x3f));
59		}
60	}
61
62	if (toSize > 0)
63		*to = '\0';
64}
65
66
67#ifndef _BOOT_MODE
68void
69to_ucs2(const char* from, size_t fromLength, uint16* to, size_t maxToLength)
70{
71	size_t index = 0;
72	while (from[0] != '\0' && index < maxToLength) {
73		// TODO: handle characters that are not representable in UCS-2 better
74		uint32 code = UTF8ToCharCode(&from);
75		if (code < 0x10000)
76			to[index++] = code;
77	}
78
79	if (index < maxToLength)
80		to[index] = '\0';
81}
82#endif // !_BOOT_MODE
83
84
85const char*
86get_partition_type(const guid_t& guid)
87{
88	for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
89		if (kTypeMap[i].guid == guid)
90			return kTypeMap[i].type;
91	}
92
93	return NULL;
94}
95
96
97#ifndef _BOOT_MODE
98bool
99get_guid_for_partition_type(const char* type, guid_t& guid)
100{
101	for (uint32 i = 0; i < sizeof(kTypeMap) / sizeof(kTypeMap[0]); i++) {
102		if (strcmp(kTypeMap[i].type, type) == 0) {
103			guid = kTypeMap[i].guid;
104			return true;
105		}
106	}
107
108	return false;
109}
110#endif // !_BOOT_MODE
111