1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "TypeComponentPath.h"
8
9#include <stdio.h>
10
11#include <new>
12
13#include "StringUtils.h"
14
15
16// #pragma mark - TypeComponent
17
18
19bool
20TypeComponent::HasPrefix(const TypeComponent& other) const
21{
22	if (*this == other)
23		return true;
24
25	return componentKind == TYPE_COMPONENT_ARRAY_ELEMENT
26		&& other.componentKind == TYPE_COMPONENT_ARRAY_ELEMENT
27		&& name.Compare(other.name, other.name.Length()) == 0;
28}
29
30
31uint32
32TypeComponent::HashValue() const
33{
34	uint32 hash = ((uint32)index << 8) | (componentKind << 4) | typeKind;
35	return StringUtils::HashValue(name) * 13 + hash;
36}
37
38
39void
40TypeComponent::Dump() const
41{
42	switch (typeKind) {
43		case TYPE_PRIMITIVE:
44			printf("primitive");
45			break;
46		case TYPE_COMPOUND:
47			printf("compound");
48			break;
49		case TYPE_MODIFIED:
50			printf("modified");
51			break;
52		case TYPE_TYPEDEF:
53			printf("typedef");
54			break;
55		case TYPE_ADDRESS:
56			printf("address");
57			break;
58		case TYPE_ENUMERATION:
59			printf("enum");
60			break;
61		case TYPE_SUBRANGE:
62			printf("subrange");
63			break;
64		case TYPE_ARRAY:
65			printf("array");
66			break;
67		case TYPE_UNSPECIFIED:
68			printf("unspecified");
69			break;
70		case TYPE_FUNCTION:
71			printf("function");
72			break;
73		case TYPE_POINTER_TO_MEMBER:
74			printf("pointer to member");
75			break;
76	}
77
78	printf(" ");
79
80	switch (componentKind) {
81		case TYPE_COMPONENT_UNDEFINED:
82			printf("undefined");
83			break;
84		case TYPE_COMPONENT_BASE_TYPE:
85			printf("base %" B_PRIu64 " \"%s\"", index, name.String());
86			break;
87		case TYPE_COMPONENT_DATA_MEMBER:
88			printf("member %" B_PRIu64 " \"%s\"", index, name.String());
89			break;
90		case TYPE_COMPONENT_ARRAY_ELEMENT:
91			printf("element %" B_PRIu64 " \"%s\"", index, name.String());
92			break;
93	}
94}
95
96
97bool
98TypeComponent::operator==(const TypeComponent& other) const
99{
100	return componentKind == other.componentKind
101		&& typeKind == other.typeKind
102		&& index == other.index
103		&& name == other.name;
104}
105
106
107// #pragma mark - TypeComponentPath
108
109
110TypeComponentPath::TypeComponentPath()
111	:
112	fComponents(10, true)
113{
114}
115
116
117TypeComponentPath::TypeComponentPath(const TypeComponentPath& other)
118	:
119	fComponents(10, true)
120{
121	*this = other;
122}
123
124
125TypeComponentPath::~TypeComponentPath()
126{
127}
128
129
130int32
131TypeComponentPath::CountComponents() const
132{
133	return fComponents.CountItems();
134}
135
136
137TypeComponent
138TypeComponentPath::ComponentAt(int32 index) const
139{
140	TypeComponent* component = fComponents.ItemAt(index);
141	return component != NULL ? *component : TypeComponent();
142}
143
144
145bool
146TypeComponentPath::AddComponent(const TypeComponent& component)
147{
148	TypeComponent* myComponent = new(std::nothrow) TypeComponent(component);
149	if (myComponent == NULL || !fComponents.AddItem(myComponent)) {
150		delete myComponent;
151		return false;
152	}
153
154	return true;
155}
156
157
158void
159TypeComponentPath::Clear()
160{
161	fComponents.MakeEmpty();
162}
163
164
165TypeComponentPath*
166TypeComponentPath::CreateSubPath(int32 componentCount) const
167{
168	if (componentCount < 0 || componentCount > fComponents.CountItems())
169		componentCount = fComponents.CountItems();
170
171	TypeComponentPath* path = new(std::nothrow) TypeComponentPath;
172	if (path == NULL)
173		return NULL;
174	BReference<TypeComponentPath> pathReference(path, true);
175
176	for (int32 i = 0; i < componentCount; i++) {
177		if (!path->AddComponent(*fComponents.ItemAt(i)))
178			return NULL;
179	}
180
181	return pathReference.Detach();
182}
183
184
185uint32
186TypeComponentPath::HashValue() const
187{
188	int32 count = fComponents.CountItems();
189	if (count == 0)
190		return 0;
191
192	uint32 hash = fComponents.ItemAt(0)->HashValue();
193
194	for (int32 i = 1; i < count; i++)
195		hash = hash * 17 + fComponents.ItemAt(i)->HashValue();
196
197	return hash;
198}
199
200
201void
202TypeComponentPath::Dump() const
203{
204	int32 count = fComponents.CountItems();
205	for (int32 i = 0; i < count; i++) {
206		if (i == 0)
207			printf("[");
208		else
209			printf(" -> [");
210		fComponents.ItemAt(i)->Dump();
211		printf("]");
212	}
213}
214
215
216TypeComponentPath&
217TypeComponentPath::operator=(const TypeComponentPath& other)
218{
219	if (this != &other) {
220		fComponents.MakeEmpty();
221
222		for (int32 i = 0;
223				TypeComponent* component = other.fComponents.ItemAt(i); i++) {
224			if (!AddComponent(*component))
225				break;
226		}
227	}
228
229	return *this;
230}
231
232
233bool
234TypeComponentPath::operator==(const TypeComponentPath& other) const
235{
236	int32 count = fComponents.CountItems();
237	if (count != other.fComponents.CountItems())
238		return false;
239
240	for (int32 i = 0; i < count; i++) {
241		if (*fComponents.ItemAt(i) != *other.fComponents.ItemAt(i))
242			return false;
243	}
244
245	return true;
246}
247