📄 mitab_utils.cpp
字号:
/*-----------------------------------------------------------------
* None of the extensions worked!
* Try adjusting cases in the whole path and filename
*----------------------------------------------------------------*/
return TABAdjustCaseSensitiveFilename(pszFname);
}
/**********************************************************************
* TABGetBasename()
*
* Extract the basename part of a complete file path.
*
* Returns a newly allocated string without the leading path (dirs) and
* the extenstion. The returned string should be freed using CPLFree().
**********************************************************************/
char *TABGetBasename(const char *pszFname)
{
const char *pszTmp = NULL;
/*-----------------------------------------------------------------
* Skip leading path or use whole name if no path dividers are
* encountered.
*----------------------------------------------------------------*/
pszTmp = pszFname + strlen(pszFname) - 1;
while ( pszTmp != pszFname
&& *pszTmp != '/' && *pszTmp != '\\' )
pszTmp--;
if( pszTmp != pszFname )
pszTmp++;
/*-----------------------------------------------------------------
* Now allocate our own copy and remove extension
*----------------------------------------------------------------*/
char *pszBasename = CPLStrdup(pszTmp);
int i;
for(i=0; pszBasename[i] != '\0'; i++)
{
if (pszBasename[i] == '.')
{
pszBasename[i] = '\0';
break;
}
}
return pszBasename;
}
/**********************************************************************
* TAB_CSLLoad()
*
* Same as CSLLoad(), but does not produce an error if it fails... it
* just returns NULL silently instead.
*
* Load a test file into a stringlist.
*
* Lines are limited in length by the size fo the CPLReadLine() buffer.
**********************************************************************/
char **TAB_CSLLoad(const char *pszFname)
{
FILE *fp;
const char *pszLine;
char **papszStrList=NULL;
fp = VSIFOpen(pszFname, "rt");
if (fp)
{
while(!VSIFEof(fp))
{
if ( (pszLine = CPLReadLine(fp)) != NULL )
{
papszStrList = CSLAddString(papszStrList, pszLine);
}
}
VSIFClose(fp);
}
return papszStrList;
}
/**********************************************************************
* TABUnEscapeString()
*
* Convert a string that can possibly contain escaped "\n" chars in
* into into a new one with binary newlines in it.
*
* Tries to work on hte original buffer unless bSrcIsConst=TRUE, in
* which case the original is always untouched and a copy is allocated
* ONLY IF NECESSARY. This means that the caller should compare the
* return value and the source (pszString) to see if a copy was returned,
* in which case the caller becomes responsible of freeing both the
* source and the copy.
**********************************************************************/
char *TABUnEscapeString(char *pszString, GBool bSrcIsConst)
{
/*-----------------------------------------------------------------
* First check if we need to do any replacement
*----------------------------------------------------------------*/
if (pszString == NULL || strstr(pszString, "\\n") == NULL)
{
return pszString;
}
/*-----------------------------------------------------------------
* Yes, we need to replace at least one "\n"
* We try to work on the original buffer unless we have bSrcIsConst=TRUE
*
* Note that we do not worry about freeing the source buffer when we
* return a copy... it is up to the caller to decide if he needs to
* free the source based on context and by comparing pszString with
* the returned pointer (pszWorkString) to see if they are identical.
*----------------------------------------------------------------*/
char *pszWorkString = NULL;
int i =0;
int j =0;
if (bSrcIsConst)
{
// We have to create a copy to work on.
pszWorkString = (char *)CPLMalloc(sizeof(char) *
(strlen(pszString) +1));
}
else
{
// We'll work on the original.
pszWorkString = pszString;
}
while (pszString[i])
{
if (pszString[i] =='\\' &&
pszString[i+1] == 'n')
{
pszWorkString[j++] = '\n';
i+= 2;
}
else if (pszString[i] =='\\' &&
pszString[i+1] == '\\')
{
pszWorkString[j++] = '\\';
i+= 2;
}
else
{
pszWorkString[j++] = pszString[i++];
}
}
pszWorkString[j++] = '\0';
return pszWorkString;
}
/**********************************************************************
* TABEscapeString()
*
* Convert a string that can possibly contain binary "\n" chars in
* into into a new one with escaped newlines ("\\" + "n") in it.
*
* The function returns the original string pointer if it did not need to
* be modified, or a copy that has to be freed by the caller if the
* string had to be modified.
*
* It is up to the caller to decide if he needs to free the returned
* string by comparing the source (pszString) pointer with the returned
* pointer (pszWorkString) to see if they are identical.
**********************************************************************/
char *TABEscapeString(char *pszString)
{
/*-----------------------------------------------------------------
* First check if we need to do any replacement
*----------------------------------------------------------------*/
if (pszString == NULL || strchr(pszString, '\n') == NULL)
{
return pszString;
}
/*-----------------------------------------------------------------
* OK, we need to do some replacements... alloc a copy big enough
* to hold the worst possible case
*----------------------------------------------------------------*/
char *pszWorkString = (char *)CPLMalloc(2*sizeof(char) *
(strlen(pszString) +1));
int i =0;
int j =0;
while (pszString[i])
{
if (pszString[i] =='\n')
{
pszWorkString[j++] = '\\';
pszWorkString[j++] = 'n';
i++;
}
else if (pszString[i] =='\\')
{
pszWorkString[j++] = '\\';
pszWorkString[j++] = '\\';
i++;
}
else
{
pszWorkString[j++] = pszString[i++];
}
}
pszWorkString[j++] = '\0';
return pszWorkString;
}
/**********************************************************************
* TABCleanFieldName()
*
* Return a copy of pszSrcName that contains only valid characters for a
* TAB field name. All invalid characters are replaced by '_'.
*
* The returned string should be freed by the caller.
**********************************************************************/
char *TABCleanFieldName(const char *pszSrcName)
{
char *pszNewName;
int numInvalidChars = 0;
pszNewName = CPLStrdup(pszSrcName);
if (strlen(pszNewName) > 31)
{
pszNewName[31] = '\0';
CPLError(CE_Warning, TAB_WarningInvalidFieldName,
"Field name '%s' is longer than the max of 31 characters. "
"'%s' will be used instead.", pszSrcName, pszNewName);
}
#if defined(_WIN32) && !defined(unix) && !defined(WIN32CE)
/*-----------------------------------------------------------------
* On Windows, check if we're using a double-byte codepage, and
* if so then just keep the field name as is...
*----------------------------------------------------------------*/
if (_getmbcp() != 0)
return pszNewName;
#endif
/*-----------------------------------------------------------------
* According to the MapInfo User's Guide (p. 240, v5.5)
* New Table Command:
* Name:
* Displays the field name in the name box. You can also enter new field
* names here. Defaults are Field1, Field2, etc. A field name can contain
* up to 31 alphanumeric characters. Use letters, numbers, and the
* underscore. Do not use spaces; instead, use the underscore character
* (_) to separate words in a field name. Use upper and lower case for
* legibility, but MapInfo is not case-sensitive.
*
* It was also verified that extended chars with accents are also
* accepted.
*----------------------------------------------------------------*/
for(int i=0; pszSrcName && pszSrcName[i] != '\0'; i++)
{
if ( !( pszSrcName[i] == '_' ||
(pszSrcName[i]>='0' && pszSrcName[i]<='9') ||
(pszSrcName[i]>='a' && pszSrcName[i]<='z') ||
(pszSrcName[i]>='A' && pszSrcName[i]<='Z') ||
(GByte)pszSrcName[i]>=192 ) )
{
pszNewName[i] = '_';
numInvalidChars++;
}
}
if (numInvalidChars > 0)
{
CPLError(CE_Warning, TAB_WarningInvalidFieldName,
"Field name '%s' contains invalid characters. "
"'%s' will be used instead.", pszSrcName, pszNewName);
}
return pszNewName;
}
/**********************************************************************
* MapInfo Units string to numeric ID conversion
**********************************************************************/
typedef struct
{
int nUnitId;
char *pszAbbrev;
} MapInfoUnitsInfo;
static MapInfoUnitsInfo gasUnitsList[] =
{
{0, "mi"},
{1, "km"},
{2, "in"},
{3, "ft"},
{4, "yd"},
{5, "mm"},
{6, "cm"},
{7, "m"},
{8, "survey ft"},
{9, "nmi"},
{30, "li"},
{31, "ch"},
{32, "rd"},
{-1, NULL}
};
/**********************************************************************
* TABUnitIdToString()
*
* Return the MIF units name for specified units id.
* Return "" if no match found.
*
* The returned string should not be freed by the caller.
**********************************************************************/
const char *TABUnitIdToString(int nId)
{
MapInfoUnitsInfo *psList;
psList = gasUnitsList;
while(psList->nUnitId != -1)
{
if (psList->nUnitId == nId)
return psList->pszAbbrev;
psList++;
}
return "";
}
/**********************************************************************
* TABUnitIdFromString()
*
* Return the units ID for specified MIF units name
*
* Returns -1 if no match found.
**********************************************************************/
int TABUnitIdFromString(const char *pszName)
{
MapInfoUnitsInfo *psList;
psList = gasUnitsList;
while(psList->nUnitId != -1)
{
if (EQUAL(psList->pszAbbrev, pszName))
return psList->nUnitId;
psList++;
}
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -