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 23CStringValueNode::CStringValueNode(ValueNodeChild* nodeChild, 24 Type* type) 25 : 26 ChildlessValueNode(nodeChild), 27 fType(type) 28{ 29 fType->AcquireReference(); 30} 31 32 33CStringValueNode::~CStringValueNode() 34{ 35 fType->ReleaseReference(); 36} 37 38 39Type* 40CStringValueNode::GetType() const 41{ 42 return fType; 43} 44 45 46status_t 47CStringValueNode::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 error = valueLoader->LoadStringValue(addressData, maxSize, valueData); 88 if (error != B_OK) 89 return error; 90 91 piece.size = valueData.Length(); 92 93 ValueLocation* stringLocation = new(std::nothrow) ValueLocation( 94 valueLoader->GetArchitecture()->IsBigEndian(), piece); 95 96 if (stringLocation == NULL) 97 return B_NO_MEMORY; 98 99 BReference<ValueLocation> locationReference(stringLocation, true); 100 101 error = valueLoader->LoadStringValue(addressData, maxSize, valueData); 102 if (error != B_OK) 103 return error; 104 105 // create the type object 106 Value* value = new(std::nothrow) StringValue(valueData); 107 if (value == NULL) 108 return B_NO_MEMORY; 109 110 NodeChild()->SetLocation(stringLocation, B_OK); 111 _location = locationReference.Detach(); 112 _value = value; 113 return B_OK; 114} 115