LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/miramon - mm_gdal_functions.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 874 1404 62.3 %
Date: 2025-03-28 11:40:40 Functions: 48 50 96.0 %

          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(&currentTime, &ltime);
    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(&currentTime);
    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

Generated by: LCOV version 1.14