int sci_matfile_varreadnext(char *fname, void* pvApiCtx)
{
    mat_t *matfile = NULL;
    matvar_t *matvar = NULL;
    int fileIndex = 0;
    int returnedClass = 0, var_type;
    int * fd_addr = NULL;
    double tmp_dbl;
    SciErr sciErr;

    CheckRhs(1, 1);
    CheckLhs(1, 3);

    /* Input argument is the index of the file to read */

    sciErr = getVarAddressFromPosition(pvApiCtx, 1, &fd_addr);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 0;
    }
    sciErr = getVarType(pvApiCtx, fd_addr, &var_type);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 0;
    }

    if (var_type == sci_matrix)
    {
        getScalarDouble(pvApiCtx, fd_addr, &tmp_dbl);
        if (!isScalar(pvApiCtx, fd_addr))
        {
            Scierror(999, _("%s: Wrong size for first input argument: Single double expected.\n"), fname);
            return FALSE;
        }
        fileIndex = (int)tmp_dbl;
    }
    else
    {
        Scierror(999, _("%s: Wrong type for first input argument: Double expected.\n"), fname);
        return FALSE;
    }

    /* Gets the corresponding matfile */
    matfile_manager(MATFILEMANAGER_GETFILE, &fileIndex, &matfile);

    if (matfile == NULL)
    {
        Scierror(999, _("%s: Invalid file identifier.\n"), fname);
        return FALSE;
    }

    matvar = Mat_VarReadNext(matfile);
    if ((matvar == NULL) || (matvar->name == NULL))
    {
        /* Return empty name */
        createSingleString(pvApiCtx, Rhs + 1, "\0");
        LhsVar(1) = Rhs + 1;

        if (Lhs >= 2)
        {
            /* Return empty value */
            createEmptyMatrix(pvApiCtx, Rhs + 2);
            LhsVar(2) = Rhs + 2;
        }

        if (Lhs == 3)
        {
            /* Return error flag instead of variable class */
            createScalarDouble(pvApiCtx, Rhs + 3, NO_MORE_VARIABLES);
            LhsVar(3) = Rhs + 3;
        }

        PutLhsVar();

        return TRUE;
    }

    /* To be sure isComplex is 0 or 1 */
    matvar->isComplex =  matvar->isComplex != 0;

    /* Return the variable name */
    createSingleString(pvApiCtx, Rhs + 1, matvar->name);
    LhsVar(1) = Rhs + 1;

    returnedClass = matvar->class_type;

    if (Lhs >= 2)
    {
        /* Return the values */
        if (!CreateMatlabVariable(pvApiCtx, Rhs + 2, matvar, NULL, -1)) /* Could not Create Variable */
        {
            sciprint("Do not know how to read a variable of class %d.\n", matvar->class_type);
            returnedClass = UNKNOWN_VARIABLE_TYPE;
        }
        LhsVar(2) = Rhs + 2;
    }

    if (Lhs == 3)
    {
        /* Create class return value */
        createScalarDouble(pvApiCtx, Rhs + 3, returnedClass);
        LhsVar(3) = Rhs + 3;
    }

    Mat_VarFree(matvar);
    PutLhsVar();
    return TRUE;
}
Example #2
0
int CreateCellVariable(int iVar, matvar_t *matVariable, int * parent, int item_position)
{
  static const char *fieldNames[] = {"ce", "dims","entries"};
  int nbFields = 3;
  int K = 0;
  int prodDims = 0;
  int valueIndex = 0, type;
  int * cell_addr = NULL;
  int * cell_entry_addr = NULL;
  matvar_t ** allData = NULL;
  SciErr _SciErr;

  /* Returned mlist initialization */
  if (parent==NULL)
    {
      _SciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr); MATIO_ERROR;
    }
  else
    {
      _SciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr); MATIO_ERROR;
    }
 
  /* FIRST LIST ENTRY: fieldnames */
  _SciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, (char **)fieldNames); MATIO_ERROR;
  
  /* SECOND LIST ENTRY: Dimensions (int32 type) */
  if(matVariable->rank==2) /* Two dimensions */
    {
      _SciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, matVariable->dims); MATIO_ERROR;
    }
  else /* 3 or more dimensions -> Scilab HyperMatrix */
    {
      type = I_INT32;
      CreateHyperMatrixVariable(iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE, 
				&type, &matVariable->rank, matVariable->dims, matVariable->data,
				NULL, cell_addr, 2);
    }

  /* ALL OTHER ENTRIES: Fields data */
  prodDims = 1;
  for (K=0; K<matVariable->rank; K++)
    {
      prodDims *= matVariable->dims[K];
    }

  allData = (matvar_t**) (matVariable->data);

  if (prodDims == 1) /* Scalar cell */
    {
      /* Create list entry in the stack */
      if (!CreateMatlabVariable(iVar, allData[0], cell_addr, 3)) /* Could not Create Variable */
	{
	  sciprint("Do not know how to read a variable of class %d.\n", allData[0]->class_type);
	}
    }
  else
    {
      _SciErr = createListInList(pvApiCtx, iVar, cell_addr, 3, prodDims, &cell_entry_addr); MATIO_ERROR;

      for (valueIndex = 0; valueIndex < prodDims; valueIndex++)
        {
          /* Create list entry in the stack */
          if (!CreateMatlabVariable(iVar, allData[valueIndex], cell_entry_addr, valueIndex+1)) /* Could not Create Variable */
            {
              sciprint("Do not know how to read a variable of class %d.\n", allData[valueIndex]->class_type);
            }
        }
    }
  
  return TRUE;
}
int CreateStructVariable(void *pvApiCtx, int iVar, matvar_t *matVariable, int * parent, int item_position)
{
    char **fieldNames = NULL;
    int nbFields = 0;
    int fieldIndex = 0;
    int K = 0;
    int prodDims = 0;
    int valueIndex = 0;
    matvar_t *fieldMatVar = NULL;
    matvar_t ** allData = NULL;
    int * cell_addr = NULL;
    int * cell_entry_addr = NULL;
    int type;
    SciErr sciErr;
    int *piDims = NULL;
    int i = 0;

    /* Fields of the struct */
    nbFields = 2; /* "st" "dims" */
    nbFields += Mat_VarGetNumberOfFields(matVariable);

    fieldNames = (char**) MALLOC(sizeof(char*) * nbFields);
    if (fieldNames == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }

    fieldNames[0] = strdup("st");
    if (fieldNames[0] == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }
    fieldNames[1] = strdup("dims");
    if (fieldNames[1] == NULL)
    {
        Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
        return FALSE;
    }

    for (fieldIndex = 1; fieldIndex < nbFields - 1; fieldIndex++)
    {
        fieldMatVar = Mat_VarGetStructField(matVariable, &fieldIndex, MAT_BY_INDEX, 0);
        fieldNames[fieldIndex + 1] = strdup(fieldMatVar->name);
        if (fieldNames[fieldIndex + 1] == NULL)
        {
            Scierror(999, _("%s: No more memory.\n"), "CreateStructVariable");
            return FALSE;
        }
    }

    /* Returned mlist initialization */
    if (parent == NULL)
    {
        sciErr = createMList(pvApiCtx, iVar, nbFields, &cell_addr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }
    else
    {
        sciErr = createMListInList(pvApiCtx, iVar, parent, item_position, nbFields, &cell_addr);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }

    /* FIRST LIST ENTRY: fieldnames */
    sciErr = createMatrixOfStringInList(pvApiCtx, iVar, cell_addr, 1, 1, nbFields, fieldNames);
    if (sciErr.iErr)
    {
        printError(&sciErr, 0);
        return 0;
    }

    /* SECOND LIST ENTRY: Dimensions (int32 type) */
    if (nbFields == 2) /* Empty struct must have size 0x0 in Scilab */
    {
        matVariable->dims[0] = 0;
        matVariable->dims[1] = 0;
    }

    piDims = (int *) MALLOC(matVariable->rank * sizeof(int));
    for (i = 0 ; i < matVariable->rank ; ++i)
    {
        piDims[i] = (int)matVariable->dims[i];
    }

    if (matVariable->rank == 2) /* Two dimensions */
    {
        sciErr = createMatrixOfInteger32InList(pvApiCtx, iVar, cell_addr, 2, 1, matVariable->rank, piDims);
        if (sciErr.iErr)
        {
            printError(&sciErr, 0);
            return 0;
        }
    }
    else /* 3 or more dimensions -> Scilab HyperMatrix */
    {
        type = I_INT32;
        CreateHyperMatrixVariable(pvApiCtx, iVar, MATRIX_OF_VARIABLE_SIZE_INTEGER_DATATYPE,
                                  &type, &matVariable->rank, piDims, (double*)matVariable->data,
                                  NULL, cell_addr, 2);
    }

    FREE(piDims);

    /* ALL OTHER ENTRIES: Fields data */
    prodDims = 1;
    for (K = 0; K < matVariable->rank; K++)
    {
        prodDims *= (int)matVariable->dims[K];
    }

    allData = (matvar_t**) (matVariable->data);

    if (prodDims == 1) /* Scalar struct */
    {
        for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
        {
            /* Create list entry in the stack */
            if (!CreateMatlabVariable(pvApiCtx, iVar, allData[fieldIndex], cell_addr, fieldIndex + 3)) /* Could not Create Variable */
            {
                if (allData[fieldIndex]->class_type != 0) /* class is 0 for not initialized fields */
                {
                    sciprint("Do not know how to read a variable of class %d.\n", allData[fieldIndex]->class_type);
                }
            }
        }
    }
    else
    {
        for (fieldIndex = 0; fieldIndex < nbFields - 2; fieldIndex++)
        {
            sciErr = createListInList(pvApiCtx, iVar, cell_addr, fieldIndex + 3, prodDims, &cell_entry_addr);
            if (sciErr.iErr)
            {
                printError(&sciErr, 0);
                return 0;
            }

            for (valueIndex = 0; valueIndex < prodDims; valueIndex++)
            {
                /* Create list entry in the stack */
                if (!CreateMatlabVariable(pvApiCtx, iVar, allData[(fieldIndex) + (nbFields - 2)*valueIndex], cell_entry_addr, valueIndex + 1)) /* Could not Create Variable */
                {
                    if (allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type != 0) /* class is 0 for not initialized fields */
                    {
                        sciprint("Do not know how to read a variable of class %d.\n", allData[(fieldIndex) + (nbFields - 2)*valueIndex]->class_type);
                    }
                }
            }
        }
    }

    freeArrayOfString(fieldNames, nbFields);

    return TRUE;
}