* isnum has been redesigned in native code. Up to 130x performance
[scilab.git] / scilab / modules / spreadsheet / src / c / getRange.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010-2011 - DIGITEO - Allan CORNET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12 #include <string.h>
13 #include "MALLOC.h"
14 #include "getRange.h"
15 #ifdef _MSC_VER
16 #include "strdup_windows.h"
17 #endif
18 // =============================================================================
19 #define SIZE_ARRAY_RANGE 4
20 // =============================================================================
21 static int getRangeSize(int *lowCoord, int *highCoord, int maxCoord);
22 // =============================================================================
23 void getSubIndices(const int *iRange, int * R1, int * R2, int * C1, int * C2 )
24 {
25     *R1 = iRange[0];
26     *C1 = iRange[1];
27     *R2 = iRange[2];
28     *C2 = iRange[3];
29
30     return;
31 }
32 // =============================================================================
33 int isValidRange(const int *iRange, int sizeArray)
34 {
35     int i = 0;
36     int R1 = 0, C1 = 0, R2 = 0, C2 = 0;
37
38     if (iRange == NULL)
39     {
40         return 0;
41     }
42
43     getSubIndices(iRange, &R1, &R2, &C1, &C2 );
44
45     if (sizeArray != SIZE_ARRAY_RANGE)
46     {
47         return 0;
48     }
49
50     if (R1 <= 0)
51     {
52         return 0;
53     }
54     if (R2 <= 0)
55     {
56         return 0;
57     }
58     if (C1 <= 0)
59     {
60         return 0;
61     }
62     if (C2 <= 0)
63     {
64         return 0;
65     }
66     if (R1 > R2)
67     {
68         return 0;
69     }
70     if (C1 > C2)
71     {
72         return 0;
73     }
74
75     return 1;
76 }
77 // =============================================================================
78 char **getRangeAsString(const char **pStrsValues,
79                         int nbRows, int nbCols,
80                         const int *iRange,
81                         int *returnedNbRows, int *returnedNbCols)
82 {
83     if (isValidRange(iRange, SIZE_ARRAY_RANGE))
84     {
85         int R1, C1, R2, C2;
86         int rangeSize;
87
88         getSubIndices(iRange, &R1, &R2, &C1, &C2);
89
90         *returnedNbRows = getRangeSize(&R1, &R2, nbRows);
91         *returnedNbCols = getRangeSize(&C1, &C2, nbCols);
92
93         rangeSize = (*returnedNbRows) * (*returnedNbCols);
94         if (rangeSize > 0)
95         {
96             char **newStrArray = (char**)MALLOC(sizeof(char*) * rangeSize);
97             if (newStrArray != NULL)
98             {
99                 int i = 0;
100                 int j = 0;
101                 int k = 0;
102
103                 for (j = C1 - 1 ; j < C2 ; j++)
104                 {
105                     for (i = R1 - 1 ; i < R2 ; i++ )
106                     {
107                         newStrArray[k] = strdup(pStrsValues[i + nbRows * j]);
108                         k++;
109                     }
110                 }
111             }
112             return newStrArray;
113         }
114         // range is empty, calling function should raise an out of bound error
115     }
116     return NULL;
117 }
118 // =============================================================================
119 complexArray *getRangeAsComplexArray(const complexArray *pComplex,
120         int nbRows, int nbCols,
121         const int *iRange,
122         int *returnedNbRows, int *returnedNbCols)
123 {
124     if (isValidRange(iRange, SIZE_ARRAY_RANGE))
125     {
126         int R1, C1, R2, C2;
127         int rangeSize;
128
129         getSubIndices(iRange, &R1, &R2, &C1, &C2 );
130
131         *returnedNbRows = getRangeSize(&R1, &R2, nbRows);
132         *returnedNbCols = getRangeSize(&C1, &C2, nbCols);
133
134         rangeSize = (*returnedNbRows) * (*returnedNbCols);
135         if (rangeSize > 0)
136         {
137             complexArray *newComplexArray =
138                 createComplexArrayEmpty(rangeSize);
139             if (newComplexArray != NULL)
140             {
141                 int i = 0;
142                 int j = 0;
143                 int k = 0;
144
145                 newComplexArray->isComplex = pComplex->isComplex;
146
147                 for (j = C1 - 1 ; j < C2 ; j++)
148                 {
149                     for (i = R1 - 1 ; i < R2 ; i++)
150                     {
151                         newComplexArray->realPart[k] = pComplex->realPart[i + (nbRows * j)];
152                         if (pComplex->isComplex)
153                         {
154                             newComplexArray->imagPart[k] = pComplex->imagPart[i + (nbRows * j)];
155                         }
156                         k++;
157                     }
158                 }
159             }
160             return newComplexArray;
161         }
162         // range is empty, calling function should raise an out of bound error
163     }
164     return NULL;
165 }
166 // =============================================================================
167 static int getRangeSize(int *lowCoord, int *highCoord, int maxCoord)
168 {
169     // IsValidRange has done all checks of range, except on right bound
170     if (*lowCoord <= maxCoord)
171     {
172         if (*highCoord > maxCoord)
173         {
174             *highCoord = maxCoord;
175         }
176         return *highCoord - *lowCoord + 1;
177     }
178     // lower coord is out of bound
179     return 0;
180 }
181 // =============================================================================