Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: OpenGIS Simple Features Reference Implementation
4 : * Purpose: C MiraMon code adapted to be used in GDAL
5 : * Author: Abel Pau, a.pau@creaf.uab.cat, based on the MiraMon codes,
6 : * mainly written by Xavier Pons, Joan Maso (correctly written
7 : * "Mas0xF3"), Abel Pau, Nuria Julia (N0xFAria Juli0xE0),
8 : * Xavier Calaf, Lluis (Llu0xEDs) Pesquer and Alaitz Zabala, from
9 : * CREAF and Universitat Autonoma (Aut0xF2noma) de Barcelona.
10 : * For a complete list of contributors:
11 : * https://www.miramon.cat/eng/QuiSom.htm
12 : ******************************************************************************
13 : * Copyright (c) 2024, Xavier Pons
14 : *
15 : * SPDX-License-Identifier: MIT
16 : ****************************************************************************/
17 :
18 : #ifdef GDAL_COMPILATION
19 : #include "ogr_api.h" // For CPL_C_START
20 : #include "mm_gdal_functions.h" // For CPLStrlcpy()
21 : #include "mm_wrlayr.h" // For calloc_function()...
22 : #else
23 : #include "CmptCmp.h"
24 : #include "mm_gdal\mm_gdal_functions.h" // For CPLStrlcpy()
25 : #include "mm_gdal\mm_wrlayr.h" // For calloc_function()...
26 : #endif // GDAL_COMPILATION
27 :
28 : #ifdef GDAL_COMPILATION
29 : CPL_C_START // Necessary for compiling in GDAL project
30 : #include "cpl_string.h" // For CPL_ENC_UTF8
31 : #else
32 : #ifdef _WIN64
33 : #include "gdal\release-1911-x64\cpl_string.h" // For CPL_ENC_UTF8
34 : #else
35 : #include "gdal\release-1911-32\cpl_string.h" // For CPL_ENC_UTF8
36 : #endif
37 : #endif
38 :
39 : char szInternalGraphicIdentifierEng[MM_MAX_IDENTIFIER_SIZE];
40 : char szInternalGraphicIdentifierCat[MM_MAX_IDENTIFIER_SIZE];
41 : char szInternalGraphicIdentifierSpa[MM_MAX_IDENTIFIER_SIZE];
42 :
43 : char szNumberOfVerticesEng[MM_MAX_IDENTIFIER_SIZE];
44 : char szNumberOfVerticesCat[MM_MAX_IDENTIFIER_SIZE];
45 : char szNumberOfVerticesSpa[MM_MAX_IDENTIFIER_SIZE];
46 :
47 : char szLengthOfAarcEng[MM_MAX_IDENTIFIER_SIZE];
48 : char szLengthOfAarcCat[MM_MAX_IDENTIFIER_SIZE];
49 : char szLengthOfAarcSpa[MM_MAX_IDENTIFIER_SIZE];
50 :
51 : char szInitialNodeEng[MM_MAX_IDENTIFIER_SIZE];
52 : char szInitialNodeCat[MM_MAX_IDENTIFIER_SIZE];
53 : char szInitialNodeSpa[MM_MAX_IDENTIFIER_SIZE];
54 :
55 : char szFinalNodeEng[MM_MAX_IDENTIFIER_SIZE];
56 : char szFinalNodeCat[MM_MAX_IDENTIFIER_SIZE];
57 : char szFinalNodeSpa[MM_MAX_IDENTIFIER_SIZE];
58 :
59 : char szNumberOfArcsToNodeEng[MM_MAX_IDENTIFIER_SIZE];
60 : char szNumberOfArcsToNodeCat[MM_MAX_IDENTIFIER_SIZE];
61 : char szNumberOfArcsToNodeSpa[MM_MAX_IDENTIFIER_SIZE];
62 :
63 : char szNodeTypeEng[MM_MAX_IDENTIFIER_SIZE];
64 : char szNodeTypeCat[MM_MAX_IDENTIFIER_SIZE];
65 : char szNodeTypeSpa[MM_MAX_IDENTIFIER_SIZE];
66 :
67 : char szPerimeterOfThePolygonEng[MM_MAX_IDENTIFIER_SIZE];
68 : char szPerimeterOfThePolygonCat[MM_MAX_IDENTIFIER_SIZE];
69 : char szPerimeterOfThePolygonSpa[MM_MAX_IDENTIFIER_SIZE];
70 :
71 : char szAreaOfThePolygonEng[MM_MAX_IDENTIFIER_SIZE];
72 : char szAreaOfThePolygonCat[MM_MAX_IDENTIFIER_SIZE];
73 : char szAreaOfThePolygonSpa[MM_MAX_IDENTIFIER_SIZE];
74 :
75 : char szNumberOfArcsEng[MM_MAX_IDENTIFIER_SIZE];
76 : char szNumberOfArcsCat[MM_MAX_IDENTIFIER_SIZE];
77 : char szNumberOfArcsSpa[MM_MAX_IDENTIFIER_SIZE];
78 :
79 : char szNumberOfElementaryPolygonsEng[MM_MAX_IDENTIFIER_SIZE];
80 : char szNumberOfElementaryPolygonsCat[MM_MAX_IDENTIFIER_SIZE];
81 : char szNumberOfElementaryPolygonsSpa[MM_MAX_IDENTIFIER_SIZE];
82 :
83 328 : void MM_FillFieldDescriptorByLanguage(void)
84 : {
85 328 : CPLStrlcpy(szInternalGraphicIdentifierEng, "Internal Graphic identifier",
86 : MM_MAX_IDENTIFIER_SIZE);
87 328 : CPLStrlcpy(szInternalGraphicIdentifierCat, "Identificador Grafic intern",
88 : MM_MAX_IDENTIFIER_SIZE);
89 328 : *(unsigned char *)&szInternalGraphicIdentifierCat[16] = MM_a_WITH_GRAVE;
90 328 : CPLStrlcpy(szInternalGraphicIdentifierSpa, "Identificador Grafico interno",
91 : MM_MAX_IDENTIFIER_SIZE);
92 328 : *(unsigned char *)&szInternalGraphicIdentifierSpa[16] = MM_a_WITH_ACUTE;
93 :
94 328 : CPLStrlcpy(szNumberOfVerticesEng, "Number of vertices",
95 : MM_MAX_IDENTIFIER_SIZE);
96 328 : CPLStrlcpy(szNumberOfVerticesCat, "Nombre de vertexs",
97 : MM_MAX_IDENTIFIER_SIZE);
98 328 : CPLStrlcpy(szNumberOfVerticesSpa, "Numero de vertices",
99 : MM_MAX_IDENTIFIER_SIZE);
100 328 : *(unsigned char *)&szNumberOfVerticesCat[11] = MM_e_WITH_GRAVE;
101 328 : *(unsigned char *)&szNumberOfVerticesSpa[1] = MM_u_WITH_ACUTE;
102 328 : *(unsigned char *)&szNumberOfVerticesSpa[11] = MM_e_WITH_ACUTE;
103 :
104 328 : CPLStrlcpy(szLengthOfAarcEng, "Length of arc", MM_MAX_IDENTIFIER_SIZE);
105 328 : CPLStrlcpy(szLengthOfAarcCat, "Longitud de l'arc", MM_MAX_IDENTIFIER_SIZE);
106 328 : CPLStrlcpy(szLengthOfAarcSpa, "Longitud del arco", MM_MAX_IDENTIFIER_SIZE);
107 :
108 328 : CPLStrlcpy(szInitialNodeEng, "Initial node", MM_MAX_IDENTIFIER_SIZE);
109 328 : CPLStrlcpy(szInitialNodeCat, "Node inicial", MM_MAX_IDENTIFIER_SIZE);
110 328 : CPLStrlcpy(szInitialNodeSpa, "Nodo inicial", MM_MAX_IDENTIFIER_SIZE);
111 :
112 328 : CPLStrlcpy(szFinalNodeEng, "Final node", MM_MAX_IDENTIFIER_SIZE);
113 328 : CPLStrlcpy(szFinalNodeCat, "Node final", MM_MAX_IDENTIFIER_SIZE);
114 328 : CPLStrlcpy(szFinalNodeSpa, "Nodo final", MM_MAX_IDENTIFIER_SIZE);
115 :
116 328 : CPLStrlcpy(szNumberOfArcsToNodeEng, "Number of arcs to node",
117 : MM_MAX_IDENTIFIER_SIZE);
118 328 : CPLStrlcpy(szNumberOfArcsToNodeCat, "Nombre d'arcs al node",
119 : MM_MAX_IDENTIFIER_SIZE);
120 328 : CPLStrlcpy(szNumberOfArcsToNodeSpa, "Numero de arcos al nodo",
121 : MM_MAX_IDENTIFIER_SIZE);
122 328 : *(unsigned char *)&szNumberOfArcsToNodeSpa[1] = MM_u_WITH_ACUTE;
123 :
124 328 : CPLStrlcpy(szNodeTypeEng, "Node type", MM_MAX_IDENTIFIER_SIZE);
125 328 : CPLStrlcpy(szNodeTypeCat, "Tipus de node", MM_MAX_IDENTIFIER_SIZE);
126 328 : CPLStrlcpy(szNodeTypeSpa, "Tipo de nodo", MM_MAX_IDENTIFIER_SIZE);
127 :
128 328 : CPLStrlcpy(szPerimeterOfThePolygonEng, "Perimeter of the polygon",
129 : MM_MAX_IDENTIFIER_SIZE);
130 328 : CPLStrlcpy(szPerimeterOfThePolygonCat, "Perimetre del poligon",
131 : MM_MAX_IDENTIFIER_SIZE);
132 328 : CPLStrlcpy(szPerimeterOfThePolygonSpa, "Perimetro del poligono",
133 : MM_MAX_IDENTIFIER_SIZE);
134 :
135 328 : *(unsigned char *)&szPerimeterOfThePolygonCat[3] = MM_i_WITH_ACUTE;
136 328 : *(unsigned char *)&szPerimeterOfThePolygonSpa[3] = MM_i_WITH_ACUTE;
137 328 : *(unsigned char *)&szPerimeterOfThePolygonCat[17] = MM_i_WITH_ACUTE;
138 328 : *(unsigned char *)&szPerimeterOfThePolygonSpa[17] = MM_i_WITH_ACUTE;
139 :
140 328 : CPLStrlcpy(szAreaOfThePolygonEng, "Area of the polygon",
141 : MM_MAX_IDENTIFIER_SIZE);
142 328 : CPLStrlcpy(szAreaOfThePolygonCat, "Area del poligon",
143 : MM_MAX_IDENTIFIER_SIZE);
144 328 : CPLStrlcpy(szAreaOfThePolygonSpa, "Area del poligono",
145 : MM_MAX_IDENTIFIER_SIZE);
146 :
147 328 : *(unsigned char *)&szAreaOfThePolygonCat[0] = MM_A_WITH_GRAVE;
148 328 : *(unsigned char *)&szAreaOfThePolygonSpa[0] = MM_A_WITH_ACUTE;
149 328 : *(unsigned char *)&szAreaOfThePolygonCat[12] = MM_i_WITH_ACUTE;
150 328 : *(unsigned char *)&szAreaOfThePolygonSpa[12] = MM_i_WITH_ACUTE;
151 :
152 328 : CPLStrlcpy(szNumberOfArcsEng, "Number of arcs", MM_MAX_IDENTIFIER_SIZE);
153 328 : CPLStrlcpy(szNumberOfArcsCat, "Nombre d'arcs", MM_MAX_IDENTIFIER_SIZE);
154 328 : CPLStrlcpy(szNumberOfArcsSpa, "Numero de arcos", MM_MAX_IDENTIFIER_SIZE);
155 :
156 328 : *(unsigned char *)&szNumberOfArcsSpa[1] = MM_u_WITH_ACUTE;
157 :
158 328 : CPLStrlcpy(szNumberOfElementaryPolygonsEng, "Number of elementary polygons",
159 : MM_MAX_IDENTIFIER_SIZE);
160 328 : CPLStrlcpy(szNumberOfElementaryPolygonsCat, "Nombre de poligons elementals",
161 : MM_MAX_IDENTIFIER_SIZE);
162 328 : CPLStrlcpy(szNumberOfElementaryPolygonsSpa,
163 : "Numero de poligonos elementales", MM_MAX_IDENTIFIER_SIZE);
164 :
165 328 : *(unsigned char *)&szNumberOfElementaryPolygonsSpa[1] = MM_u_WITH_ACUTE;
166 328 : *(unsigned char *)&szNumberOfElementaryPolygonsCat[13] = MM_i_WITH_ACUTE;
167 328 : *(unsigned char *)&szNumberOfElementaryPolygonsSpa[13] = MM_i_WITH_ACUTE;
168 328 : }
169 :
170 : const char *MM_pszLogFilename = nullptr;
171 :
172 : static const char MM_EmptyString[] = {""};
173 : #define MM_SetEndOfString (*MM_EmptyString)
174 :
175 1516 : void fclose_and_nullify(FILE_TYPE **pFunc)
176 : {
177 1516 : if (!pFunc || !(*pFunc))
178 355 : return;
179 1161 : fclose_function(*pFunc);
180 1161 : *pFunc = nullptr;
181 : }
182 :
183 : // CREATING AN EXTENDED MIRAMON DBF
184 4108 : void MM_InitializeField(struct MM_FIELD *pField)
185 : {
186 4108 : memset(pField, '\0', sizeof(*pField));
187 4108 : pField->FieldType = 'C';
188 4108 : pField->GeoTopoTypeField = MM_NO_ES_CAMP_GEOTOPO;
189 4108 : }
190 :
191 : #define MM_ACCEPTABLE_NUMBER_OF_FIELDS 20000
192 :
193 306 : struct MM_FIELD *MM_CreateAllFields(MM_EXT_DBF_N_FIELDS nFields)
194 : {
195 : struct MM_FIELD *camp;
196 : MM_EXT_DBF_N_FIELDS i;
197 :
198 : // MiraMon could accept a number of fields 13.4 million
199 : // but GDAL prefers to limit that to 20.000 to avoid
200 : // too large memory allocation attempts with corrupted datasets
201 306 : if (nFields > MM_ACCEPTABLE_NUMBER_OF_FIELDS)
202 : {
203 0 : MMCPLError(CE_Failure, CPLE_OutOfMemory,
204 : "More than 20000 fields not accepted");
205 0 : return nullptr;
206 : }
207 :
208 : #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
209 306 : if (nFields >= UINT32_MAX / sizeof(*camp))
210 0 : return nullptr;
211 : #else
212 : if (nFields >= (1000U * 1000 * 1000) / sizeof(*camp))
213 : return nullptr;
214 : #endif
215 :
216 306 : if ((camp = calloc_function(nFields * sizeof(*camp))) == nullptr)
217 0 : return nullptr;
218 :
219 2613 : for (i = 0; i < nFields; i++)
220 2307 : MM_InitializeField(camp + i);
221 306 : return camp;
222 : }
223 :
224 191 : static struct MM_DATA_BASE_XP *MM_CreateEmptyHeader(MM_EXT_DBF_N_FIELDS nFields)
225 : {
226 : struct MM_DATA_BASE_XP *data_base_XP;
227 :
228 191 : if ((data_base_XP = (struct MM_DATA_BASE_XP *)calloc_function(
229 : sizeof(struct MM_DATA_BASE_XP))) == nullptr)
230 0 : return nullptr;
231 :
232 191 : if (nFields == 0)
233 : {
234 : ;
235 : }
236 : else
237 : {
238 191 : data_base_XP->pField = (struct MM_FIELD *)MM_CreateAllFields(nFields);
239 191 : if (!data_base_XP->pField)
240 : {
241 0 : free_function(data_base_XP);
242 0 : return nullptr;
243 : }
244 : }
245 191 : data_base_XP->nFields = nFields;
246 191 : return data_base_XP;
247 : }
248 :
249 191 : struct MM_DATA_BASE_XP *MM_CreateDBFHeader(MM_EXT_DBF_N_FIELDS n_camps,
250 : MM_BYTE charset)
251 : {
252 : struct MM_DATA_BASE_XP *bd_xp;
253 : struct MM_FIELD *camp;
254 : MM_EXT_DBF_N_FIELDS i;
255 :
256 191 : if (nullptr == (bd_xp = MM_CreateEmptyHeader(n_camps)))
257 0 : return nullptr;
258 :
259 191 : bd_xp->CharSet = charset;
260 :
261 191 : strcpy(bd_xp->ReadingMode, "a+b");
262 :
263 191 : bd_xp->IdGraficField = n_camps;
264 191 : bd_xp->IdEntityField = MM_MAX_EXT_DBF_N_FIELDS_TYPE;
265 191 : bd_xp->dbf_version = (MM_BYTE)((n_camps > MM_MAX_N_CAMPS_DBF_CLASSICA)
266 : ? MM_MARCA_VERSIO_1_DBF_ESTESA
267 : : MM_MARCA_DBASE4);
268 :
269 1417 : for (i = 0, camp = bd_xp->pField; i < n_camps; i++, camp++)
270 : {
271 1226 : MM_InitializeField(camp);
272 1226 : if (i < 99999)
273 1226 : snprintf(camp->FieldName, sizeof(camp->FieldName), "CAMP%05u",
274 1226 : (unsigned)(i + 1));
275 : else
276 0 : snprintf(camp->FieldName, sizeof(camp->FieldName), "CM%u",
277 0 : (unsigned)(i + 1));
278 1226 : camp->FieldType = 'C';
279 1226 : camp->DecimalsIfFloat = 0;
280 1226 : camp->BytesPerField = 50;
281 : }
282 191 : return bd_xp;
283 : }
284 :
285 1226 : static MM_BYTE MM_GetDefaultDesiredDBFFieldWidth(const struct MM_FIELD *camp)
286 : {
287 : size_t a, b, c, d, e;
288 :
289 1226 : b = strlen(camp->FieldName);
290 1226 : c = strlen(camp->FieldDescription[0]);
291 :
292 1226 : if (camp->FieldType == 'D')
293 : {
294 68 : d = (b > c ? b : c);
295 68 : a = (size_t)camp->BytesPerField + 2;
296 68 : return (MM_BYTE)(a > d ? a : d);
297 : }
298 1158 : a = camp->BytesPerField;
299 1158 : d = (unsigned int)(b > c ? b : c);
300 1158 : e = (a > d ? a : d);
301 1158 : return (MM_BYTE)(e < 80 ? e : 80);
302 : }
303 :
304 9063 : static MM_BOOLEAN MM_is_field_name_lowercase(const char *szChain)
305 : {
306 : const char *p;
307 :
308 56071 : for (p = szChain; *p; p++)
309 : {
310 50335 : if ((*p >= 'a' && *p <= 'z'))
311 3327 : return TRUE;
312 : }
313 5736 : return FALSE;
314 : }
315 :
316 : static MM_BOOLEAN
317 9095 : MM_Is_classical_DBF_field_name_or_lowercase(const char *szChain)
318 : {
319 : const char *p;
320 :
321 76551 : for (p = szChain; *p; p++)
322 : {
323 67488 : if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z') ||
324 6275 : (*p >= '0' && *p <= '9') || *p == '_')
325 : ;
326 : else
327 32 : return FALSE;
328 : }
329 9063 : if (szChain[0] == '_')
330 0 : return FALSE;
331 9063 : return TRUE;
332 : }
333 :
334 : static MM_BOOLEAN
335 81431 : MM_Is_character_valid_for_extended_DBF_field_name(int valor,
336 : int *valor_substitut)
337 : {
338 81431 : if (valor_substitut)
339 : {
340 0 : switch (valor)
341 : {
342 0 : case 32:
343 0 : *valor_substitut = '_';
344 0 : return FALSE;
345 0 : case 91:
346 0 : *valor_substitut = '(';
347 0 : return FALSE;
348 0 : case 93:
349 0 : *valor_substitut = ')';
350 0 : return FALSE;
351 0 : case 96:
352 0 : *valor_substitut = '\'';
353 0 : return FALSE;
354 0 : case 127:
355 0 : *valor_substitut = '_';
356 0 : return FALSE;
357 0 : case 168:
358 0 : *valor_substitut = '-';
359 0 : return FALSE;
360 : }
361 : }
362 : else
363 : {
364 81431 : if (valor < 32 || valor == 91 || valor == 93 || valor == 96 ||
365 81431 : valor == 127 || valor == 168)
366 0 : return FALSE;
367 : }
368 81431 : return TRUE;
369 : }
370 :
371 10213 : static int MM_ISExtendedNameBD_XP(const char *nom_camp)
372 : {
373 : size_t mida, j;
374 :
375 10213 : mida = strlen(nom_camp);
376 10213 : if (mida >= MM_MAX_LON_FIELD_NAME_DBF)
377 0 : return MM_DBF_NAME_NO_VALID;
378 :
379 91644 : for (j = 0; j < mida; j++)
380 : {
381 81431 : if (!MM_Is_character_valid_for_extended_DBF_field_name(
382 81431 : (unsigned char)nom_camp[j], nullptr))
383 0 : return MM_DBF_NAME_NO_VALID;
384 : }
385 :
386 10213 : if (mida >= MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF)
387 1118 : return MM_VALID_EXTENDED_DBF_NAME;
388 :
389 9095 : if (!MM_Is_classical_DBF_field_name_or_lowercase(nom_camp))
390 32 : return MM_VALID_EXTENDED_DBF_NAME;
391 :
392 9063 : if (MM_is_field_name_lowercase(nom_camp))
393 3327 : return MM_DBF_NAME_LOWERCASE_AND_VALID;
394 :
395 5736 : return NM_CLASSICAL_DBF_AND_VALID_NAME;
396 : }
397 :
398 530 : static MM_BYTE MM_CalculateBytesExtendedFieldName(struct MM_FIELD *camp)
399 : {
400 530 : camp->reserved_2[MM_OFFSET_RESERVED2_EXTENDED_NAME_SIZE] =
401 530 : (MM_BYTE)strlen(camp->FieldName);
402 530 : return MM_DonaBytesNomEstesCamp(camp);
403 : }
404 :
405 : static MM_ACCUMULATED_BYTES_TYPE_DBF
406 191 : MM_CalculateBytesExtendedFieldNames(const struct MM_DATA_BASE_XP *bd_xp)
407 : {
408 191 : MM_ACCUMULATED_BYTES_TYPE_DBF bytes_acumulats = 0;
409 : MM_EXT_DBF_N_FIELDS i_camp;
410 :
411 1417 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
412 : {
413 1226 : if (MM_VALID_EXTENDED_DBF_NAME ==
414 1226 : MM_ISExtendedNameBD_XP(bd_xp->pField[i_camp].FieldName))
415 91 : bytes_acumulats +=
416 91 : MM_CalculateBytesExtendedFieldName(bd_xp->pField + i_camp);
417 : }
418 :
419 191 : return bytes_acumulats;
420 : }
421 :
422 : static MM_FIRST_RECORD_OFFSET_TYPE
423 191 : MM_CalculateBytesFirstRecordOffset(struct MM_DATA_BASE_XP *bd_xp)
424 : {
425 191 : if (bd_xp)
426 191 : return (32 + 32 * bd_xp->nFields + 1 +
427 191 : MM_CalculateBytesExtendedFieldNames(bd_xp));
428 0 : return 0;
429 : }
430 :
431 191 : static void MM_CheckDBFHeader(struct MM_DATA_BASE_XP *bd_xp)
432 : {
433 : struct MM_FIELD *camp;
434 : MM_EXT_DBF_N_FIELDS i;
435 191 : MM_BOOLEAN cal_DBF_estesa = FALSE;
436 :
437 191 : bd_xp->BytesPerRecord = 1;
438 1417 : for (i = 0, camp = bd_xp->pField; i < bd_xp->nFields; i++, camp++)
439 : {
440 1226 : camp->AccumulatedBytes = bd_xp->BytesPerRecord;
441 1226 : bd_xp->BytesPerRecord += camp->BytesPerField;
442 1226 : if (camp->DesiredWidth == 0)
443 1226 : camp->DesiredWidth = camp->OriginalDesiredWidth =
444 1226 : MM_GetDefaultDesiredDBFFieldWidth(camp); //camp->BytesPerField;
445 1226 : if (camp->FieldType == 'C' &&
446 192 : camp->BytesPerField > MM_MAX_AMPLADA_CAMP_C_DBF_CLASSICA)
447 0 : cal_DBF_estesa = TRUE;
448 1226 : if (MM_VALID_EXTENDED_DBF_NAME ==
449 1226 : MM_ISExtendedNameBD_XP(camp->FieldName))
450 91 : cal_DBF_estesa = TRUE;
451 : }
452 :
453 191 : bd_xp->FirstRecordOffset = MM_CalculateBytesFirstRecordOffset(bd_xp);
454 :
455 191 : if (cal_DBF_estesa || bd_xp->nFields > MM_MAX_N_CAMPS_DBF_CLASSICA ||
456 167 : bd_xp->nRecords > UINT32_MAX)
457 24 : bd_xp->dbf_version = (MM_BYTE)MM_MARCA_VERSIO_1_DBF_ESTESA;
458 : else
459 167 : bd_xp->dbf_version = MM_MARCA_DBASE4;
460 191 : }
461 :
462 : static void
463 2105 : MM_InitializeOffsetExtendedFieldNameFields(struct MM_DATA_BASE_XP *bd_xp,
464 : MM_EXT_DBF_N_FIELDS i_camp)
465 : {
466 2105 : memset((char *)(&bd_xp->pField[i_camp].reserved_2) +
467 : MM_OFFSET_RESERVAT2_OFFSET_NOM_ESTES,
468 : 0, 4);
469 2105 : }
470 :
471 : static void
472 2105 : MM_InitializeBytesExtendedFieldNameFields(struct MM_DATA_BASE_XP *bd_xp,
473 : MM_EXT_DBF_N_FIELDS i_camp)
474 : {
475 2105 : memset((char *)(&bd_xp->pField[i_camp].reserved_2) +
476 : MM_OFFSET_RESERVED2_EXTENDED_NAME_SIZE,
477 : 0, 1);
478 2105 : }
479 :
480 91 : static short int MM_return_common_valid_DBF_field_name_string(char *szChain)
481 : {
482 : char *p;
483 91 : short int error_retornat = 0;
484 :
485 91 : if (!szChain)
486 0 : return 0;
487 : //strupr(szChain);
488 1204 : for (p = szChain; *p; p++)
489 : {
490 1113 : (*p) = (char)toupper((unsigned char)*p);
491 1113 : if ((*p >= 'A' && *p <= 'Z') || (*p >= '0' && *p <= '9') || *p == '_')
492 : ;
493 : else
494 : {
495 7 : *p = '_';
496 7 : error_retornat |= MM_FIELD_NAME_CHARACTER_INVALID;
497 : }
498 : }
499 91 : if (szChain[0] == '_')
500 : {
501 : // To avoid having field names starting by '_' this case is
502 : // substituted by a 0 (not a '\0').
503 0 : szChain[0] = '0';
504 0 : error_retornat |= MM_FIELD_NAME_FIRST_CHARACTER_;
505 : }
506 91 : return error_retornat;
507 : }
508 :
509 91 : static short int MM_ReturnValidClassicDBFFieldName(char *szChain)
510 : {
511 : size_t long_nom_camp;
512 91 : short int error_retornat = 0;
513 :
514 91 : long_nom_camp = strlen(szChain);
515 91 : if ((long_nom_camp < 1) ||
516 : (long_nom_camp >= MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF))
517 : {
518 89 : szChain[MM_MAX_LON_FIELD_NAME_DBF - 1] = '\0';
519 89 : error_retornat |= MM_FIELD_NAME_TOO_LONG;
520 : }
521 91 : error_retornat |= MM_return_common_valid_DBF_field_name_string(szChain);
522 91 : return error_retornat;
523 : }
524 :
525 : static MM_BOOLEAN
526 91 : MM_CheckClassicFieldNameEqual(const struct MM_DATA_BASE_XP *data_base_XP,
527 : const char *classical_name)
528 : {
529 : MM_EXT_DBF_N_FIELDS i;
530 :
531 1300 : for (i = 0; i < data_base_XP->nFields; i++)
532 : {
533 1209 : if ((strcasecmp(data_base_XP->pField[i].ClassicalDBFFieldName,
534 1209 : classical_name)) == 0 ||
535 1209 : (strcasecmp(data_base_XP->pField[i].FieldName, classical_name)) ==
536 : 0)
537 0 : return TRUE;
538 : }
539 91 : return FALSE;
540 : }
541 :
542 0 : static char *MM_GiveNewStringWithCharacterInFront(const char *text,
543 : char character)
544 : {
545 : char *ptr;
546 : size_t i;
547 :
548 0 : if (!text)
549 0 : return nullptr;
550 :
551 0 : i = strlen(text);
552 0 : if ((ptr = calloc_function(i + 2)) == nullptr)
553 0 : return nullptr;
554 :
555 0 : *ptr = character;
556 0 : memcpy(ptr + 1, text, i + 1);
557 0 : return ptr;
558 : }
559 :
560 0 : static char *MM_SetSubIndexFieldNam(const char *nom_camp,
561 : MM_EXT_DBF_N_FIELDS index,
562 : size_t ampladamax)
563 : {
564 : char *NomCamp_SubIndex;
565 : char *_subindex;
566 : char subindex[19 + 1];
567 : size_t sizet_subindex;
568 : size_t sizet_nomcamp;
569 :
570 0 : NomCamp_SubIndex = calloc_function(ampladamax);
571 0 : if (!NomCamp_SubIndex)
572 0 : return nullptr;
573 :
574 0 : CPLStrlcpy(NomCamp_SubIndex, nom_camp, ampladamax);
575 0 : NomCamp_SubIndex[ampladamax - 1] = '\0';
576 :
577 0 : snprintf(subindex, sizeof(subindex), sprintf_UINT64, (GUInt64)index);
578 :
579 0 : _subindex = MM_GiveNewStringWithCharacterInFront(subindex, '_');
580 0 : if (!_subindex)
581 : {
582 0 : free_function(NomCamp_SubIndex);
583 0 : return nullptr;
584 : }
585 :
586 0 : sizet_subindex = strlen(_subindex);
587 0 : sizet_nomcamp = strlen(NomCamp_SubIndex);
588 :
589 0 : if (sizet_nomcamp + sizet_subindex > ampladamax - 1)
590 0 : memcpy(NomCamp_SubIndex + ((ampladamax - 1) - sizet_subindex),
591 : _subindex, strlen(_subindex));
592 : else
593 0 : NomCamp_SubIndex = strcat(NomCamp_SubIndex, _subindex);
594 :
595 0 : free_function(_subindex);
596 :
597 0 : return NomCamp_SubIndex;
598 : }
599 :
600 : MM_FIRST_RECORD_OFFSET_TYPE
601 771 : MM_GiveOffsetExtendedFieldName(const struct MM_FIELD *camp)
602 : {
603 : MM_FIRST_RECORD_OFFSET_TYPE offset_nom_camp;
604 :
605 771 : memcpy(&offset_nom_camp,
606 771 : (char *)(&camp->reserved_2) + MM_OFFSET_RESERVAT2_OFFSET_NOM_ESTES,
607 : 4);
608 771 : return offset_nom_camp;
609 : }
610 :
611 308 : int MM_WriteNRecordsMMBD_XPFile(struct MMAdmDatabase *MMAdmDB)
612 : {
613 308 : if (!MMAdmDB->pMMBDXP || !MMAdmDB->pMMBDXP->pfDataBase)
614 0 : return 0;
615 :
616 : // Updating number of features in features table
617 308 : fseek_function(MMAdmDB->pMMBDXP->pfDataBase, MM_FIRST_OFFSET_to_N_RECORDS,
618 : SEEK_SET);
619 :
620 308 : if (MMAdmDB->pMMBDXP->nRecords > UINT32_MAX)
621 : {
622 0 : MMAdmDB->pMMBDXP->dbf_version = MM_MARCA_VERSIO_1_DBF_ESTESA;
623 : }
624 : else
625 : {
626 308 : MMAdmDB->pMMBDXP->dbf_version = MM_MARCA_DBASE4;
627 : }
628 :
629 : {
630 308 : GUInt32 nRecords32LowBits =
631 308 : (GUInt32)(MMAdmDB->pMMBDXP->nRecords & UINT32_MAX);
632 308 : if (fwrite_function(&nRecords32LowBits, 4, 1,
633 : MMAdmDB->pMMBDXP->pfDataBase) != 1)
634 0 : return 1;
635 : }
636 :
637 308 : fseek_function(MMAdmDB->pMMBDXP->pfDataBase, MM_SECOND_OFFSET_to_N_RECORDS,
638 : SEEK_SET);
639 308 : if (MMAdmDB->pMMBDXP->dbf_version == MM_MARCA_VERSIO_1_DBF_ESTESA)
640 : {
641 : /* from 16 to 19, position MM_SECOND_OFFSET_to_N_RECORDS */
642 0 : GUInt32 nRecords32HighBits =
643 0 : (GUInt32)(MMAdmDB->pMMBDXP->nRecords >> 32);
644 0 : if (fwrite_function(&nRecords32HighBits, 4, 1,
645 : MMAdmDB->pMMBDXP->pfDataBase) != 1)
646 0 : return 1;
647 :
648 : /* from 20 to 27 */
649 0 : if (fwrite_function(&(MMAdmDB->pMMBDXP->dbf_on_a_LAN), 8, 1,
650 : MMAdmDB->pMMBDXP->pfDataBase) != 1)
651 0 : return 1;
652 : }
653 : else
654 : {
655 308 : if (fwrite_function(&(MMAdmDB->pMMBDXP->dbf_on_a_LAN), 12, 1,
656 : MMAdmDB->pMMBDXP->pfDataBase) != 1)
657 0 : return 1;
658 : }
659 :
660 308 : return 0;
661 : }
662 :
663 : static MM_BOOLEAN
664 308 : MM_OpenIfNeededAndUpdateEntireHeader(struct MM_DATA_BASE_XP *data_base_XP)
665 : {
666 : MM_BYTE variable_byte;
667 308 : MM_EXT_DBF_N_FIELDS i, j = 0;
668 308 : char zero[11] = {0};
669 308 : const MM_BYTE byte_zero = 0;
670 308 : char ModeLectura_previ[4] = "";
671 : MM_FIRST_RECORD_OFFSET_TYPE bytes_acumulats;
672 : MM_BYTE name_size;
673 : int estat;
674 : char nom_camp[MM_MAX_LON_FIELD_NAME_DBF];
675 : size_t retorn_fwrite;
676 :
677 308 : if (!data_base_XP)
678 0 : return FALSE;
679 :
680 308 : if (data_base_XP->pfDataBase == nullptr)
681 : {
682 191 : strcpy(ModeLectura_previ, data_base_XP->ReadingMode);
683 191 : strcpy(data_base_XP->ReadingMode, "wb+");
684 :
685 191 : if ((data_base_XP->pfDataBase =
686 191 : fopen_function(data_base_XP->szFileName,
687 : data_base_XP->ReadingMode)) == nullptr)
688 : {
689 0 : return FALSE;
690 : }
691 : }
692 : else
693 : {
694 : // If it's open we just update the header
695 117 : fseek_function(data_base_XP->pfDataBase, 0, SEEK_SET);
696 : }
697 :
698 308 : if ((data_base_XP->nFields) > MM_MAX_N_CAMPS_DBF_CLASSICA)
699 0 : data_base_XP->dbf_version = MM_MARCA_VERSIO_1_DBF_ESTESA;
700 308 : else if ((data_base_XP->nRecords) > UINT32_MAX)
701 0 : data_base_XP->dbf_version = MM_MARCA_VERSIO_1_DBF_ESTESA;
702 : else
703 : {
704 308 : if (data_base_XP->dbf_version == MM_MARCA_VERSIO_1_DBF_ESTESA)
705 24 : data_base_XP->dbf_version = MM_MARCA_DBASE4;
706 2240 : for (i = 0; i < data_base_XP->nFields; i++)
707 : {
708 2022 : if (data_base_XP->pField[i].FieldType == 'C' &&
709 348 : data_base_XP->pField[i].BytesPerField >
710 : MM_MAX_AMPLADA_CAMP_C_DBF_CLASSICA)
711 : {
712 0 : data_base_XP->dbf_version = MM_MARCA_VERSIO_1_DBF_ESTESA;
713 0 : break;
714 : }
715 2022 : if (MM_VALID_EXTENDED_DBF_NAME ==
716 2022 : MM_ISExtendedNameBD_XP(data_base_XP->pField[i].FieldName))
717 : {
718 90 : data_base_XP->dbf_version = MM_MARCA_VERSIO_1_DBF_ESTESA;
719 90 : break;
720 : }
721 : }
722 : }
723 :
724 : // Writing header
725 308 : fseek_function(data_base_XP->pfDataBase, 0, SEEK_SET);
726 :
727 : /* Byte 0 */
728 308 : if (fwrite_function(&(data_base_XP->dbf_version), 1, 1,
729 : data_base_XP->pfDataBase) != 1)
730 : {
731 0 : fclose_function(data_base_XP->pfDataBase);
732 0 : data_base_XP->pfDataBase = nullptr;
733 0 : return FALSE;
734 : }
735 :
736 : /* MM_BYTE from 1 to 3 */
737 308 : variable_byte = (MM_BYTE)(data_base_XP->year - 1900);
738 308 : if (fwrite_function(&variable_byte, 1, 1, data_base_XP->pfDataBase) != 1)
739 : {
740 0 : fclose_function(data_base_XP->pfDataBase);
741 0 : data_base_XP->pfDataBase = nullptr;
742 0 : return FALSE;
743 : }
744 308 : if (fwrite_function(&(data_base_XP->month), 1, 1,
745 : data_base_XP->pfDataBase) != 1)
746 : {
747 0 : fclose_function(data_base_XP->pfDataBase);
748 0 : data_base_XP->pfDataBase = nullptr;
749 0 : return FALSE;
750 : }
751 308 : if (fwrite_function(&(data_base_XP->day), 1, 1, data_base_XP->pfDataBase) !=
752 : 1)
753 : {
754 0 : fclose_function(data_base_XP->pfDataBase);
755 0 : data_base_XP->pfDataBase = nullptr;
756 0 : return FALSE;
757 : }
758 :
759 : /* from 4 a 7, position MM_FIRST_OFFSET_to_N_RECORDS */
760 : {
761 308 : GUInt32 nRecords32LowBits =
762 308 : (GUInt32)(data_base_XP->nRecords & UINT32_MAX);
763 308 : if (fwrite_function(&nRecords32LowBits, 4, 1,
764 : data_base_XP->pfDataBase) != 1)
765 : {
766 0 : fclose_function(data_base_XP->pfDataBase);
767 0 : data_base_XP->pfDataBase = nullptr;
768 0 : return FALSE;
769 : }
770 : }
771 :
772 : /* from 8 a 9, position MM_PRIMER_OFFSET_a_OFFSET_1a_FITXA */
773 308 : if (fwrite_function(&(data_base_XP->FirstRecordOffset), 2, 1,
774 : data_base_XP->pfDataBase) != 1)
775 : {
776 0 : fclose_function(data_base_XP->pfDataBase);
777 0 : data_base_XP->pfDataBase = nullptr;
778 0 : return FALSE;
779 : }
780 : /* from 10 to 11, & from 12 to 13 */
781 308 : if (MM_ES_DBF_ESTESA(data_base_XP->dbf_version))
782 : {
783 90 : if (fwrite_function(&(data_base_XP->BytesPerRecord),
784 : sizeof(MM_ACCUMULATED_BYTES_TYPE_DBF), 1,
785 : data_base_XP->pfDataBase) != 1)
786 : {
787 0 : fclose_function(data_base_XP->pfDataBase);
788 0 : data_base_XP->pfDataBase = nullptr;
789 0 : return FALSE;
790 : }
791 : }
792 : else
793 : {
794 : /* from 10 to 11 */
795 218 : if (fwrite_function(&(data_base_XP->BytesPerRecord), 2, 1,
796 : data_base_XP->pfDataBase) != 1)
797 : {
798 0 : fclose_function(data_base_XP->pfDataBase);
799 0 : data_base_XP->pfDataBase = nullptr;
800 0 : return FALSE;
801 : }
802 : /* from 12 to 13 */
803 218 : if (fwrite_function(&(data_base_XP->reserved_1), 2, 1,
804 : data_base_XP->pfDataBase) != 1)
805 : {
806 0 : fclose_function(data_base_XP->pfDataBase);
807 0 : data_base_XP->pfDataBase = nullptr;
808 0 : return FALSE;
809 : }
810 : }
811 : /* byte 14 */
812 308 : if (fwrite_function(&(data_base_XP->transaction_flag), 1, 1,
813 : data_base_XP->pfDataBase) != 1)
814 : {
815 0 : fclose_function(data_base_XP->pfDataBase);
816 0 : data_base_XP->pfDataBase = nullptr;
817 0 : return FALSE;
818 : }
819 : /* byte 15 */
820 308 : if (fwrite_function(&(data_base_XP->encryption_flag), 1, 1,
821 : data_base_XP->pfDataBase) != 1)
822 : {
823 0 : fclose_function(data_base_XP->pfDataBase);
824 0 : data_base_XP->pfDataBase = nullptr;
825 0 : return FALSE;
826 : }
827 :
828 : /* from 16 to 27 */
829 308 : if (data_base_XP->nRecords > UINT32_MAX)
830 : {
831 : /* from 16 to 19, position MM_SECOND_OFFSET_to_N_RECORDS */
832 0 : GUInt32 nRecords32HighBits = (GUInt32)(data_base_XP->nRecords >> 32);
833 0 : if (fwrite_function(&nRecords32HighBits, 4, 1,
834 : data_base_XP->pfDataBase) != 1)
835 : {
836 0 : fclose_function(data_base_XP->pfDataBase);
837 0 : data_base_XP->pfDataBase = nullptr;
838 0 : return FALSE;
839 : }
840 :
841 : /* from 20 to 27 */
842 0 : if (fwrite_function(&(data_base_XP->dbf_on_a_LAN), 8, 1,
843 : data_base_XP->pfDataBase) != 1)
844 : {
845 0 : fclose_function(data_base_XP->pfDataBase);
846 0 : data_base_XP->pfDataBase = nullptr;
847 0 : return FALSE;
848 : }
849 : }
850 : else
851 : {
852 : /* from 16 to 27 */
853 308 : if (fwrite_function(&(data_base_XP->dbf_on_a_LAN), 12, 1,
854 : data_base_XP->pfDataBase) != 1)
855 : {
856 0 : fclose_function(data_base_XP->pfDataBase);
857 0 : data_base_XP->pfDataBase = nullptr;
858 0 : return FALSE;
859 : }
860 : }
861 : /* byte 28 */
862 308 : if (fwrite_function(&(data_base_XP->MDX_flag), 1, 1,
863 : data_base_XP->pfDataBase) != 1)
864 : {
865 0 : fclose_function(data_base_XP->pfDataBase);
866 0 : data_base_XP->pfDataBase = nullptr;
867 0 : return FALSE;
868 : }
869 :
870 : /* Byte 29 */
871 308 : if (fwrite_function(&(data_base_XP->CharSet), 1, 1,
872 : data_base_XP->pfDataBase) != 1)
873 : {
874 0 : fclose_function(data_base_XP->pfDataBase);
875 0 : data_base_XP->pfDataBase = nullptr;
876 0 : return FALSE;
877 : }
878 :
879 : /* Bytes from 30 to 31, in position MM_SEGON_OFFSET_a_OFFSET_1a_FITXA */
880 308 : if (MM_ES_DBF_ESTESA(data_base_XP->dbf_version))
881 : {
882 90 : if (fwrite_function(((char *)&(data_base_XP->FirstRecordOffset)) + 2, 2,
883 : 1, data_base_XP->pfDataBase) != 1)
884 : {
885 0 : fclose_function(data_base_XP->pfDataBase);
886 0 : data_base_XP->pfDataBase = nullptr;
887 0 : return FALSE;
888 : }
889 : }
890 : else
891 : {
892 218 : if (fwrite_function(&(data_base_XP->reserved_2), 2, 1,
893 : data_base_XP->pfDataBase) != 1)
894 : {
895 0 : fclose_function(data_base_XP->pfDataBase);
896 0 : data_base_XP->pfDataBase = nullptr;
897 0 : return FALSE;
898 : }
899 : }
900 :
901 : /* At 32th byte fields description begins */
902 : /* Every description is 32 bytes long */
903 308 : bytes_acumulats = 32 + 32 * (data_base_XP->nFields) + 1;
904 :
905 2852 : for (i = 0; i < data_base_XP->nFields; i++)
906 : {
907 : /* Bytes from 0 to 10 -> Field name, \0 finished */
908 2544 : estat = MM_ISExtendedNameBD_XP(data_base_XP->pField[i].FieldName);
909 2544 : if (estat == NM_CLASSICAL_DBF_AND_VALID_NAME ||
910 : estat == MM_DBF_NAME_LOWERCASE_AND_VALID)
911 : {
912 2105 : j = (short)strlen(data_base_XP->pField[i].FieldName);
913 :
914 2105 : retorn_fwrite = fwrite_function(&data_base_XP->pField[i].FieldName,
915 : 1, j, data_base_XP->pfDataBase);
916 2105 : if (retorn_fwrite != (size_t)j)
917 : {
918 0 : fclose_function(data_base_XP->pfDataBase);
919 0 : data_base_XP->pfDataBase = nullptr;
920 0 : return FALSE;
921 : }
922 2105 : MM_InitializeOffsetExtendedFieldNameFields(data_base_XP, i);
923 2105 : MM_InitializeBytesExtendedFieldNameFields(data_base_XP, i);
924 : }
925 439 : else if (estat == MM_VALID_EXTENDED_DBF_NAME)
926 : {
927 439 : if (*(data_base_XP->pField[i].ClassicalDBFFieldName) == '\0')
928 : {
929 : char nom_temp[MM_MAX_LON_FIELD_NAME_DBF];
930 :
931 91 : CPLStrlcpy(nom_temp, data_base_XP->pField[i].FieldName,
932 : MM_MAX_LON_FIELD_NAME_DBF);
933 91 : MM_ReturnValidClassicDBFFieldName(nom_temp);
934 91 : nom_temp[MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF - 1] = '\0';
935 91 : if ((MM_CheckClassicFieldNameEqual(data_base_XP, nom_temp)) ==
936 : TRUE)
937 : {
938 : char *c;
939 :
940 0 : c = MM_SetSubIndexFieldNam(
941 : nom_temp, i, MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF);
942 :
943 0 : if (c)
944 : {
945 0 : j = 0;
946 0 : while (MM_CheckClassicFieldNameEqual(data_base_XP, c) ==
947 0 : TRUE &&
948 0 : j < data_base_XP->nFields)
949 : {
950 0 : free_function(c);
951 0 : c = MM_SetSubIndexFieldNam(
952 : nom_temp, ++j,
953 : MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF);
954 : }
955 0 : if (c)
956 : {
957 0 : CPLStrlcpy(
958 0 : data_base_XP->pField[i].ClassicalDBFFieldName,
959 : c,
960 : sizeof(data_base_XP->pField[i]
961 : .ClassicalDBFFieldName));
962 0 : free_function(c);
963 : }
964 : }
965 : }
966 : else
967 91 : CPLStrlcpy(
968 91 : data_base_XP->pField[i].ClassicalDBFFieldName, nom_temp,
969 : sizeof(data_base_XP->pField[i].ClassicalDBFFieldName));
970 : }
971 :
972 : // This is a 11-byte fixed size field consisting of the filename
973 : // and it's been padding calculated some next lines.
974 439 : j = (short)strlen(data_base_XP->pField[i].ClassicalDBFFieldName);
975 :
976 : retorn_fwrite =
977 439 : fwrite_function(&data_base_XP->pField[i].ClassicalDBFFieldName,
978 : 1, j, data_base_XP->pfDataBase);
979 439 : if (retorn_fwrite != (size_t)j)
980 : {
981 0 : fclose_function(data_base_XP->pfDataBase);
982 0 : data_base_XP->pfDataBase = nullptr;
983 0 : return FALSE;
984 : }
985 :
986 : name_size =
987 439 : MM_CalculateBytesExtendedFieldName(data_base_XP->pField + i);
988 439 : MM_EscriuOffsetNomEstesBD_XP(data_base_XP, i, bytes_acumulats);
989 439 : bytes_acumulats += name_size;
990 : }
991 : else
992 : {
993 0 : fclose_function(data_base_XP->pfDataBase);
994 0 : data_base_XP->pfDataBase = nullptr;
995 0 : return FALSE;
996 : }
997 :
998 2544 : if (fwrite_function(zero, 1, 11 - j, data_base_XP->pfDataBase) !=
999 2544 : 11 - (size_t)j)
1000 : {
1001 0 : fclose_function(data_base_XP->pfDataBase);
1002 0 : data_base_XP->pfDataBase = nullptr;
1003 0 : return FALSE;
1004 : }
1005 : /* Byte 11, Field type */
1006 2544 : if (fwrite_function(&data_base_XP->pField[i].FieldType, 1, 1,
1007 : data_base_XP->pfDataBase) != 1)
1008 : {
1009 0 : fclose_function(data_base_XP->pfDataBase);
1010 0 : data_base_XP->pfDataBase = nullptr;
1011 0 : return FALSE;
1012 : }
1013 : /* Bytes 12 to 15 --> Reserved */
1014 2544 : if (fwrite_function(&data_base_XP->pField[i].reserved_1, 4, 1,
1015 : data_base_XP->pfDataBase) != 1)
1016 : {
1017 0 : fclose_function(data_base_XP->pfDataBase);
1018 0 : data_base_XP->pfDataBase = nullptr;
1019 0 : return FALSE;
1020 : }
1021 : /* Byte 16, or OFFSET_BYTESxCAMP_CAMP_CLASSIC --> BytesPerField */
1022 2544 : if (MM_ES_DBF_ESTESA(data_base_XP->dbf_version) &&
1023 1192 : data_base_XP->pField[i].FieldType == 'C')
1024 : {
1025 201 : if (fwrite_function((void *)&byte_zero, 1, 1,
1026 : data_base_XP->pfDataBase) != 1)
1027 : {
1028 0 : fclose_function(data_base_XP->pfDataBase);
1029 0 : data_base_XP->pfDataBase = nullptr;
1030 0 : return FALSE;
1031 : }
1032 : }
1033 : else
1034 : {
1035 2343 : if (fwrite_function(&data_base_XP->pField[i].BytesPerField, 1, 1,
1036 : data_base_XP->pfDataBase) != 1)
1037 : {
1038 0 : fclose_function(data_base_XP->pfDataBase);
1039 0 : data_base_XP->pfDataBase = nullptr;
1040 0 : return FALSE;
1041 : }
1042 : }
1043 : /* 17th byte 17 --> In fields of type 'N' and 'F' indicates decimal places.*/
1044 2544 : if (data_base_XP->pField[i].FieldType == 'N' ||
1045 716 : data_base_XP->pField[i].FieldType == 'F')
1046 : {
1047 1828 : if (fwrite_function(&data_base_XP->pField[i].DecimalsIfFloat, 1, 1,
1048 : data_base_XP->pfDataBase) != 1)
1049 : {
1050 0 : fclose_function(data_base_XP->pfDataBase);
1051 0 : data_base_XP->pfDataBase = nullptr;
1052 0 : return FALSE;
1053 : }
1054 : }
1055 : else
1056 : {
1057 716 : if (fwrite_function(zero, 1, 1, data_base_XP->pfDataBase) != 1)
1058 : {
1059 0 : fclose_function(data_base_XP->pfDataBase);
1060 0 : data_base_XP->pfDataBase = nullptr;
1061 0 : return FALSE;
1062 : }
1063 : }
1064 2544 : if (MM_ES_DBF_ESTESA(data_base_XP->dbf_version) &&
1065 1192 : data_base_XP->pField[i].FieldType == 'C')
1066 : {
1067 : /* Bytes from 18 to 20 --> Reserved */
1068 201 : if (fwrite_function(&data_base_XP->pField[i].reserved_2,
1069 : 20 - 18 + 1, 1, data_base_XP->pfDataBase) != 1)
1070 : {
1071 0 : fclose_function(data_base_XP->pfDataBase);
1072 0 : data_base_XP->pfDataBase = nullptr;
1073 0 : return FALSE;
1074 : }
1075 : /* Bytes from 21 to 24 --> OFFSET_BYTESxCAMP_CAMP_ESPECIAL, special fields, like C
1076 : in extended DBF */
1077 201 : if (fwrite_function(&data_base_XP->pField[i].BytesPerField,
1078 : sizeof(MM_BYTES_PER_FIELD_TYPE_DBF), 1,
1079 : data_base_XP->pfDataBase) != 1)
1080 : {
1081 0 : fclose_function(data_base_XP->pfDataBase);
1082 0 : data_base_XP->pfDataBase = nullptr;
1083 0 : return FALSE;
1084 : }
1085 :
1086 : /* Bytes from 25 to 30 --> Reserved */
1087 201 : if (fwrite_function(&data_base_XP->pField[i].reserved_2[25 - 18],
1088 : 30 - 25 + 1, 1, data_base_XP->pfDataBase) != 1)
1089 : {
1090 0 : fclose_function(data_base_XP->pfDataBase);
1091 0 : data_base_XP->pfDataBase = nullptr;
1092 0 : return FALSE;
1093 : }
1094 : }
1095 : else
1096 : {
1097 : /* Bytes de 21 a 24 --> OFFSET_BYTESxCAMP_CAMP_ESPECIAL, special fields, like C */
1098 2343 : memset(data_base_XP->pField[i].reserved_2 +
1099 : MM_OFFSET_RESERVAT2_BYTESxCAMP_CAMP_ESPECIAL,
1100 : '\0', 4);
1101 : /* Bytes from 18 to 30 --> Reserved */
1102 2343 : if (fwrite_function(&data_base_XP->pField[i].reserved_2, 13, 1,
1103 : data_base_XP->pfDataBase) != 1)
1104 : {
1105 0 : fclose_function(data_base_XP->pfDataBase);
1106 0 : data_base_XP->pfDataBase = nullptr;
1107 0 : return FALSE;
1108 : }
1109 : }
1110 : /* Byte 31 --> MDX flag. */
1111 2544 : if (fwrite_function(&data_base_XP->pField[i].MDX_field_flag, 1, 1,
1112 : data_base_XP->pfDataBase) != 1)
1113 : {
1114 0 : fclose_function(data_base_XP->pfDataBase);
1115 0 : data_base_XP->pfDataBase = nullptr;
1116 0 : return FALSE;
1117 : }
1118 : }
1119 :
1120 308 : variable_byte = 13;
1121 308 : if (fwrite_function(&variable_byte, 1, 1, data_base_XP->pfDataBase) != 1)
1122 : {
1123 0 : fclose_function(data_base_XP->pfDataBase);
1124 0 : data_base_XP->pfDataBase = nullptr;
1125 0 : return FALSE;
1126 : }
1127 :
1128 308 : if (data_base_XP->FirstRecordOffset != bytes_acumulats)
1129 : {
1130 0 : fclose_function(data_base_XP->pfDataBase);
1131 0 : data_base_XP->pfDataBase = nullptr;
1132 0 : return FALSE;
1133 : }
1134 :
1135 : // Extended fields
1136 2852 : for (i = 0; i < data_base_XP->nFields; i++)
1137 : {
1138 2544 : if (MM_VALID_EXTENDED_DBF_NAME ==
1139 2544 : MM_ISExtendedNameBD_XP(data_base_XP->pField[i].FieldName))
1140 : {
1141 439 : bytes_acumulats =
1142 439 : MM_GiveOffsetExtendedFieldName(data_base_XP->pField + i);
1143 439 : name_size = MM_DonaBytesNomEstesCamp(data_base_XP->pField + i);
1144 :
1145 439 : fseek_function(data_base_XP->pfDataBase, bytes_acumulats, SEEK_SET);
1146 :
1147 439 : strcpy(nom_camp, data_base_XP->pField[i].FieldName);
1148 : //CanviaJocCaracPerEscriureDBF(nom_camp, JocCaracDBFaMM(data_base_XP->CharSet, ParMM.JocCaracDBFPerDefecte));
1149 :
1150 439 : retorn_fwrite = fwrite_function(nom_camp, 1, name_size,
1151 : data_base_XP->pfDataBase);
1152 :
1153 439 : if (retorn_fwrite != (size_t)name_size)
1154 : {
1155 0 : fclose_function(data_base_XP->pfDataBase);
1156 0 : data_base_XP->pfDataBase = nullptr;
1157 0 : return FALSE;
1158 : }
1159 : }
1160 : }
1161 :
1162 308 : return TRUE;
1163 : } /* End of MM_OpenIfNeededAndUpdateEntireHeader() */
1164 :
1165 191 : MM_BOOLEAN MM_CreateAndOpenDBFFile(struct MM_DATA_BASE_XP *bd_xp,
1166 : const char *NomFitxer)
1167 : {
1168 : time_t currentTime;
1169 :
1170 191 : if (!NomFitxer || MMIsEmptyString(NomFitxer) || !bd_xp)
1171 0 : return FALSE;
1172 :
1173 191 : MM_CheckDBFHeader(bd_xp);
1174 :
1175 : // Setting the current date
1176 191 : currentTime = time(nullptr);
1177 : #ifdef GDAL_COMPILATION
1178 : {
1179 : struct tm ltime;
1180 191 : VSILocalTime(¤tTime, <ime);
1181 :
1182 191 : bd_xp->year = (short int)(ltime.tm_year + 1900);
1183 191 : bd_xp->month = (MM_BYTE)(ltime.tm_mon + 1);
1184 191 : bd_xp->day = (MM_BYTE)ltime.tm_mday;
1185 : }
1186 : #else
1187 : {
1188 : struct tm *pLocalTime;
1189 : pLocalTime = localtime(¤tTime);
1190 :
1191 : bd_xp->year = pLocalTime->tm_year + 1900;
1192 : bd_xp->month = pLocalTime->tm_mon + 1;
1193 : bd_xp->day = pLocalTime->tm_mday;
1194 : }
1195 : #endif
1196 :
1197 191 : CPLStrlcpy(bd_xp->szFileName, NomFitxer, sizeof(bd_xp->szFileName));
1198 191 : return MM_OpenIfNeededAndUpdateEntireHeader(bd_xp);
1199 : }
1200 :
1201 307 : void MM_ReleaseMainFields(struct MM_DATA_BASE_XP *data_base_XP)
1202 : {
1203 : MM_EXT_DBF_N_FIELDS i;
1204 : size_t j;
1205 : char **szChain;
1206 :
1207 307 : if (data_base_XP->pField)
1208 : {
1209 2613 : for (i = 0; i < data_base_XP->nFields; i++)
1210 : {
1211 11535 : for (j = 0; j < MM_NUM_IDIOMES_MD_MULTIDIOMA; j++)
1212 : {
1213 9228 : szChain = data_base_XP->pField[i].Separator;
1214 9228 : if (szChain[j])
1215 : {
1216 0 : free_function(szChain[j]);
1217 0 : szChain[j] = nullptr;
1218 : }
1219 : }
1220 : }
1221 306 : free_function(data_base_XP->pField);
1222 306 : data_base_XP->pField = nullptr;
1223 306 : data_base_XP->nFields = 0;
1224 : }
1225 307 : return;
1226 : }
1227 :
1228 : // READING THE HEADER OF AN EXTENDED DBF
1229 : // Free with MM_ReleaseDBFHeader()
1230 116 : int MM_ReadExtendedDBFHeaderFromFile(const char *szFileName,
1231 : struct MM_DATA_BASE_XP *pMMBDXP,
1232 : const char *pszRelFile)
1233 : {
1234 : MM_BYTE variable_byte;
1235 : FILE_TYPE *pf;
1236 : unsigned short int two_bytes;
1237 : MM_EXT_DBF_N_FIELDS nIField;
1238 : uint16_t offset_primera_fitxa;
1239 116 : MM_FIRST_RECORD_OFFSET_TYPE offset_fals = 0;
1240 116 : MM_BOOLEAN incoherent_record_size = FALSE;
1241 : MM_BYTE un_byte;
1242 : MM_BYTES_PER_FIELD_TYPE_DBF bytes_per_camp;
1243 : MM_BYTE tretze_bytes[13];
1244 : MM_FIRST_RECORD_OFFSET_TYPE offset_possible;
1245 116 : MM_BYTE some_problems_when_reading = 0;
1246 116 : MM_FILE_OFFSET offset_reintent = 0; // For retrying
1247 : char cpg_file[MM_CPL_PATH_BUF_SIZE];
1248 : char *pszDesc;
1249 : char section[MM_MAX_LON_FIELD_NAME_DBF + 25]; // TAULA_PRINCIPAL:field_name
1250 : GUInt32 nRecords32LowBits;
1251 : char *pszString;
1252 :
1253 116 : if (!szFileName || !pMMBDXP)
1254 0 : return 1;
1255 :
1256 116 : CPLStrlcpy(pMMBDXP->szFileName, szFileName, sizeof(pMMBDXP->szFileName));
1257 116 : strcpy(pMMBDXP->ReadingMode, "rb");
1258 :
1259 116 : if ((pMMBDXP->pfDataBase = fopen_function(pMMBDXP->szFileName,
1260 : pMMBDXP->ReadingMode)) == nullptr)
1261 1 : return 1;
1262 :
1263 115 : pf = pMMBDXP->pfDataBase;
1264 :
1265 115 : fseek_function(pf, 0, SEEK_SET);
1266 : /* ====== Header reading (32 bytes) =================== */
1267 115 : offset_primera_fitxa = 0;
1268 :
1269 230 : if (1 != fread_function(&(pMMBDXP->dbf_version), 1, 1, pf) ||
1270 230 : 1 != fread_function(&variable_byte, 1, 1, pf) ||
1271 230 : 1 != fread_function(&(pMMBDXP->month), 1, 1, pf) ||
1272 115 : 1 != fread_function(&(pMMBDXP->day), 1, 1, pf))
1273 : {
1274 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1275 0 : return 1;
1276 : }
1277 :
1278 115 : if (1 != fread_function(&nRecords32LowBits, 4, 1, pf))
1279 : {
1280 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1281 0 : return 1;
1282 : }
1283 :
1284 115 : if (1 != fread_function(&offset_primera_fitxa, 2, 1, pf))
1285 : {
1286 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1287 0 : return 1;
1288 : }
1289 :
1290 115 : pMMBDXP->year = (short)(1900 + variable_byte);
1291 115 : reintenta_lectura_per_si_error_CreaCampBD_XP:
1292 :
1293 115 : if (some_problems_when_reading > 0)
1294 : {
1295 0 : if (!MM_ES_DBF_ESTESA(pMMBDXP->dbf_version))
1296 : {
1297 0 : offset_fals =
1298 0 : offset_primera_fitxa & (MM_FIRST_RECORD_OFFSET_TYPE)(~31);
1299 : }
1300 : }
1301 : else
1302 115 : offset_reintent = ftell_function(pf);
1303 :
1304 230 : if (1 != fread_function(&two_bytes, 2, 1, pf) ||
1305 230 : 1 != fread_function(&(pMMBDXP->reserved_1), 2, 1, pf) ||
1306 230 : 1 != fread_function(&(pMMBDXP->transaction_flag), 1, 1, pf) ||
1307 230 : 1 != fread_function(&(pMMBDXP->encryption_flag), 1, 1, pf) ||
1308 115 : 1 != fread_function(&(pMMBDXP->dbf_on_a_LAN), 12, 1, pf))
1309 : {
1310 0 : free_function(pMMBDXP->pField);
1311 0 : pMMBDXP->pField = nullptr;
1312 0 : pMMBDXP->nFields = 0;
1313 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1314 0 : return 1;
1315 : }
1316 :
1317 115 : if (MM_ES_DBF_ESTESA(pMMBDXP->dbf_version))
1318 : {
1319 : GUInt32 nRecords32HighBits;
1320 :
1321 : // Getting 4 bytes of the 8 bytes variable
1322 38 : memcpy(&nRecords32HighBits, &pMMBDXP->dbf_on_a_LAN, 4);
1323 :
1324 : // Getting other 4 bytes of the 8 bytes variable
1325 : // The cast to GUInt64 of the high 32 bits is important to
1326 : // make sure the left bit shift is done correctly
1327 38 : pMMBDXP->nRecords =
1328 38 : ((GUInt64)nRecords32HighBits << 32) | nRecords32LowBits;
1329 : }
1330 : else
1331 77 : pMMBDXP->nRecords = nRecords32LowBits;
1332 :
1333 230 : if (1 != fread_function(&(pMMBDXP->MDX_flag), 1, 1, pf) ||
1334 230 : 1 != fread_function(&(pMMBDXP->CharSet), 1, 1, pf) ||
1335 115 : 1 != fread_function(&(pMMBDXP->reserved_2), 2, 1, pf))
1336 : {
1337 0 : free_function(pMMBDXP->pField);
1338 0 : pMMBDXP->pField = nullptr;
1339 0 : pMMBDXP->nFields = 0;
1340 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1341 0 : return 1;
1342 : }
1343 :
1344 : // Checking for a cpg file
1345 115 : if (pMMBDXP->CharSet == 0)
1346 : {
1347 : FILE_TYPE *f_cpg;
1348 : char charset_cpg[11];
1349 :
1350 3 : strcpy(cpg_file, pMMBDXP->szFileName);
1351 3 : CPLStrlcpy(cpg_file, reset_extension(cpg_file, "cpg"),
1352 : sizeof(cpg_file));
1353 3 : f_cpg = fopen_function(cpg_file, "r");
1354 3 : if (f_cpg)
1355 : {
1356 : char *p;
1357 : size_t read_bytes;
1358 0 : fseek_function(f_cpg, 0L, SEEK_SET);
1359 0 : if (11 > (read_bytes = fread_function(charset_cpg, 1, 10, f_cpg)))
1360 : {
1361 0 : charset_cpg[read_bytes] = '\0';
1362 0 : p = MM_stristr(charset_cpg, "UTF-8");
1363 0 : if (p)
1364 0 : pMMBDXP->CharSet = MM_JOC_CARAC_UTF8_DBF;
1365 0 : p = MM_stristr(charset_cpg, "UTF8");
1366 0 : if (p)
1367 0 : pMMBDXP->CharSet = MM_JOC_CARAC_UTF8_DBF;
1368 0 : p = MM_stristr(charset_cpg, "ISO-8859-1");
1369 0 : if (p)
1370 0 : pMMBDXP->CharSet = MM_JOC_CARAC_ANSI_DBASE;
1371 : }
1372 0 : fclose_function(f_cpg);
1373 : }
1374 : }
1375 115 : if (MM_ES_DBF_ESTESA(pMMBDXP->dbf_version))
1376 : {
1377 : unsigned short FirstRecordOffsetLow16Bits;
1378 : unsigned short FirstRecordOffsetHigh16Bits;
1379 : GUInt32 nTmp;
1380 :
1381 38 : memcpy(&FirstRecordOffsetLow16Bits, &offset_primera_fitxa, 2);
1382 38 : memcpy(&FirstRecordOffsetHigh16Bits, &pMMBDXP->reserved_2, 2);
1383 :
1384 38 : nTmp = ((GUInt32)FirstRecordOffsetHigh16Bits << 16) |
1385 : FirstRecordOffsetLow16Bits;
1386 38 : if (nTmp > INT32_MAX)
1387 : {
1388 0 : free_function(pMMBDXP->pField);
1389 0 : pMMBDXP->pField = nullptr;
1390 0 : pMMBDXP->nFields = 0;
1391 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1392 0 : return 1;
1393 : }
1394 38 : pMMBDXP->FirstRecordOffset = (MM_FIRST_RECORD_OFFSET_TYPE)nTmp;
1395 :
1396 38 : if (some_problems_when_reading > 0)
1397 0 : offset_fals = pMMBDXP->FirstRecordOffset;
1398 :
1399 38 : memcpy(&FirstRecordOffsetLow16Bits, &two_bytes, 2);
1400 38 : memcpy(&FirstRecordOffsetHigh16Bits, &pMMBDXP->reserved_1, 2);
1401 :
1402 38 : pMMBDXP->BytesPerRecord = ((GUInt32)FirstRecordOffsetHigh16Bits << 16) |
1403 : FirstRecordOffsetLow16Bits;
1404 : }
1405 : else
1406 : {
1407 77 : pMMBDXP->FirstRecordOffset = offset_primera_fitxa;
1408 77 : pMMBDXP->BytesPerRecord = two_bytes;
1409 : }
1410 :
1411 : /* ====== Record structure ========================= */
1412 :
1413 115 : if (some_problems_when_reading > 0)
1414 : {
1415 0 : if (offset_fals < 1 + 32)
1416 0 : pMMBDXP->nFields = 0;
1417 : else
1418 0 : pMMBDXP->nFields =
1419 0 : (MM_EXT_DBF_N_FIELDS)(((offset_fals - 1) - 32) / 32);
1420 : }
1421 : else
1422 : {
1423 : // There's a chance that bytes_acumulats could overflow if it's GUInt32.
1424 : // For that reason it's better to promote to GUInt64.
1425 115 : GUInt64 bytes_acumulats = 1;
1426 :
1427 115 : pMMBDXP->nFields = 0;
1428 :
1429 115 : fseek_function(pf, 0, SEEK_END);
1430 115 : if (32 - 1 < ftell_function(pf))
1431 : {
1432 115 : fseek_function(pf, 32, SEEK_SET);
1433 : do
1434 : {
1435 1081 : bytes_per_camp = 0;
1436 1081 : fseek_function(
1437 : pf,
1438 : 32 + (MM_FILE_OFFSET)pMMBDXP->nFields * 32 +
1439 : (MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF + 1 + 4),
1440 : SEEK_SET);
1441 2162 : if (1 != fread_function(&bytes_per_camp, 1, 1, pf) ||
1442 2162 : 1 != fread_function(&un_byte, 1, 1, pf) ||
1443 1081 : 1 != fread_function(&tretze_bytes,
1444 : 3 + sizeof(bytes_per_camp), 1, pf))
1445 : {
1446 0 : free_function(pMMBDXP->pField);
1447 0 : pMMBDXP->pField = nullptr;
1448 0 : pMMBDXP->nFields = 0;
1449 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1450 0 : return 1;
1451 : }
1452 1081 : if (bytes_per_camp == 0)
1453 79 : memcpy(&bytes_per_camp, (char *)(&tretze_bytes) + 3,
1454 : sizeof(bytes_per_camp));
1455 :
1456 1081 : bytes_acumulats += bytes_per_camp;
1457 1081 : pMMBDXP->nFields++;
1458 1081 : } while (bytes_acumulats < pMMBDXP->BytesPerRecord);
1459 : }
1460 : }
1461 :
1462 115 : if (pMMBDXP->nFields != 0)
1463 : {
1464 115 : free_function(pMMBDXP->pField);
1465 115 : pMMBDXP->pField = MM_CreateAllFields(pMMBDXP->nFields);
1466 115 : if (!pMMBDXP->pField)
1467 : {
1468 0 : pMMBDXP->nFields = 0;
1469 0 : fclose_and_nullify(&pMMBDXP->pfDataBase);
1470 0 : return 1;
1471 : }
1472 : }
1473 : else
1474 : {
1475 0 : free_function(pMMBDXP->pField);
1476 0 : pMMBDXP->pField = nullptr;
1477 : }
1478 :
1479 115 : fseek_function(pf, 32, SEEK_SET);
1480 1196 : for (nIField = 0; nIField < pMMBDXP->nFields; nIField++)
1481 : {
1482 1081 : if (1 != fread_function(pMMBDXP->pField[nIField].FieldName,
1483 1081 : MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF, 1, pf) ||
1484 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].FieldType), 1, 1,
1485 1081 : pf) ||
1486 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].reserved_1), 4, 1,
1487 1081 : pf) ||
1488 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].BytesPerField), 1, 1,
1489 1081 : pf) ||
1490 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].DecimalsIfFloat), 1,
1491 1081 : 1, pf) ||
1492 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].reserved_2), 13, 1,
1493 1081 : pf) ||
1494 1081 : 1 != fread_function(&(pMMBDXP->pField[nIField].MDX_field_flag), 1,
1495 : 1, pf))
1496 : {
1497 0 : free_function(pMMBDXP->pField);
1498 0 : pMMBDXP->pField = nullptr;
1499 0 : pMMBDXP->nFields = 0;
1500 0 : fclose_function(pf);
1501 0 : pMMBDXP->pfDataBase = nullptr;
1502 0 : return 1;
1503 : }
1504 :
1505 1081 : if (pMMBDXP->pField[nIField].FieldType == 'F')
1506 0 : pMMBDXP->pField[nIField].FieldType = 'N';
1507 :
1508 1081 : pMMBDXP->pField[nIField]
1509 1081 : .FieldName[MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF - 1] = '\0';
1510 1081 : if (EQUAL(pMMBDXP->pField[nIField].FieldName,
1511 : szMMNomCampIdGraficDefecte))
1512 115 : pMMBDXP->IdGraficField = nIField;
1513 :
1514 : // Limit BytesPerField to avoid later integer overflows
1515 : // We could potentially limit further...
1516 1081 : if (pMMBDXP->pField[nIField].BytesPerField > (uint32_t)(INT32_MAX - 1))
1517 : {
1518 0 : free_function(pMMBDXP->pField);
1519 0 : pMMBDXP->pField = nullptr;
1520 0 : pMMBDXP->nFields = 0;
1521 0 : fclose_function(pf);
1522 0 : pMMBDXP->pfDataBase = nullptr;
1523 0 : return 1;
1524 : }
1525 :
1526 1081 : if (pMMBDXP->pField[nIField].BytesPerField == 0)
1527 : {
1528 79 : if (!MM_ES_DBF_ESTESA(pMMBDXP->dbf_version))
1529 : {
1530 0 : free_function(pMMBDXP->pField);
1531 0 : pMMBDXP->pField = nullptr;
1532 0 : pMMBDXP->nFields = 0;
1533 0 : fclose_function(pf);
1534 0 : pMMBDXP->pfDataBase = nullptr;
1535 0 : return 1;
1536 : }
1537 79 : if (pMMBDXP->pField[nIField].FieldType != 'C')
1538 : {
1539 0 : free_function(pMMBDXP->pField);
1540 0 : pMMBDXP->pField = nullptr;
1541 0 : pMMBDXP->nFields = 0;
1542 0 : fclose_function(pf);
1543 0 : pMMBDXP->pfDataBase = nullptr;
1544 0 : return 1;
1545 : }
1546 :
1547 79 : memcpy(&pMMBDXP->pField[nIField].BytesPerField,
1548 79 : (char *)(&pMMBDXP->pField[nIField].reserved_2) + 3,
1549 : sizeof(MM_BYTES_PER_FIELD_TYPE_DBF));
1550 : }
1551 :
1552 1081 : if (nIField)
1553 : {
1554 : // To avoid overflow
1555 966 : if (pMMBDXP->pField[nIField - 1].AccumulatedBytes >
1556 966 : UINT32_MAX - pMMBDXP->pField[nIField - 1].BytesPerField)
1557 : {
1558 0 : free_function(pMMBDXP->pField);
1559 0 : pMMBDXP->pField = nullptr;
1560 0 : pMMBDXP->nFields = 0;
1561 0 : fclose_function(pf);
1562 0 : pMMBDXP->pfDataBase = nullptr;
1563 0 : return 1;
1564 : }
1565 :
1566 966 : pMMBDXP->pField[nIField].AccumulatedBytes =
1567 966 : (pMMBDXP->pField[nIField - 1].AccumulatedBytes +
1568 966 : pMMBDXP->pField[nIField - 1].BytesPerField);
1569 : }
1570 : else
1571 : {
1572 115 : pMMBDXP->pField[nIField].AccumulatedBytes = 1;
1573 : }
1574 :
1575 1081 : if (pszRelFile)
1576 : {
1577 : // Usually, in multilingual MiraMon metadata files, the main
1578 : // language is the default one and has no "_cat", "_spa", or
1579 : // "_eng" suffix after the keyword. So, to retrieve all
1580 : // languages in a multilingual file, first, we'll identify
1581 : // the one with no suffix "_cat", "_spa", or "_eng", and then the
1582 : // others. If one of them lacks a value, it gets the default value.
1583 1081 : snprintf(section, sizeof(section), "TAULA_PRINCIPAL:%s",
1584 1081 : pMMBDXP->pField[nIField].FieldName);
1585 :
1586 : // MM_DEF_LANGUAGE
1587 1081 : pszDesc = MMReturnValueFromSectionINIFile(pszRelFile, section,
1588 : "descriptor");
1589 1081 : if (pszDesc)
1590 : {
1591 602 : CPLStrlcpy(
1592 602 : pMMBDXP->pField[nIField].FieldDescription[MM_DEF_LANGUAGE],
1593 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1594 :
1595 602 : free_function(pszDesc);
1596 : }
1597 : else
1598 479 : *pMMBDXP->pField[nIField].FieldDescription[MM_DEF_LANGUAGE] =
1599 : '\0';
1600 :
1601 : // MM_ENG_LANGUAGE
1602 1081 : pszDesc = MMReturnValueFromSectionINIFile(pszRelFile, section,
1603 : "descriptor_eng");
1604 1081 : if (pszDesc)
1605 : {
1606 70 : CPLStrlcpy(
1607 70 : pMMBDXP->pField[nIField].FieldDescription[MM_ENG_LANGUAGE],
1608 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1609 :
1610 70 : if (*pMMBDXP->pField[nIField]
1611 : .FieldDescription[MM_DEF_LANGUAGE] == '\0')
1612 : {
1613 0 : CPLStrlcpy(pMMBDXP->pField[nIField]
1614 0 : .FieldDescription[MM_DEF_LANGUAGE],
1615 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1616 : }
1617 70 : free_function(pszDesc);
1618 : }
1619 : else
1620 : {
1621 : // If there is no value descriptor_eng it's because it's the
1622 : // default one. So, it's taken from there.
1623 1011 : CPLStrlcpy(
1624 1011 : pMMBDXP->pField[nIField].FieldDescription[MM_ENG_LANGUAGE],
1625 1011 : pMMBDXP->pField[nIField].FieldDescription[MM_DEF_LANGUAGE],
1626 : MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1627 : }
1628 :
1629 : // MM_CAT_LANGUAGE
1630 1081 : pszDesc = MMReturnValueFromSectionINIFile(pszRelFile, section,
1631 : "descriptor_cat");
1632 1081 : if (pszDesc)
1633 : {
1634 0 : CPLStrlcpy(
1635 0 : pMMBDXP->pField[nIField].FieldDescription[MM_CAT_LANGUAGE],
1636 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1637 :
1638 0 : if (*pMMBDXP->pField[nIField]
1639 : .FieldDescription[MM_DEF_LANGUAGE] == '\0')
1640 : {
1641 0 : CPLStrlcpy(pMMBDXP->pField[nIField]
1642 0 : .FieldDescription[MM_DEF_LANGUAGE],
1643 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1644 : }
1645 :
1646 0 : free_function(pszDesc);
1647 : }
1648 : else
1649 : {
1650 : // If there is no value descriptor_cat it's because it's the
1651 : // default one. So, it's taken from there.
1652 1081 : CPLStrlcpy(
1653 1081 : pMMBDXP->pField[nIField].FieldDescription[MM_CAT_LANGUAGE],
1654 1081 : pMMBDXP->pField[nIField].FieldDescription[MM_DEF_LANGUAGE],
1655 : MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1656 : }
1657 :
1658 : // MM_SPA_LANGUAGE
1659 1081 : pszDesc = MMReturnValueFromSectionINIFile(pszRelFile, section,
1660 : "descriptor_spa");
1661 1081 : if (pszDesc)
1662 : {
1663 70 : CPLStrlcpy(
1664 70 : pMMBDXP->pField[nIField].FieldDescription[MM_SPA_LANGUAGE],
1665 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1666 :
1667 70 : if (*pMMBDXP->pField[nIField]
1668 : .FieldDescription[MM_DEF_LANGUAGE] == '\0')
1669 : {
1670 0 : CPLStrlcpy(pMMBDXP->pField[nIField]
1671 0 : .FieldDescription[MM_DEF_LANGUAGE],
1672 : pszDesc, MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1673 : }
1674 :
1675 70 : free_function(pszDesc);
1676 : }
1677 : else
1678 : {
1679 : // If there is no value descriptor_spa it's because it's the
1680 : // default one. So, it's taken from there.
1681 1011 : CPLStrlcpy(
1682 1011 : pMMBDXP->pField[nIField].FieldDescription[MM_SPA_LANGUAGE],
1683 1011 : pMMBDXP->pField[nIField].FieldDescription[MM_DEF_LANGUAGE],
1684 : MM_MAX_LON_DESCRIPCIO_CAMP_DBF);
1685 : }
1686 : }
1687 : }
1688 :
1689 115 : if (!pMMBDXP->nFields)
1690 : {
1691 0 : if (pMMBDXP->BytesPerRecord)
1692 0 : incoherent_record_size = TRUE;
1693 : }
1694 : else
1695 : {
1696 : // To avoid overflow
1697 115 : if (pMMBDXP->pField[pMMBDXP->nFields - 1].AccumulatedBytes >
1698 115 : UINT32_MAX - pMMBDXP->pField[pMMBDXP->nFields - 1].BytesPerField)
1699 : {
1700 0 : free_function(pMMBDXP->pField);
1701 0 : pMMBDXP->pField = nullptr;
1702 0 : pMMBDXP->nFields = 0;
1703 0 : fclose_function(pf);
1704 0 : pMMBDXP->pfDataBase = nullptr;
1705 0 : return 1;
1706 : }
1707 115 : if (pMMBDXP->pField[pMMBDXP->nFields - 1].BytesPerField +
1708 115 : pMMBDXP->pField[pMMBDXP->nFields - 1].AccumulatedBytes >
1709 115 : pMMBDXP->BytesPerRecord)
1710 0 : incoherent_record_size = TRUE;
1711 : }
1712 115 : if (incoherent_record_size)
1713 : {
1714 0 : if (some_problems_when_reading == 0)
1715 : {
1716 0 : incoherent_record_size = FALSE;
1717 0 : fseek_function(pf, offset_reintent, SEEK_SET);
1718 0 : some_problems_when_reading++;
1719 : /* Reset IdGraficField as it might no longer be valid */
1720 0 : pMMBDXP->IdGraficField = 0;
1721 0 : goto reintenta_lectura_per_si_error_CreaCampBD_XP;
1722 : }
1723 : else
1724 : {
1725 0 : free_function(pMMBDXP->pField);
1726 0 : pMMBDXP->pField = nullptr;
1727 0 : pMMBDXP->nFields = 0;
1728 0 : fclose_function(pf);
1729 0 : pMMBDXP->pfDataBase = nullptr;
1730 0 : return 1;
1731 : }
1732 : }
1733 :
1734 115 : offset_possible = 32 + 32 * (pMMBDXP->nFields) + 1;
1735 :
1736 115 : if (!incoherent_record_size &&
1737 115 : offset_possible != pMMBDXP->FirstRecordOffset)
1738 : { // Extended names
1739 : MM_FIRST_RECORD_OFFSET_TYPE offset_nom_camp;
1740 : int mida_nom;
1741 :
1742 370 : for (nIField = 0; nIField < pMMBDXP->nFields; nIField++)
1743 : {
1744 : offset_nom_camp =
1745 332 : MM_GiveOffsetExtendedFieldName(pMMBDXP->pField + nIField);
1746 332 : mida_nom = MM_DonaBytesNomEstesCamp(pMMBDXP->pField + nIField);
1747 332 : if (mida_nom > 0 && mida_nom < MM_MAX_LON_FIELD_NAME_DBF &&
1748 101 : offset_nom_camp >= offset_possible &&
1749 101 : offset_nom_camp < pMMBDXP->FirstRecordOffset)
1750 : {
1751 101 : CPLStrlcpy(pMMBDXP->pField[nIField].ClassicalDBFFieldName,
1752 101 : pMMBDXP->pField[nIField].FieldName,
1753 : MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF);
1754 101 : fseek_function(pf, offset_nom_camp, SEEK_SET);
1755 101 : if (1 != fread_function(pMMBDXP->pField[nIField].FieldName,
1756 : mida_nom, 1, pf))
1757 : {
1758 0 : free_function(pMMBDXP->pField);
1759 0 : pMMBDXP->pField = nullptr;
1760 0 : pMMBDXP->nFields = 0;
1761 0 : fclose_function(pf);
1762 0 : pMMBDXP->pfDataBase = nullptr;
1763 0 : return 1;
1764 : }
1765 101 : pMMBDXP->pField[nIField].FieldName[mida_nom] = '\0';
1766 :
1767 : // All field names to UTF-8
1768 101 : if (pMMBDXP->CharSet == MM_JOC_CARAC_ANSI_DBASE)
1769 : {
1770 : pszString =
1771 81 : CPLRecode_function(pMMBDXP->pField[nIField].FieldName,
1772 : CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
1773 81 : CPLStrlcpy(pMMBDXP->pField[nIField].FieldName, pszString,
1774 : MM_MAX_LON_FIELD_NAME_DBF);
1775 81 : CPLFree_function(pszString);
1776 : }
1777 20 : else if (pMMBDXP->CharSet == MM_JOC_CARAC_OEM850_DBASE)
1778 : {
1779 15 : MM_oemansi(pMMBDXP->pField[nIField].FieldName);
1780 : pszString =
1781 15 : CPLRecode_function(pMMBDXP->pField[nIField].FieldName,
1782 : CPL_ENC_ISO8859_1, CPL_ENC_UTF8);
1783 15 : CPLStrlcpy(pMMBDXP->pField[nIField].FieldName, pszString,
1784 : MM_MAX_LON_FIELD_NAME_DBF - 1);
1785 15 : CPLFree_function(pszString);
1786 : }
1787 : }
1788 : }
1789 : }
1790 :
1791 115 : pMMBDXP->IdEntityField = MM_MAX_EXT_DBF_N_FIELDS_TYPE;
1792 115 : return 0;
1793 : } // End of MM_ReadExtendedDBFHeaderFromFile()
1794 :
1795 307 : void MM_ReleaseDBFHeader(struct MM_DATA_BASE_XP **data_base_XP)
1796 : {
1797 307 : if (!data_base_XP)
1798 0 : return;
1799 307 : if (!*data_base_XP)
1800 0 : return;
1801 :
1802 307 : MM_ReleaseMainFields(*data_base_XP);
1803 307 : free_function(*data_base_XP);
1804 307 : *data_base_XP = nullptr;
1805 :
1806 307 : return;
1807 : }
1808 :
1809 575 : int MM_ModifyFieldNameAndDescriptorIfPresentBD_XP(
1810 : struct MM_FIELD *camp, struct MM_DATA_BASE_XP *bd_xp,
1811 : MM_BOOLEAN no_modifica_descriptor, size_t mida_nom)
1812 : {
1813 : MM_EXT_DBF_N_FIELDS i_camp;
1814 575 : unsigned n_digits_i = 0, i;
1815 575 : int retorn = 0;
1816 :
1817 575 : if (mida_nom == 0)
1818 575 : mida_nom = MM_MAX_LON_FIELD_NAME_DBF;
1819 :
1820 5744 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1821 : {
1822 5239 : if (bd_xp->pField + i_camp == camp)
1823 505 : continue;
1824 4734 : if (!strcasecmp(bd_xp->pField[i_camp].FieldName, camp->FieldName))
1825 70 : break;
1826 : }
1827 575 : if (i_camp < bd_xp->nFields)
1828 : {
1829 70 : retorn = 1;
1830 70 : if (strlen(camp->FieldName) > mida_nom - 2)
1831 0 : camp->FieldName[mida_nom - 2] = '\0';
1832 70 : strcat(camp->FieldName, "0");
1833 70 : for (i = 2; i < (size_t)10; i++)
1834 : {
1835 70 : snprintf(camp->FieldName + strlen(camp->FieldName) - 1,
1836 70 : sizeof(camp->FieldName) - strlen(camp->FieldName) + 1,
1837 : "%u", i);
1838 965 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1839 : {
1840 895 : if (bd_xp->pField + i_camp == camp)
1841 70 : continue;
1842 825 : if (!strcasecmp(bd_xp->pField[i_camp].FieldName,
1843 825 : camp->FieldName))
1844 0 : break;
1845 : }
1846 70 : if (i_camp == bd_xp->nFields)
1847 : {
1848 70 : n_digits_i = 1;
1849 70 : break;
1850 : }
1851 : }
1852 70 : if (i == 10)
1853 : {
1854 0 : camp->FieldName[strlen(camp->FieldName) - 1] = '\0';
1855 0 : if (strlen(camp->FieldName) > mida_nom - 3)
1856 0 : camp->FieldName[mida_nom - 3] = '\0';
1857 0 : strcat(camp->FieldName, "00");
1858 0 : for (i = 10; i < (size_t)100; i++)
1859 : {
1860 0 : snprintf(camp->FieldName + strlen(camp->FieldName) - 2,
1861 0 : sizeof(camp->FieldName) - strlen(camp->FieldName) + 2,
1862 : "%u", i);
1863 0 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1864 : {
1865 0 : if (bd_xp->pField + i_camp == camp)
1866 0 : continue;
1867 0 : if (!strcasecmp(bd_xp->pField[i_camp].FieldName,
1868 0 : camp->FieldName))
1869 0 : break;
1870 : }
1871 0 : if (i_camp == bd_xp->nFields)
1872 : {
1873 0 : n_digits_i = 2;
1874 0 : break;
1875 : }
1876 : }
1877 0 : if (i == 100)
1878 : {
1879 0 : camp->FieldName[strlen(camp->FieldName) - 2] = '\0';
1880 0 : if (strlen(camp->FieldName) > mida_nom - 4)
1881 0 : camp->FieldName[mida_nom - 4] = '\0';
1882 0 : strcat(camp->FieldName, "000");
1883 0 : for (i = 100; i < (size_t)256 + 2; i++)
1884 : {
1885 0 : snprintf(camp->FieldName + strlen(camp->FieldName) - 3,
1886 0 : sizeof(camp->FieldName) - strlen(camp->FieldName) +
1887 : 3,
1888 : "%u", i);
1889 0 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1890 : {
1891 0 : if (bd_xp->pField + i_camp == camp)
1892 0 : continue;
1893 0 : if (!strcasecmp(bd_xp->pField[i_camp].FieldName,
1894 0 : camp->FieldName))
1895 0 : break;
1896 : }
1897 0 : if (i_camp == bd_xp->nFields)
1898 : {
1899 0 : n_digits_i = 3;
1900 0 : break;
1901 : }
1902 : }
1903 0 : if (i == 256)
1904 0 : return 2;
1905 : }
1906 : }
1907 : }
1908 : else
1909 : {
1910 505 : i = 1;
1911 : }
1912 :
1913 575 : if ((*(camp->FieldDescription[0]) == '\0') || no_modifica_descriptor)
1914 476 : return retorn;
1915 :
1916 1329 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1917 : {
1918 1230 : if (bd_xp->pField + i_camp == camp)
1919 99 : continue;
1920 1131 : if (!strcasecmp(bd_xp->pField[i_camp].FieldDescription[0],
1921 1131 : camp->FieldDescription[0]))
1922 0 : break;
1923 : }
1924 99 : if (i_camp == bd_xp->nFields)
1925 99 : return retorn;
1926 :
1927 0 : if (retorn == 1)
1928 : {
1929 0 : if (strlen(camp->FieldDescription[0]) >
1930 0 : MM_MAX_LON_DESCRIPCIO_CAMP_DBF - 4 - n_digits_i)
1931 0 : camp->FieldDescription[0][mida_nom - 4 - n_digits_i] = '\0';
1932 :
1933 0 : snprintf(camp->FieldDescription[0] + strlen(camp->FieldDescription[0]),
1934 : sizeof(camp->FieldDescription[0]) -
1935 0 : strlen(camp->FieldDescription[0]),
1936 : " (%u)", i);
1937 0 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1938 : {
1939 0 : if (bd_xp->pField + i_camp == camp)
1940 0 : continue;
1941 0 : if (!strcasecmp(bd_xp->pField[i_camp].FieldDescription[0],
1942 0 : camp->FieldDescription[0]))
1943 0 : break;
1944 : }
1945 0 : if (i_camp == bd_xp->nFields)
1946 0 : return retorn;
1947 : }
1948 :
1949 0 : retorn = 1;
1950 0 : if (strlen(camp->FieldDescription[0]) >
1951 0 : MM_MAX_LON_DESCRIPCIO_CAMP_DBF - 4 - n_digits_i)
1952 0 : camp->FieldDescription[0][mida_nom - 4 - n_digits_i] = '\0';
1953 0 : camp->FieldDescription[0][strlen(camp->FieldDescription[0]) - 4 -
1954 0 : n_digits_i + 1] = '\0';
1955 0 : if (strlen(camp->FieldDescription[0]) > MM_MAX_LON_DESCRIPCIO_CAMP_DBF - 7)
1956 0 : camp->FieldDescription[0][mida_nom - 7] = '\0';
1957 0 : for (i++; i < (size_t)256; i++)
1958 : {
1959 : //if (camp->FieldDescription[0] + strlen(camp->FieldDescription[0]))
1960 0 : snprintf(camp->FieldDescription[0] + strlen(camp->FieldDescription[0]),
1961 : sizeof(camp->FieldDescription[0]) -
1962 0 : strlen(camp->FieldDescription[0]),
1963 : " (%u)", i);
1964 0 : for (i_camp = 0; i_camp < bd_xp->nFields; i_camp++)
1965 : {
1966 0 : if (bd_xp->pField + i_camp == camp)
1967 0 : continue;
1968 0 : if (!strcasecmp(bd_xp->pField[i_camp].FieldName, camp->FieldName))
1969 0 : break;
1970 : }
1971 0 : if (i_camp == bd_xp->nFields)
1972 0 : return retorn;
1973 : }
1974 0 : return 2;
1975 : } // End of MM_ModifyFieldNameAndDescriptorIfPresentBD_XP()
1976 :
1977 575 : static int MM_DuplicateMultilingualString(
1978 : char *(szChain_final[MM_NUM_IDIOMES_MD_MULTIDIOMA]),
1979 : const char *const(szChain_inicial[MM_NUM_IDIOMES_MD_MULTIDIOMA]))
1980 : {
1981 : size_t i;
1982 :
1983 2875 : for (i = 0; i < MM_NUM_IDIOMES_MD_MULTIDIOMA; i++)
1984 : {
1985 2300 : if (szChain_inicial[i])
1986 : {
1987 0 : if (nullptr == (szChain_final[i] = strdup(szChain_inicial[i])))
1988 0 : return 1;
1989 : }
1990 : else
1991 2300 : szChain_final[i] = nullptr;
1992 : }
1993 575 : return 0;
1994 : }
1995 :
1996 575 : int MM_DuplicateFieldDBXP(struct MM_FIELD *camp_final,
1997 : const struct MM_FIELD *camp_inicial)
1998 : {
1999 575 : *camp_final = *camp_inicial;
2000 :
2001 575 : if (0 != MM_DuplicateMultilingualString(
2002 575 : camp_final->Separator,
2003 575 : (const char *const(*))camp_inicial->Separator))
2004 0 : return 1;
2005 :
2006 575 : return 0;
2007 : }
2008 :
2009 : // If n_bytes==SIZE_MAX, the parameter is ignored ant, then,
2010 : // it's assumed that szszChain is NUL terminated
2011 2619 : char *MM_oemansi_n(char *szszChain, size_t n_bytes)
2012 : {
2013 : size_t u_i;
2014 : unsigned char *punter_bait;
2015 2619 : unsigned char t_oemansi[128] = {
2016 : 199, 252, 233, 226, 228, 224, 229, 231, 234, 235, 232, 239, 238,
2017 : 236, 196, 197, 201, 230, 198, 244, 246, 242, 251, 249, 255, 214,
2018 : 220, 248, 163, 216, 215, 131, 225, 237, 243, 250, 241, 209, 170,
2019 : 186, 191, 174, 172, 189, 188, 161, 171, 187, 164, 164, 164, 166,
2020 : 166, 193, 194, 192, 169, 166, 166, 164, 164, 162, 165, 164, 164,
2021 : 164, 164, 164, 164, 164, 227, 195, 164, 164, 164, 164, 166, 164,
2022 : 164, 164, 240, 208, 202, 203, 200, 180, 205, 206, 207, 164, 164,
2023 : 164, 164, 166, 204, 164, 211, 223, 212, 210, 245, 213, 181, 254,
2024 : 222, 218, 219, 217, 253, 221, 175, 180, 173, 177, 164, 190, 182,
2025 : 167, 247, 184, 176, 168, 183, 185, 179, 178, 164, 183};
2026 2619 : if (n_bytes == SIZE_MAX)
2027 : {
2028 26979 : for (punter_bait = (unsigned char *)szszChain; *punter_bait;
2029 24504 : punter_bait++)
2030 : {
2031 24504 : if (*punter_bait > 127)
2032 299 : *punter_bait = t_oemansi[*punter_bait - 128];
2033 : }
2034 : }
2035 : else
2036 : {
2037 2004 : for (u_i = 0, punter_bait = (unsigned char *)szszChain; u_i < n_bytes;
2038 1860 : punter_bait++, u_i++)
2039 : {
2040 1860 : if (*punter_bait > 127)
2041 0 : *punter_bait = t_oemansi[*punter_bait - 128];
2042 : }
2043 : }
2044 2619 : return szszChain;
2045 : }
2046 :
2047 : // An implementation of non-sensitive strstr()
2048 1250 : char *MM_stristr(const char *haystack, const char *needle)
2049 : {
2050 1250 : if (!haystack)
2051 0 : return nullptr;
2052 :
2053 1250 : if (!needle)
2054 0 : return nullptr;
2055 :
2056 1250 : if (!*needle)
2057 0 : return (char *)haystack;
2058 :
2059 1250 : char *p1 = (char *)haystack;
2060 27229 : while (*p1 != '\0' && !EQUALN(p1, needle, strlen(needle)))
2061 25979 : p1++;
2062 :
2063 1250 : if (*p1 == '\0')
2064 494 : return nullptr;
2065 :
2066 756 : return p1;
2067 : }
2068 :
2069 2475 : char *MM_oemansi(char *szszChain)
2070 : {
2071 2475 : return MM_oemansi_n(szszChain, SIZE_MAX);
2072 : }
2073 :
2074 651 : static MM_BOOLEAN MM_FillFieldDB_XP(
2075 : struct MM_FIELD *camp, const char *FieldName,
2076 : const char *FieldDescriptionEng, const char *FieldDescriptionCat,
2077 : const char *FieldDescriptionSpa, char FieldType,
2078 : MM_BYTES_PER_FIELD_TYPE_DBF BytesPerField, MM_BYTE DecimalsIfFloat)
2079 : {
2080 : char nom_temp[MM_MAX_LON_FIELD_NAME_DBF];
2081 : int retorn_valida_nom_camp;
2082 :
2083 651 : if (FieldName)
2084 : {
2085 651 : retorn_valida_nom_camp = MM_ISExtendedNameBD_XP(FieldName);
2086 651 : if (retorn_valida_nom_camp == MM_DBF_NAME_NO_VALID)
2087 0 : return FALSE;
2088 651 : CPLStrlcpy(camp->FieldName, FieldName, MM_MAX_LON_FIELD_NAME_DBF);
2089 :
2090 651 : if (retorn_valida_nom_camp == MM_VALID_EXTENDED_DBF_NAME)
2091 : {
2092 0 : MM_CalculateBytesExtendedFieldName(camp);
2093 0 : CPLStrlcpy(nom_temp, FieldName, MM_MAX_LON_FIELD_NAME_DBF);
2094 0 : MM_ReturnValidClassicDBFFieldName(nom_temp);
2095 0 : nom_temp[MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF] = '\0';
2096 0 : CPLStrlcpy(camp->ClassicalDBFFieldName, nom_temp,
2097 : MM_MAX_LON_CLASSICAL_FIELD_NAME_DBF);
2098 : }
2099 : }
2100 :
2101 651 : if (FieldDescriptionEng)
2102 651 : CPLStrlcpy(camp->FieldDescription[MM_DEF_LANGUAGE], FieldDescriptionEng,
2103 : sizeof(camp->FieldDescription[MM_DEF_LANGUAGE]));
2104 : else
2105 0 : strcpy(camp->FieldDescription[MM_DEF_LANGUAGE], "\0");
2106 :
2107 651 : if (FieldDescriptionEng)
2108 651 : CPLStrlcpy(camp->FieldDescription[MM_ENG_LANGUAGE], FieldDescriptionEng,
2109 : sizeof(camp->FieldDescription[MM_ENG_LANGUAGE]));
2110 : else
2111 0 : strcpy(camp->FieldDescription[MM_ENG_LANGUAGE], "\0");
2112 :
2113 651 : if (FieldDescriptionCat)
2114 651 : CPLStrlcpy(camp->FieldDescription[MM_CAT_LANGUAGE], FieldDescriptionCat,
2115 : sizeof(camp->FieldDescription[MM_CAT_LANGUAGE]));
2116 : else
2117 0 : strcpy(camp->FieldDescription[MM_CAT_LANGUAGE], "\0");
2118 :
2119 651 : if (FieldDescriptionSpa)
2120 651 : CPLStrlcpy(camp->FieldDescription[MM_SPA_LANGUAGE], FieldDescriptionSpa,
2121 : sizeof(camp->FieldDescription[MM_SPA_LANGUAGE]));
2122 : else
2123 0 : strcpy(camp->FieldDescription[MM_SPA_LANGUAGE], "\0");
2124 :
2125 651 : camp->FieldType = FieldType;
2126 651 : camp->DecimalsIfFloat = DecimalsIfFloat;
2127 651 : camp->BytesPerField = BytesPerField;
2128 651 : return TRUE;
2129 : }
2130 :
2131 27 : size_t MM_DefineFirstPolygonFieldsDB_XP(struct MM_DATA_BASE_XP *bd_xp,
2132 : MM_BYTE n_perimeter_decimals,
2133 : MM_BYTE n_area_decimals_decimals)
2134 : {
2135 27 : MM_EXT_DBF_N_FIELDS i_camp = 0;
2136 :
2137 27 : MM_FillFieldDB_XP(
2138 27 : bd_xp->pField + i_camp, szMMNomCampIdGraficDefecte,
2139 : szInternalGraphicIdentifierEng, szInternalGraphicIdentifierCat,
2140 : szInternalGraphicIdentifierSpa, 'N', MM_MIN_WIDTH_ID_GRAFIC, 0);
2141 27 : bd_xp->IdGraficField = 0;
2142 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_ID_GRAFIC;
2143 27 : i_camp++;
2144 :
2145 27 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampNVertexsDefecte,
2146 : szNumberOfVerticesEng, szNumberOfVerticesCat,
2147 : szNumberOfVerticesSpa, 'N', MM_MIN_WIDTH_N_VERTEXS, 0);
2148 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_N_VERTEXS;
2149 27 : i_camp++;
2150 :
2151 27 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampPerimetreDefecte,
2152 : szPerimeterOfThePolygonEng, szPerimeterOfThePolygonCat,
2153 : szPerimeterOfThePolygonSpa, 'N', MM_MIN_WIDTH_LONG,
2154 : n_perimeter_decimals);
2155 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_PERIMETRE;
2156 27 : i_camp++;
2157 :
2158 27 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampAreaDefecte,
2159 : szAreaOfThePolygonEng, szAreaOfThePolygonCat,
2160 : szAreaOfThePolygonSpa, 'N', MM_MIN_WIDTH_AREA,
2161 : n_area_decimals_decimals);
2162 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_AREA;
2163 27 : i_camp++;
2164 :
2165 27 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampNArcsDefecte,
2166 : szNumberOfArcsEng, szNumberOfArcsCat, szNumberOfArcsSpa,
2167 : 'N', MM_MIN_WIDTH_N_ARCS, 0);
2168 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_N_ARCS;
2169 27 : i_camp++;
2170 :
2171 27 : MM_FillFieldDB_XP(
2172 27 : bd_xp->pField + i_camp, szMMNomCampNPoligonsDefecte,
2173 : szNumberOfElementaryPolygonsEng, szNumberOfElementaryPolygonsCat,
2174 : szNumberOfElementaryPolygonsSpa, 'N', MM_MIN_WIDTH_N_POLIG, 0);
2175 27 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_N_POLIG;
2176 27 : i_camp++;
2177 :
2178 27 : return i_camp;
2179 : }
2180 :
2181 57 : size_t MM_DefineFirstArcFieldsDB_XP(struct MM_DATA_BASE_XP *bd_xp,
2182 : MM_BYTE n_decimals)
2183 : {
2184 : MM_EXT_DBF_N_FIELDS i_camp;
2185 :
2186 57 : i_camp = 0;
2187 57 : MM_FillFieldDB_XP(
2188 57 : bd_xp->pField + i_camp, szMMNomCampIdGraficDefecte,
2189 : szInternalGraphicIdentifierEng, szInternalGraphicIdentifierCat,
2190 : szInternalGraphicIdentifierSpa, 'N', MM_MIN_WIDTH_ID_GRAFIC, 0);
2191 57 : bd_xp->IdGraficField = 0;
2192 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_ID_GRAFIC;
2193 57 : i_camp++;
2194 :
2195 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampNVertexsDefecte,
2196 : szNumberOfVerticesEng, szNumberOfVerticesCat,
2197 : szNumberOfVerticesSpa, 'N', MM_MIN_WIDTH_N_VERTEXS, 0);
2198 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_N_VERTEXS;
2199 57 : i_camp++;
2200 :
2201 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampLongitudArcDefecte,
2202 : szLengthOfAarcEng, szLengthOfAarcCat, szLengthOfAarcSpa,
2203 : 'N', MM_MIN_WIDTH_LONG, n_decimals);
2204 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_LONG_ARC;
2205 57 : i_camp++;
2206 :
2207 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampNodeIniDefecte,
2208 : szInitialNodeEng, szInitialNodeCat, szInitialNodeSpa, 'N',
2209 : MM_MIN_WIDTH_INITIAL_NODE, 0);
2210 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_NODE_INI;
2211 57 : i_camp++;
2212 :
2213 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampNodeFiDefecte,
2214 : szFinalNodeEng, szFinalNodeCat, szFinalNodeSpa, 'N',
2215 : MM_MIN_WIDTH_FINAL_NODE, 0);
2216 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_NODE_FI;
2217 57 : i_camp++;
2218 :
2219 57 : return i_camp;
2220 : }
2221 :
2222 57 : size_t MM_DefineFirstNodeFieldsDB_XP(struct MM_DATA_BASE_XP *bd_xp)
2223 : {
2224 : MM_EXT_DBF_N_FIELDS i_camp;
2225 :
2226 57 : i_camp = 0;
2227 :
2228 57 : MM_FillFieldDB_XP(
2229 57 : bd_xp->pField + i_camp, szMMNomCampIdGraficDefecte,
2230 : szInternalGraphicIdentifierEng, szInternalGraphicIdentifierCat,
2231 : szInternalGraphicIdentifierSpa, 'N', MM_MIN_WIDTH_ID_GRAFIC, 0);
2232 57 : bd_xp->IdGraficField = 0;
2233 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_ID_GRAFIC;
2234 57 : i_camp++;
2235 :
2236 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampArcsANodeDefecte,
2237 : szNumberOfArcsToNodeEng, szNumberOfArcsToNodeCat,
2238 : szNumberOfArcsToNodeSpa, 'N', MM_MIN_WIDTH_ARCS_TO_NODE,
2239 : 0);
2240 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_ARCS_A_NOD;
2241 57 : i_camp++;
2242 :
2243 57 : MM_FillFieldDB_XP(bd_xp->pField + i_camp, szMMNomCampTipusNodeDefecte,
2244 : szNodeTypeEng, szNodeTypeCat, szNodeTypeSpa, 'N', 1, 0);
2245 57 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_TIPUS_NODE;
2246 57 : i_camp++;
2247 :
2248 57 : return i_camp;
2249 : }
2250 :
2251 33 : size_t MM_DefineFirstPointFieldsDB_XP(struct MM_DATA_BASE_XP *bd_xp)
2252 : {
2253 33 : size_t i_camp = 0;
2254 :
2255 33 : MM_FillFieldDB_XP(
2256 33 : bd_xp->pField + i_camp, szMMNomCampIdGraficDefecte,
2257 : szInternalGraphicIdentifierEng, szInternalGraphicIdentifierCat,
2258 : szInternalGraphicIdentifierSpa, 'N', MM_MIN_WIDTH_ID_GRAFIC, 0);
2259 33 : bd_xp->IdGraficField = 0;
2260 33 : (bd_xp->pField + i_camp)->GeoTopoTypeField = (MM_BYTE)MM_CAMP_ES_ID_GRAFIC;
2261 33 : i_camp++;
2262 :
2263 33 : return i_camp;
2264 : }
2265 :
2266 : /*
2267 : Controlling the number of significant figures is often crucial in science
2268 : and technology, and the best option when nothing is known about the number
2269 : to be printed (if it is really small (near to 0), or very large), and
2270 : allows a good return (the same value) into memory when re-read from a text
2271 : file with scanf() functions.
2272 : If you need to print 0.00000000000000000000000000000000000000001 with %f
2273 : you will need an extremely large string. If you print 1980.45 with %E you
2274 : obtain 1.98045E+003, needing more space, and not being easy to interpret
2275 : for some people. Moreover, “normal” users do not want to see 1.0 as
2276 : 1.0E+000 or 1.0E+00. The choice of the format specifier, and the integer
2277 : to be passed to the ‘*’ is not always easy,
2278 : and MM_SprintfDoubleSignifFigures() automatically uses a “fair” notation
2279 : whenever it is possible, resulting in shorter strings, being them under
2280 : control (the maximum length of the resulting string is always known).
2281 : Moreover, it avoids some failures in compilers not expecting
2282 : NAN or INF values.
2283 : */
2284 233 : int MM_SprintfDoubleSignifFigures(char *szChain, size_t size_szChain,
2285 : int nSignifFigures, double dfRealValue)
2286 : {
2287 : double VALOR_LIMIT_PRINT_IN_FORMAT_E;
2288 : double VALOR_TOO_SMALL_TO_PRINT_f;
2289 : int retorn, exponent;
2290 : char *ptr;
2291 :
2292 : #define N_POWERS MM_MAX_XS_DOUBLE
2293 :
2294 : /* This expression ensures that no garbage is written in
2295 : the non-significant digits of the integer part, i.e., requesting 9E20
2296 : with 16 significant digits does not print 90000000000000004905, where
2297 : "4905" is garbage generated by the print call with such a large value
2298 : and "%.16f", but rather writes 9.000000000000000E+20.
2299 : At the same time, it ensures that 9000 requested with 4 significant
2300 : digits is written as 9000 and that requested with 5 significant digits
2301 : is written as 9000.0, but that requested with 3 significant digits is
2302 : written as 9.00E+03. */
2303 233 : double potencies_de_10[N_POWERS] = {
2304 : 1E+1, 1E+2, 1E+3, 1E+4, 1E+5, 1E+6, 1E+7, 1E+8, 1E+9,
2305 : 1E+10, 1E+11, 1E+12, 1E+13, 1E+14, 1E+15, 1E+16, 1E+17};
2306 :
2307 : /* This expression ensures that -9E-7 requested with 11 significant digits
2308 : still uses "natural" notation and gives -0.0000009000000000, which still
2309 : fits exactly within the 20 characters of a 'N' field in dBASE, while
2310 : requested with 12 significant digits jumps to exponential notation and
2311 : writes -9.00000000000E-07, which also fits (in this case, comfortably)
2312 : within the 20 characters of dBASE.
2313 : The expression could be replaced by: pow(10,-max(0,20-2-signif_digits)); */
2314 233 : double fraccions_de_10[N_POWERS + 1] = {
2315 : 1E-1, 1E-2, 1E-3, 1E-4, 1E-5, 1E-6, 1E-7, 1E-8, 1E-9,
2316 : 1E-10, 1E-11, 1E-12, 1E-13, 1E-14, 1E-15, 1E-16, 1E-17, 1E-18};
2317 :
2318 233 : if (!szChain)
2319 0 : return 0;
2320 :
2321 233 : if (size_szChain < 3)
2322 0 : return 0;
2323 :
2324 233 : memset(szChain, '\0', size_szChain);
2325 :
2326 233 : if (MM_IsNANDouble(dfRealValue))
2327 0 : return snprintf(szChain, size_szChain, "NAN");
2328 :
2329 233 : if (MM_IsDoubleInfinite(dfRealValue))
2330 0 : return snprintf(szChain, size_szChain, "INF");
2331 :
2332 233 : if (dfRealValue == 0.0)
2333 3 : return snprintf(szChain, size_szChain, "%.*f", nSignifFigures, 0.0);
2334 :
2335 230 : if (nSignifFigures < 1)
2336 0 : return snprintf(szChain, size_szChain, "0.0");
2337 :
2338 230 : if (nSignifFigures > N_POWERS)
2339 0 : nSignifFigures = N_POWERS;
2340 :
2341 230 : retorn = snprintf(szChain, size_szChain, "%.*E", nSignifFigures - 1,
2342 : dfRealValue);
2343 :
2344 230 : VALOR_LIMIT_PRINT_IN_FORMAT_E = potencies_de_10[nSignifFigures - 1];
2345 230 : VALOR_TOO_SMALL_TO_PRINT_f =
2346 230 : fraccions_de_10[MM_MAX_XS_DOUBLE - nSignifFigures];
2347 :
2348 230 : if (dfRealValue > VALOR_LIMIT_PRINT_IN_FORMAT_E ||
2349 212 : dfRealValue < -VALOR_LIMIT_PRINT_IN_FORMAT_E ||
2350 1 : (dfRealValue < VALOR_TOO_SMALL_TO_PRINT_f &&
2351 1 : dfRealValue > -VALOR_TOO_SMALL_TO_PRINT_f))
2352 18 : return retorn;
2353 :
2354 212 : ptr = strchr(szChain, 'E');
2355 212 : if (!ptr)
2356 0 : return 0;
2357 212 : exponent = atoi(ptr + 1);
2358 :
2359 212 : return sprintf(szChain, "%.*f",
2360 212 : (nSignifFigures - exponent - 1) > 0
2361 : ? (nSignifFigures - exponent - 1)
2362 : : 0,
2363 : dfRealValue);
2364 : #undef N_POWERS
2365 : } // End of SprintfDoubleXifSignif()
2366 :
2367 1331 : int MM_SecureCopyStringFieldValue(char **pszStringDst, const char *pszStringSrc,
2368 : MM_EXT_DBF_N_FIELDS *nStringCurrentLength)
2369 : {
2370 :
2371 1331 : if (!pszStringSrc)
2372 : {
2373 0 : if (1 >= *nStringCurrentLength)
2374 : {
2375 0 : void *new_ptr = realloc_function(*pszStringDst, 2);
2376 0 : if (!new_ptr)
2377 0 : return 1;
2378 0 : *pszStringDst = new_ptr;
2379 0 : *nStringCurrentLength = (MM_EXT_DBF_N_FIELDS)2;
2380 : }
2381 0 : strcpy(*pszStringDst, "\0");
2382 0 : return 0;
2383 : }
2384 :
2385 1331 : if (strlen(pszStringSrc) >= *nStringCurrentLength)
2386 : {
2387 : void *new_ptr =
2388 450 : realloc_function(*pszStringDst, strlen(pszStringSrc) + 1);
2389 450 : if (!new_ptr)
2390 0 : return 1;
2391 450 : (*pszStringDst) = new_ptr;
2392 450 : *nStringCurrentLength = (MM_EXT_DBF_N_FIELDS)(strlen(pszStringSrc) + 1);
2393 : }
2394 1331 : strcpy(*pszStringDst, pszStringSrc);
2395 1331 : return 0;
2396 : }
2397 :
2398 : // This function assumes that all the file is saved in disk and closed.
2399 117 : int MM_ChangeDBFWidthField(struct MM_DATA_BASE_XP *data_base_XP,
2400 : MM_EXT_DBF_N_FIELDS nIField,
2401 : MM_BYTES_PER_FIELD_TYPE_DBF nNewWidth,
2402 : MM_BYTE nNewPrecision)
2403 : {
2404 117 : char *record, *whites = nullptr;
2405 : MM_BYTES_PER_FIELD_TYPE_DBF l_glop1, l_glop2, i_glop2;
2406 : MM_EXT_DBF_N_RECORDS nfitx, i_reg;
2407 : int canvi_amplada; // change width
2408 : GInt32 j;
2409 : MM_EXT_DBF_N_FIELDS i_camp;
2410 : size_t retorn_fwrite;
2411 : int retorn_TruncaFitxer;
2412 :
2413 117 : if (!data_base_XP)
2414 0 : return 1;
2415 :
2416 117 : canvi_amplada = nNewWidth - data_base_XP->pField[nIField].BytesPerField;
2417 :
2418 117 : if (data_base_XP->nRecords != 0)
2419 : {
2420 48 : l_glop1 = data_base_XP->pField[nIField].AccumulatedBytes;
2421 48 : i_glop2 = l_glop1 + data_base_XP->pField[nIField].BytesPerField;
2422 48 : if (nIField == data_base_XP->nFields - 1)
2423 26 : l_glop2 = 0;
2424 : else
2425 22 : l_glop2 = data_base_XP->BytesPerRecord -
2426 22 : data_base_XP->pField[nIField + 1].AccumulatedBytes;
2427 :
2428 48 : if ((record = calloc_function((size_t)data_base_XP->BytesPerRecord)) ==
2429 : nullptr)
2430 0 : return 1;
2431 :
2432 48 : record[data_base_XP->BytesPerRecord - 1] = MM_SetEndOfString;
2433 :
2434 48 : if ((whites = (char *)calloc_function((size_t)nNewWidth)) == nullptr)
2435 : {
2436 0 : free_function(record);
2437 0 : return 1;
2438 : }
2439 48 : memset(whites, ' ', nNewWidth);
2440 :
2441 48 : nfitx = data_base_XP->nRecords;
2442 48 : i_reg = (canvi_amplada < 0 ? 0 : nfitx - 1);
2443 : while (TRUE)
2444 : {
2445 48 : if (0 != fseek_function(data_base_XP->pfDataBase,
2446 : data_base_XP->FirstRecordOffset +
2447 : (MM_FILE_OFFSET)i_reg *
2448 : data_base_XP->BytesPerRecord,
2449 : SEEK_SET))
2450 : {
2451 0 : free_function(whites);
2452 0 : free_function(record);
2453 0 : return 1;
2454 : }
2455 :
2456 48 : if (1 != fread_function(record, data_base_XP->BytesPerRecord, 1,
2457 : data_base_XP->pfDataBase))
2458 : {
2459 0 : free_function(whites);
2460 0 : free_function(record);
2461 0 : return 1;
2462 : }
2463 :
2464 48 : if (0 !=
2465 48 : fseek_function(
2466 : data_base_XP->pfDataBase,
2467 : (MM_FILE_OFFSET)data_base_XP->FirstRecordOffset +
2468 : i_reg * ((MM_FILE_OFFSET)data_base_XP->BytesPerRecord +
2469 : canvi_amplada),
2470 : SEEK_SET))
2471 : {
2472 0 : free_function(whites);
2473 0 : free_function(record);
2474 0 : return 1;
2475 : }
2476 :
2477 48 : if (1 !=
2478 48 : fwrite_function(record, l_glop1, 1, data_base_XP->pfDataBase))
2479 : {
2480 0 : free_function(whites);
2481 0 : free_function(record);
2482 0 : return 1;
2483 : }
2484 :
2485 48 : switch (data_base_XP->pField[nIField].FieldType)
2486 : {
2487 30 : case 'C':
2488 : case 'L':
2489 30 : memcpy(whites, record + l_glop1,
2490 : (canvi_amplada < 0
2491 : ? nNewWidth
2492 30 : : data_base_XP->pField[nIField].BytesPerField));
2493 30 : retorn_fwrite = fwrite_function(whites, nNewWidth, 1,
2494 : data_base_XP->pfDataBase);
2495 :
2496 30 : if (1 != retorn_fwrite)
2497 : {
2498 0 : free_function(whites);
2499 0 : free_function(record);
2500 0 : return 1;
2501 : }
2502 30 : break;
2503 18 : case 'N':
2504 :
2505 18 : if (canvi_amplada >= 0)
2506 : {
2507 18 : if (1 != fwrite_function(whites, canvi_amplada, 1,
2508 18 : data_base_XP->pfDataBase) ||
2509 : 1 !=
2510 18 : fwrite_function(
2511 : record + l_glop1,
2512 : data_base_XP->pField[nIField].BytesPerField,
2513 : 1, data_base_XP->pfDataBase))
2514 : {
2515 0 : free_function(whites);
2516 0 : free_function(record);
2517 0 : return 1;
2518 : }
2519 : }
2520 0 : else if (canvi_amplada < 0)
2521 : {
2522 0 : j = (GInt32)(l_glop1 + (data_base_XP->pField[nIField]
2523 0 : .BytesPerField -
2524 : 1));
2525 : while (TRUE)
2526 : {
2527 0 : j--;
2528 :
2529 0 : if (j < (GInt32)l_glop1 || record[j] == ' ')
2530 : {
2531 0 : j++;
2532 0 : break;
2533 : }
2534 : }
2535 :
2536 0 : if ((data_base_XP->pField[nIField].BytesPerField +
2537 0 : l_glop1 - j) < nNewWidth)
2538 0 : j -= (GInt32)(nNewWidth -
2539 0 : (data_base_XP->pField[nIField]
2540 0 : .BytesPerField +
2541 : l_glop1 - j));
2542 :
2543 0 : retorn_fwrite = fwrite_function(
2544 : record + j, nNewWidth, 1, data_base_XP->pfDataBase);
2545 0 : if (1 != retorn_fwrite)
2546 : {
2547 0 : free_function(whites);
2548 0 : free_function(record);
2549 0 : return 1;
2550 : }
2551 : }
2552 :
2553 18 : break;
2554 0 : default:
2555 0 : free_function(whites);
2556 0 : free_function(record);
2557 0 : return 1;
2558 : }
2559 48 : if (l_glop2)
2560 : {
2561 22 : retorn_fwrite = fwrite_function(record + i_glop2, l_glop2, 1,
2562 : data_base_XP->pfDataBase);
2563 22 : if (1 != retorn_fwrite)
2564 : {
2565 0 : free_function(whites);
2566 0 : free_function(record);
2567 0 : return 1;
2568 : }
2569 : }
2570 :
2571 48 : if (canvi_amplada < 0)
2572 : {
2573 0 : if (i_reg + 1 == nfitx)
2574 0 : break;
2575 0 : i_reg++;
2576 : }
2577 : else
2578 : {
2579 48 : if (i_reg == 0)
2580 48 : break;
2581 0 : i_reg--;
2582 : }
2583 : }
2584 :
2585 48 : free_function(whites);
2586 48 : free_function(record);
2587 :
2588 48 : retorn_TruncaFitxer = TruncateFile_function(
2589 : data_base_XP->pfDataBase,
2590 : (MM_FILE_OFFSET)data_base_XP->FirstRecordOffset +
2591 : (MM_FILE_OFFSET)data_base_XP->nRecords *
2592 : ((MM_FILE_OFFSET)data_base_XP->BytesPerRecord +
2593 : canvi_amplada));
2594 48 : if (canvi_amplada < 0 && retorn_TruncaFitxer)
2595 0 : return 1;
2596 : } /* Fi de registres de != 0*/
2597 :
2598 117 : if (canvi_amplada != 0)
2599 : {
2600 117 : data_base_XP->pField[nIField].BytesPerField = nNewWidth;
2601 117 : data_base_XP->BytesPerRecord += canvi_amplada;
2602 117 : for (i_camp = (MM_EXT_DBF_N_FIELDS)(nIField + 1);
2603 477 : i_camp < data_base_XP->nFields; i_camp++)
2604 360 : data_base_XP->pField[i_camp].AccumulatedBytes += canvi_amplada;
2605 : }
2606 117 : data_base_XP->pField[nIField].DecimalsIfFloat = nNewPrecision;
2607 :
2608 117 : if ((MM_OpenIfNeededAndUpdateEntireHeader(data_base_XP)) == FALSE)
2609 0 : return 1;
2610 :
2611 117 : return 0;
2612 : } /* End of MMChangeCFieldWidthDBF() */
2613 :
2614 1525 : static void MM_AdoptHeight(double *desti, const double *proposta, uint32_t flag)
2615 : {
2616 1525 : if (*proposta == MM_NODATA_COORD_Z)
2617 0 : return;
2618 :
2619 1525 : if (flag & MM_STRING_HIGHEST_ALTITUDE)
2620 : {
2621 0 : if (*desti == MM_NODATA_COORD_Z || *desti < *proposta)
2622 0 : *desti = *proposta;
2623 : }
2624 1525 : else if (flag & MM_STRING_LOWEST_ALTITUDE)
2625 : {
2626 0 : if (*desti == MM_NODATA_COORD_Z || *desti > *proposta)
2627 0 : *desti = *proposta;
2628 : }
2629 : else
2630 : {
2631 : // First coordinate of this vertice
2632 1525 : if (*desti == MM_NODATA_COORD_Z)
2633 1525 : *desti = *proposta;
2634 : }
2635 : }
2636 :
2637 665 : int MM_GetArcHeights(double *coord_z, FILE_TYPE *pF, MM_N_VERTICES_TYPE n_vrt,
2638 : struct MM_ZD *pZDescription, uint32_t flag)
2639 : {
2640 : MM_N_HEIGHT_TYPE i;
2641 : MM_N_VERTICES_TYPE i_vrt;
2642 : double *pcoord_z;
2643 : MM_N_HEIGHT_TYPE n_alcada, n_h_total;
2644 : int tipus;
2645 665 : double *alcada = nullptr, *palcada, *palcada_i;
2646 : #define MM_N_ALCADA_LOCAL 50 // Nr of local heights
2647 : double local_CinquantaAlcades[MM_N_ALCADA_LOCAL];
2648 :
2649 2192 : for (i_vrt = 0; i_vrt < n_vrt; i_vrt++)
2650 1527 : coord_z[i_vrt] = MM_NODATA_COORD_Z;
2651 :
2652 665 : if (pZDescription->nZCount == INT_MIN)
2653 0 : return 0;
2654 665 : tipus = MM_ARC_HEIGHT_TYPE(pZDescription->nZCount);
2655 665 : n_alcada = MM_ARC_N_HEIGHTS(pZDescription->nZCount);
2656 665 : if (n_vrt == 0 || n_alcada == 0)
2657 0 : return 0;
2658 :
2659 665 : if (tipus == MM_ARC_HEIGHT_FOR_EACH_VERTEX)
2660 : {
2661 664 : if (n_vrt > (unsigned)(INT_MAX / n_alcada))
2662 : {
2663 0 : MMCPLError(CE_Failure, CPLE_OutOfMemory, "Integer overflow");
2664 0 : return 1;
2665 : }
2666 664 : n_h_total = (MM_N_HEIGHT_TYPE)n_vrt * n_alcada;
2667 : }
2668 : else
2669 1 : n_h_total = n_alcada;
2670 :
2671 665 : if (n_h_total <= MM_N_ALCADA_LOCAL)
2672 665 : palcada = local_CinquantaAlcades;
2673 : else
2674 : {
2675 0 : if (MMCheckSize_t(n_h_total, sizeof(double)))
2676 0 : return 1;
2677 0 : if (nullptr == (palcada = alcada = calloc_function((size_t)n_h_total *
2678 : sizeof(double))))
2679 0 : return 1;
2680 : }
2681 :
2682 665 : if (fseek_function(pF, pZDescription->nOffsetZ, SEEK_SET))
2683 : {
2684 0 : if (alcada)
2685 0 : free_function(alcada);
2686 0 : return 1;
2687 : }
2688 665 : if (n_h_total != (MM_N_HEIGHT_TYPE)fread_function(palcada, sizeof(double),
2689 : n_h_total, pF))
2690 : {
2691 0 : if (alcada)
2692 0 : free_function(alcada);
2693 0 : return 1;
2694 : }
2695 :
2696 665 : if (tipus == MM_ARC_HEIGHT_FOR_EACH_VERTEX)
2697 : {
2698 664 : palcada_i = palcada;
2699 1328 : for (i = 0; i < n_alcada; i++)
2700 : {
2701 2188 : for (i_vrt = 0, pcoord_z = coord_z; i_vrt < n_vrt;
2702 1524 : i_vrt++, pcoord_z++, palcada_i++)
2703 1524 : MM_AdoptHeight(pcoord_z, palcada_i, flag);
2704 : }
2705 : }
2706 : else
2707 : {
2708 1 : palcada_i = palcada;
2709 1 : pcoord_z = coord_z;
2710 2 : for (i = 0; i < n_alcada; i++, palcada_i++)
2711 1 : MM_AdoptHeight(pcoord_z, palcada_i, flag);
2712 :
2713 1 : if (*pcoord_z != MM_NODATA_COORD_Z)
2714 : {
2715 : /*Copio el mateix valor a totes les alcades.*/
2716 3 : for (i_vrt = 1, pcoord_z++; i_vrt < (size_t)n_vrt;
2717 2 : i_vrt++, pcoord_z++)
2718 2 : *pcoord_z = *coord_z;
2719 : }
2720 : }
2721 665 : if (alcada)
2722 0 : free_function(alcada);
2723 665 : return 0;
2724 : } // End of MM_GetArcHeights()
2725 :
2726 15322 : static char *MM_l_RemoveWhitespacesFromEndOfString(char *punter,
2727 : size_t l_szChain)
2728 : {
2729 15322 : size_t longitud_szChain = l_szChain;
2730 34628 : while (longitud_szChain > 0)
2731 : {
2732 34216 : longitud_szChain--;
2733 34216 : if (punter[longitud_szChain] != ' ' && punter[longitud_szChain] != '\t')
2734 : {
2735 14910 : break;
2736 : }
2737 19306 : punter[longitud_szChain] = '\0';
2738 : }
2739 15322 : return punter;
2740 : }
2741 :
2742 50 : char *MM_RemoveInitial_and_FinalQuotationMarks(char *szChain)
2743 : {
2744 : char *ptr1, *ptr2;
2745 50 : char cometa = '"';
2746 :
2747 50 : if (*szChain == cometa)
2748 : {
2749 11 : ptr1 = szChain;
2750 11 : ptr2 = ptr1 + 1;
2751 11 : if (*ptr2)
2752 : {
2753 182 : while (*ptr2)
2754 : {
2755 171 : *ptr1 = *ptr2;
2756 171 : ptr1++;
2757 171 : ptr2++;
2758 : }
2759 11 : if (*ptr1 == cometa)
2760 11 : *(ptr1 - 1) = 0;
2761 : else
2762 0 : *ptr1 = 0;
2763 : }
2764 : }
2765 50 : return szChain;
2766 : } /* End of MM_RemoveInitial_and_FinalQuotationMarks() */
2767 :
2768 84 : char *MM_RemoveLeadingWhitespaceOfString(char *szChain)
2769 : {
2770 : char *ptr;
2771 : char *ptr2;
2772 :
2773 84 : if (szChain == nullptr)
2774 0 : return szChain;
2775 :
2776 630 : for (ptr = szChain; *ptr && (*ptr == ' ' || *ptr == '\t'); ptr++)
2777 546 : continue;
2778 :
2779 84 : if (ptr != szChain)
2780 : {
2781 66 : ptr2 = szChain;
2782 534 : while (*ptr)
2783 : {
2784 468 : *ptr2 = *ptr;
2785 468 : ptr2++;
2786 468 : ptr++;
2787 : }
2788 66 : *ptr2 = 0;
2789 : }
2790 84 : return szChain;
2791 : }
2792 :
2793 15322 : char *MM_RemoveWhitespacesFromEndOfString(char *str)
2794 : {
2795 15322 : if (str == nullptr)
2796 0 : return str;
2797 15322 : return MM_l_RemoveWhitespacesFromEndOfString(str, strlen(str));
2798 : }
2799 :
2800 111 : struct MM_ID_GRAFIC_MULTIPLE_RECORD *MMCreateExtendedDBFIndex(
2801 : FILE_TYPE *f, MM_EXT_DBF_N_RECORDS nNumberOfRecords,
2802 : MM_FIRST_RECORD_OFFSET_TYPE offset_1era,
2803 : MM_ACCUMULATED_BYTES_TYPE_DBF bytes_per_fitxa,
2804 : MM_ACCUMULATED_BYTES_TYPE_DBF bytes_acumulats_id_grafic,
2805 : MM_BYTES_PER_FIELD_TYPE_DBF bytes_id_grafic, MM_BOOLEAN *isListField,
2806 : MM_EXT_DBF_N_RECORDS *nMaxN)
2807 : {
2808 : struct MM_ID_GRAFIC_MULTIPLE_RECORD *id;
2809 : MM_EXT_DBF_N_RECORDS i_dbf;
2810 : MM_EXT_DBF_SIGNED_N_RECORDS i, id_grafic;
2811 : char *fitxa;
2812 111 : MM_BYTES_PER_FIELD_TYPE_DBF bytes_final_id_principi_id1 =
2813 : bytes_per_fitxa - bytes_id_grafic;
2814 :
2815 111 : *isListField = FALSE;
2816 111 : *nMaxN = 0;
2817 111 : if (!nNumberOfRecords)
2818 9 : return nullptr; // No elements to read
2819 :
2820 102 : if (MMCheckSize_t(nNumberOfRecords, sizeof(*id)))
2821 0 : return nullptr;
2822 102 : if (nullptr == (id = (struct MM_ID_GRAFIC_MULTIPLE_RECORD *)calloc_function(
2823 : (size_t)nNumberOfRecords * sizeof(*id))))
2824 0 : return nullptr;
2825 :
2826 102 : if (bytes_id_grafic == UINT32_MAX)
2827 : {
2828 0 : free_function(id);
2829 0 : MMCPLError(CE_Failure, CPLE_OutOfMemory,
2830 : "Overflow in bytes_id_graphic");
2831 0 : return nullptr;
2832 : }
2833 :
2834 102 : if (nullptr ==
2835 102 : (fitxa = (char *)calloc_function((size_t)bytes_id_grafic + 1)))
2836 : {
2837 0 : free_function(id);
2838 0 : return nullptr;
2839 : }
2840 102 : fitxa[bytes_id_grafic] = '\0';
2841 :
2842 102 : fseek_function(f,
2843 : (MM_FILE_OFFSET)offset_1era +
2844 : (MM_FILE_OFFSET)bytes_acumulats_id_grafic,
2845 : SEEK_SET);
2846 :
2847 102 : i_dbf = 0;
2848 : do
2849 : {
2850 102 : if (i_dbf == nNumberOfRecords ||
2851 102 : fread_function(fitxa, 1, bytes_id_grafic, f) !=
2852 : (size_t)bytes_id_grafic)
2853 : {
2854 0 : free_function(id);
2855 0 : free_function(fitxa);
2856 0 : return nullptr;
2857 : }
2858 102 : i_dbf++;
2859 : } while (1 !=
2860 204 : sscanf(fitxa, scanf_MM_EXT_DBF_SIGNED_N_RECORDS, &id_grafic) ||
2861 102 : id_grafic < 0);
2862 102 : i = 0;
2863 :
2864 : while (TRUE)
2865 : {
2866 557 : if (i > id_grafic)
2867 : {
2868 0 : free_function(id);
2869 0 : free_function(fitxa);
2870 0 : return nullptr;
2871 : }
2872 557 : i = id_grafic;
2873 557 : if (i >= (MM_EXT_DBF_SIGNED_N_RECORDS)nNumberOfRecords)
2874 : {
2875 0 : free_function(fitxa);
2876 0 : return id;
2877 : }
2878 557 : id[(size_t)i].offset = (MM_FILE_OFFSET)offset_1era +
2879 557 : (MM_FILE_OFFSET)(i_dbf - 1) * bytes_per_fitxa;
2880 : do
2881 : {
2882 599 : id[(size_t)i].nMR++;
2883 599 : if (!(*isListField) && id[(size_t)i].nMR > 1)
2884 33 : *isListField = TRUE;
2885 599 : if (*nMaxN < id[(size_t)i].nMR)
2886 139 : *nMaxN = id[(size_t)i].nMR;
2887 :
2888 599 : if (i_dbf == nNumberOfRecords)
2889 : {
2890 102 : free_function(fitxa);
2891 102 : return id;
2892 : }
2893 497 : fseek_function(f, bytes_final_id_principi_id1, SEEK_CUR);
2894 497 : if (fread_function(fitxa, 1, bytes_id_grafic, f) !=
2895 : (size_t)bytes_id_grafic)
2896 : {
2897 0 : free_function(id);
2898 0 : free_function(fitxa);
2899 0 : return nullptr;
2900 : }
2901 497 : if (1 != sscanf(fitxa, scanf_MM_EXT_DBF_SIGNED_N_RECORDS,
2902 497 : &id_grafic) ||
2903 497 : id_grafic >= (MM_EXT_DBF_SIGNED_N_RECORDS)nNumberOfRecords)
2904 : {
2905 0 : free_function(fitxa);
2906 0 : return id;
2907 : }
2908 497 : i_dbf++;
2909 497 : } while (id_grafic == i);
2910 : }
2911 : } // End of MMCreateExtendedDBFIndex()
2912 :
2913 : #ifdef GDAL_COMPILATION
2914 : CPL_C_END // Necessary for compiling in GDAL project
2915 : #endif
|