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