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

Generated by: LCOV version 1.14