Example #1
0
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;
}