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: 857 1318 65.0 %
Date: 2024-05-18 15:15:27 Functions: 47 49 95.9 %

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

Generated by: LCOV version 1.14