status_t AbstractArrayValueNode::CreateChildrenInRange(int32 lowIndex, int32 highIndex) { // TODO: ensure that we don't already have children in the specified // index range. These need to be skipped if so. TRACE_LOCALS("TYPE_ARRAY\n"); int32 dimensionCount = fType->CountDimensions(); bool isFinalDimension = fDimension + 1 == dimensionCount; status_t error = B_OK; if (!fBoundsInitialized) { int32 lowerBound, upperBound; error = SupportedChildRange(lowerBound, upperBound); if (error != B_OK) return error; fLowerBound = lowerBound; fUpperBound = upperBound; fBoundsInitialized = true; } if (lowIndex < fLowerBound) lowIndex = fLowerBound; if (highIndex > fUpperBound) highIndex = fUpperBound; // create children for the array elements for (int32 i = lowIndex; i <= highIndex; i++) { BString name(Name()); name << '[' << i << ']'; if (name.Length() <= Name().Length()) return B_NO_MEMORY; AbstractArrayValueNodeChild* child; if (isFinalDimension) { child = new(std::nothrow) ArrayValueNodeChild(this, name, i, fType->BaseType()); } else { child = new(std::nothrow) InternalArrayValueNodeChild(this, name, i, fType); } if (child == NULL || !fChildren.AddItem(child)) { delete child; return B_NO_MEMORY; } child->SetContainer(fContainer); } if (fContainer != NULL) fContainer->NotifyValueNodeChildrenCreated(this); return B_OK; }
status_t AbstractArrayValueNode::CreateChildren() { if (!fChildren.IsEmpty()) return B_OK; TRACE_LOCALS("TYPE_ARRAY\n"); int32 dimensionCount = fType->CountDimensions(); bool isFinalDimension = fDimension + 1 == dimensionCount; ArrayDimension* dimension = fType->DimensionAt(fDimension); uint64 elementCount = dimension->CountElements(); if (elementCount == 0 || elementCount > kMaxArrayElementCount) elementCount = kMaxArrayElementCount; // create children for the array elements for (int32 i = 0; i < (int32)elementCount; i++) { BString name(Name()); name << '[' << i << ']'; if (name.Length() <= Name().Length()) return B_NO_MEMORY; AbstractArrayValueNodeChild* child; if (isFinalDimension) { child = new(std::nothrow) ArrayValueNodeChild(this, name, i, fType->BaseType()); } else { child = new(std::nothrow) InternalArrayValueNodeChild(this, name, i, fType); } if (child == NULL || !fChildren.AddItem(child)) { delete child; return B_NO_MEMORY; } child->SetContainer(fContainer); } if (fContainer != NULL) fContainer->NotifyValueNodeChildrenCreated(this); return B_OK; }
status_t ArrayValueNodeChild::ResolveLocation(ValueLoader* valueLoader, ValueLocation*& _location) { // get the parent (== array) location ValueLocation* parentLocation = fParent->Location(); if (parentLocation == NULL) return B_BAD_VALUE; // create an array index path ArrayType* arrayType = fParent->GetArrayType(); int32 dimensionCount = arrayType->CountDimensions(); // add dummy indices first -- we'll replace them on our way back through // our ancestors ArrayIndexPath indexPath; for (int32 i = 0; i < dimensionCount; i++) { if (!indexPath.AddIndex(0)) return B_NO_MEMORY; } AbstractArrayValueNodeChild* child = this; for (int32 i = dimensionCount - 1; i >= 0; i--) { indexPath.SetIndexAt(i, child->ElementIndex()); child = dynamic_cast<AbstractArrayValueNodeChild*>( child->ArrayParent()->NodeChild()); } // resolve the element location ValueLocation* location; status_t error = arrayType->ResolveElementLocation(indexPath, *parentLocation, location); if (error != B_OK) { TRACE_LOCALS("ArrayValueNodeChild::ResolveLocation(): " "ResolveElementLocation() failed: %s\n", strerror(error)); return error; } _location = location; return B_OK; }