//------------------------------------------------------------ //! Get the values for dimensions of the array. Assumes dimensions target is of length equal to rank //! Caller is expected to allocate an array dimensions of size array rank for the duration of function invocation. VIREO_EXPORT void Data_GetArrayDimensions(const void* pData, IntIndex dimensionsLengths[]) { TypedArrayCoreRef arrayObject = *(static_cast<const TypedArrayCoreRef*>(pData)); VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); for (int i = 0; i < arrayObject->Rank(); i++) { dimensionsLengths[i] = arrayObject->GetLength(i); } }
VIREO_FUNCTION_SIGNATURE3(FileRead, Int16, Int32, TypedArrayCoreRef) { Int16 handle = _Param(0); Int32 length = _Param(1); TypedArrayCoreRef data; if (_ParamPointer(2)) data = _Param(2); else return _NextInstruction(); PRGID PrgId = CurrentProgramId(); Int32 ISize; DESCR *pTmp; HANDLER arrayHandle; DSPSTAT DspStat; // Create a byte array to hold the data if (length < MIN_ARRAY_ELEMENTS) length = MIN_ARRAY_ELEMENTS; ISize = length * sizeof(DATA8) + sizeof(DESCR); if (cMemoryAlloc(PrgId, POOL_TYPE_MEMORY, (GBINDEX) ISize, (void**) &pTmp, &arrayHandle) == OK) { pTmp->Type = DATA_8; pTmp->ElementSize = (DATA8)sizeof(DATA8); pTmp->Elements = length; // Read the file into the array DspStat = cMemoryReadFile(PrgId, handle, length, DEL_NONE, pTmp->pArray); if (DspStat != FAILBREAK) { // If the array is not big enough, resize it if (data->Length() < length) data->Resize1D(length); // Copy into the output data array for (Int32 i = 0; i < length; i++) *data->BeginAt(i) = pTmp->pArray[i]; cMemoryFreeHandle(PrgId, arrayHandle); } } else DspStat = FAILBREAK; SetDispatchStatus(DspStat); return DspStat == BUSYBREAK ? _this : _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE4(ArrayReplaceSubset, TypedArrayCoreRef, TypedArrayCoreRef, Int32, TypedArrayCoreRef) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); Int32 idx = _Param(2); TypedArrayCoreRef subArray = _Param(3); VIREO_ASSERT(arrayOut != subArray); if(arrayOut != arrayIn){ arrayOut->Type()->CopyData(_ParamPointer(1), _ParamPointer(0)); } if(idx >= 0 && idx < arrayOut->Length()) { Int32 length = Min(subArray->Length(), arrayOut->Length() - idx); arrayIn->ElementType()->CopyData(subArray->BeginAt(0), arrayOut->BeginAt(idx), length); } return _NextInstruction(); }
//------------------------------------------------------------ VIREO_FUNCTION_SIGNATURE3(ArrayIndexElt, TypedArrayCoreRef, Int32, void) { TypedArrayCoreRef array = _Param(0); Int32 length = array->Length(); TypeRef elementType = array->ElementType(); Int32 index = _Param(1); if (_ParamPointer(2)) { if (index < 0 || index >= length) { elementType->InitData(_ParamPointer(2)); } else { elementType->CopyData(array->BeginAt(index), _ParamPointer(2)); } } return _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE4(ArrayInsertElt, TypedArrayCoreRef, TypedArrayCoreRef, Int32, void) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); Int32 length = arrayIn->Length(); Int32 index = (_ParamPointer(2) != null) ? _Param(2) : length; if(arrayOut != arrayIn) arrayOut->Type()->CopyData(_ParamPointer(1), _ParamPointer(0)); if (0 <= index && index <= length) arrayOut->Insert1D(index, 1, _ParamPointer(3)); return _NextInstruction(); }
//------------------------------------------------------------ //! Resizes a variable size Array symbol to have new dimension lengths specified by newLengths, it also initializes cells for non-flat data. VIREO_EXPORT EggShellResult EggShell_ResizeArray(TypeManagerRef tm, const TypeRef typeRef, const void* pData, Int32 rank, Int32 dimensionLengths[]) { TypeManagerScope scope(tm); if (typeRef == nullptr || !typeRef->IsValid()) return kEggShellResult_InvalidTypeRef; if (!typeRef->IsArray()) return kEggShellResult_UnexpectedObjectType; if (typeRef->Rank() != rank) return kEggShellResult_MismatchedArrayRank; TypedArrayCoreRef arrayObject = *(static_cast<const TypedArrayCoreRef*>(pData)); VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); if (!arrayObject->ResizeDimensions(rank, dimensionLengths, true, false)) { return kEggShellResult_UnableToCreateReturnBuffer; } return kEggShellResult_Success; }
VIREO_FUNCTION_SIGNATURE2(FileWrite, Int16, TypedArrayCoreRef) { Int16 handle = _Param(0); TypedArrayCoreRef data = _Param(1); Int32 length = data->Length(); PRGID PrgId = CurrentProgramId(); Int32 ISize; DESCR *pTmp; HANDLER arrayHandle; DSPSTAT DspStat; // Create a byte array to hold the data if (length < MIN_ARRAY_ELEMENTS) length = MIN_ARRAY_ELEMENTS; ISize = length * sizeof(DATA8) + sizeof(DESCR); if (cMemoryAlloc(PrgId, POOL_TYPE_MEMORY, (GBINDEX) ISize, (void**) &pTmp, &arrayHandle) == OK) { pTmp->Type = DATA_8; pTmp->ElementSize = (DATA8)sizeof(DATA8); pTmp->Elements = length; // Copy from the data array passed as an argument for (Int32 i = 0; i < length; i++) pTmp->pArray[i] = *data->BeginAt(i); // Write the array to the file DspStat = cMemoryWriteFile(PrgId, handle, length, DEL_NONE, pTmp->pArray); cMemoryFreeHandle(PrgId, arrayHandle); } else DspStat = FAILBREAK; SetDispatchStatus(DspStat); return DspStat == BUSYBREAK ? _this : _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE2(ArrayReverse, TypedArrayCoreRef, TypedArrayCoreRef) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); IntIndex arrayInLength = arrayIn->Length(); VIREO_ASSERT(arrayOut != arrayIn); arrayOut->Resize1D(arrayInLength); for (IntIndex i = 0; i < arrayInLength; i++) arrayOut->ElementType()->CopyData(arrayIn->BeginAt(i), arrayOut->BeginAt(arrayInLength - 1 - i)); return _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE3(ArrayRotate, TypedArrayCoreRef, TypedArrayCoreRef, Int32) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); Int32 offset = _Param(2); VIREO_ASSERT(arrayOut != arrayIn); IntIndex arrayInLength = arrayIn->Length(); arrayOut->Resize1D(arrayInLength); if (arrayInLength > 0) { offset = offset % arrayInLength; if (offset < 0) offset += arrayInLength; arrayOut->ElementType()->CopyData(arrayIn->BeginAt(0), arrayOut->BeginAt(offset), arrayInLength - offset); arrayOut->ElementType()->CopyData(arrayIn->BeginAt(arrayInLength - offset), arrayOut->BeginAt(0), offset); } return _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE4(ArraySubset, TypedArrayCoreRef, TypedArrayCoreRef, IntIndex, IntIndex) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); Int32 idx = (_ParamPointer(2) != null) ? _Param(2) : 0; idx = Max(idx, 0); // coerce index to non-negative integer VIREO_ASSERT(arrayOut != arrayIn || idx == 0); Int32 maxLen = arrayIn->Length() - idx; // calculate count from idx to end of array maxLen = Max(maxLen, 0); Int32 len = (_ParamPointer(3) != null) ? _Param(3) : maxLen; len = Max(len, 0); len = Min(len, maxLen); // coerce len to 0 .. maxLen arrayOut->Resize1D(len); if(idx < arrayIn->Length() && arrayOut != arrayIn) { arrayOut->ElementType()->CopyData(arrayIn->BeginAt(idx), arrayOut->BeginAt(0), len); } return _NextInstruction(); }
//------------------------------------------------------------ VIREO_FUNCTION_SIGNATURE4(ArrayReplaceElt, TypedArrayCoreRef, TypedArrayCoreRef, Int32, void) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); TypeRef elementType = arrayOut->ElementType(); Int32 index = _Param(2); Int32 length = arrayIn->Length(); if(arrayOut != arrayIn){ arrayOut->Type()->CopyData(_ParamPointer(1), _ParamPointer(0)); } if (index >= 0 && index < length) { void* pDest = arrayOut->BeginAt(index); elementType->CopyData(_ParamPointer(3), pDest); } return _NextInstruction(); }
//------------------------------------------------------------ VIREO_FUNCTION_SIGNATURE2(ArrayAppendElt, TypedArrayCoreRef, void) { TypedArrayCoreRef array = _Param(0); array->Insert1D(array->Length(), 1, _ParamPointer(1)); return _NextInstruction(); }
VIREO_FUNCTION_SIGNATURE4(ArrayInsertSubset, TypedArrayCoreRef, TypedArrayCoreRef, Int32, TypedArrayCoreRef) { TypedArrayCoreRef arrayOut = _Param(0); TypedArrayCoreRef arrayIn = _Param(1); IntIndex arrayInLength = arrayIn->Length(); Int32 idx = (_ParamPointer(2) != null) ? _Param(2) : arrayInLength; TypedArrayCoreRef subArray = _Param(3); IntIndex subArrayLength = subArray->Length(); VIREO_ASSERT(arrayOut != subArray); if (0 <= idx && idx <= arrayInLength) { if (arrayOut == arrayIn){ arrayOut->Insert1D(idx, subArrayLength, subArray->BeginAt(0)); } else { arrayOut->Resize1D(arrayInLength + subArrayLength); // Copy the original array up to the insert point arrayOut->ElementType()->CopyData(arrayIn->BeginAt(0), arrayOut->BeginAt(0), idx); // Copy the inserted subarray arrayOut->ElementType()->CopyData(subArray->BeginAt(0), arrayOut->BeginAt(idx), subArrayLength); // Copy the rest of the original array. arrayOut->ElementType()->CopyData(arrayIn->BeginAt(idx), arrayOut->BeginAt(idx + subArrayLength), arrayInLength - idx); } } else if (arrayOut != arrayIn) arrayOut->Type()->CopyData(_ParamPointer(1), _ParamPointer(0)); return _NextInstruction(); }
//------------------------------------------------------------ //! Get the total length for an array VIREO_EXPORT Int32 Data_GetArrayLength(const void* pData) { TypedArrayCoreRef arrayObject = *(static_cast<const TypedArrayCoreRef*>(pData)); VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); return arrayObject->Length(); }
//------------------------------------------------------------ //! Get the starting location of the first element of an Array / String type in memory // This function returns the start address of where elements would appear in memory (returns address even if length zero) VIREO_EXPORT void* Data_GetArrayBegin(const void* pData) { TypedArrayCoreRef arrayObject = *(static_cast<const TypedArrayCoreRef*>(pData)); VIREO_ASSERT(TypedArrayCore::ValidateHandle(arrayObject)); return arrayObject->BeginAt(0); }