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