1 /* 2 * Copyright 2010, Rene Gollent, rene@gollent.com 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "CStringValueNode.h" 8 9 #include <new> 10 11 #include "Architecture.h" 12 #include "StringValue.h" 13 #include "Tracing.h" 14 #include "Type.h" 15 #include "ValueLoader.h" 16 #include "ValueLocation.h" 17 #include "ValueNodeContainer.h" 18 19 20 // #pragma mark - CStringValueNode 21 22 23 CStringValueNode::CStringValueNode(ValueNodeChild* nodeChild, 24 Type* type) 25 : 26 ChildlessValueNode(nodeChild), 27 fType(type) 28 { 29 fType->AcquireReference(); 30 } 31 32 33 CStringValueNode::~CStringValueNode() 34 { 35 fType->ReleaseReference(); 36 } 37 38 39 Type* 40 CStringValueNode::GetType() const 41 { 42 return fType; 43 } 44 45 46 status_t 47 CStringValueNode::ResolvedLocationAndValue(ValueLoader* valueLoader, 48 ValueLocation*& _location, Value*& _value) 49 { 50 // get the location 51 ValueLocation* location = NodeChild()->Location(); 52 if (location == NULL) 53 return B_BAD_VALUE; 54 55 TRACE_LOCALS(" TYPE_ADDRESS (C string)\n"); 56 57 // get the value type 58 type_code valueType; 59 if (valueLoader->GetArchitecture()->AddressSize() == 4) { 60 valueType = B_UINT32_TYPE; 61 TRACE_LOCALS(" -> 32 bit\n"); 62 } else { 63 valueType = B_UINT64_TYPE; 64 TRACE_LOCALS(" -> 64 bit\n"); 65 } 66 67 // load the value data 68 69 BVariant addressData; 70 BString valueData; 71 status_t error = B_OK; 72 size_t maxSize = 255; 73 if (dynamic_cast<AddressType*>(fType) != NULL) { 74 error = valueLoader->LoadValue(location, valueType, false, 75 addressData); 76 if (error != B_OK) 77 return error; 78 } else { 79 addressData.SetTo(location->PieceAt(0).address); 80 maxSize = dynamic_cast<ArrayType*>(fType) 81 ->DimensionAt(0)->CountElements(); 82 } 83 84 ValuePieceLocation piece; 85 piece.SetToMemory(addressData.ToUInt64()); 86 87 TRACE_LOCALS(" Address found: %#" B_PRIx64 "\n", 88 addressData.ToUInt64()); 89 90 error = valueLoader->LoadStringValue(addressData, maxSize, valueData); 91 if (error != B_OK) 92 return error; 93 94 piece.size = valueData.Length(); 95 96 TRACE_LOCALS(" String value found, length: %" B_PRIu64 "bytes\n", 97 piece.size); 98 99 ValueLocation* stringLocation = new(std::nothrow) ValueLocation( 100 valueLoader->GetArchitecture()->IsBigEndian(), piece); 101 102 if (stringLocation == NULL) 103 return B_NO_MEMORY; 104 105 BReference<ValueLocation> locationReference(stringLocation, true); 106 107 error = valueLoader->LoadStringValue(addressData, maxSize, valueData); 108 if (error != B_OK) 109 return error; 110 111 // create the type object 112 Value* value = new(std::nothrow) StringValue(valueData); 113 if (value == NULL) 114 return B_NO_MEMORY; 115 116 NodeChild()->SetLocation(stringLocation, B_OK); 117 _location = locationReference.Detach(); 118 _value = value; 119 return B_OK; 120 } 121