gdal/apps/ogrinfo_bin.cpp

191 lines
6.4 KiB
C++

/******************************************************************************
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Simple client for viewing OGR driver data.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1999, Frank Warmerdam
* Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
*
* SPDX-License-Identifier: MIT
****************************************************************************/
#include "cpl_port.h"
#include "gdal_version.h"
#include "gdal_priv.h"
#include "gdal_utils_priv.h"
#include "ogr_p.h"
#include "commonutils.h"
/************************************************************************/
/* Usage() */
/************************************************************************/
static void Usage()
{
fprintf(stderr, "%s\n", GDALVectorInfoGetParserUsage().c_str());
exit(1);
}
/************************************************************************/
/* main() */
/************************************************************************/
MAIN_START(argc, argv)
{
// Check strict compilation and runtime library version as we use C++ API.
if (!GDAL_CHECK_VERSION(argv[0]))
exit(1);
EarlySetConfigOptions(argc, argv);
OGRRegisterAll();
argc = OGRGeneralCmdLineProcessor(argc, &argv, 0);
if (argc < 1)
exit(-argc);
auto psOptionsForBinary =
std::make_unique<GDALVectorInfoOptionsForBinary>();
GDALVectorInfoOptions *psOptions =
GDALVectorInfoOptionsNew(argv + 1, psOptionsForBinary.get());
if (psOptions == nullptr)
Usage();
/* -------------------------------------------------------------------- */
/* Open dataset. */
/* -------------------------------------------------------------------- */
#ifdef __AFL_HAVE_MANUAL_CONTROL
int iIter = 0;
while (__AFL_LOOP(1000))
{
iIter++;
#endif
/* --------------------------------------------------------------------
*/
/* Open data source. */
/* --------------------------------------------------------------------
*/
int nFlags = GDAL_OF_VECTOR;
bool bMayRetryUpdateMode = false;
if (psOptionsForBinary->bUpdate)
nFlags |= GDAL_OF_UPDATE | GDAL_OF_VERBOSE_ERROR;
else if (psOptionsForBinary->bReadOnly)
nFlags |= GDAL_OF_READONLY | GDAL_OF_VERBOSE_ERROR;
else if (psOptionsForBinary->osSQLStatement.empty())
{
nFlags |= GDAL_OF_READONLY;
// GDALIdentifyDriverEx() might emit an error message, e.g.
// when opening "/vsizip/foo.zip/" and the zip has more than one
// file. Cf https://github.com/OSGeo/gdal/issues/9459
CPLErrorHandlerPusher oErrorHandler(CPLQuietErrorHandler);
if (GDALIdentifyDriverEx(
psOptionsForBinary->osFilename.c_str(), GDAL_OF_VECTOR,
psOptionsForBinary->aosAllowInputDrivers.List(), nullptr))
{
bMayRetryUpdateMode = true;
}
else
{
// And an error Will be emitted
nFlags |= GDAL_OF_VERBOSE_ERROR;
}
}
else
nFlags |= GDAL_OF_UPDATE | GDAL_OF_VERBOSE_ERROR;
GDALDataset *poDS = GDALDataset::Open(
psOptionsForBinary->osFilename.c_str(), nFlags,
psOptionsForBinary->aosAllowInputDrivers.List(),
psOptionsForBinary->aosOpenOptions.List(), nullptr);
if (poDS == nullptr && !psOptionsForBinary->bReadOnly &&
!psOptionsForBinary->bUpdate)
{
if (psOptionsForBinary->osSQLStatement.empty() &&
bMayRetryUpdateMode)
{
// In some cases (empty geopackage for example), opening in
// read-only mode fails, so retry in update mode
poDS = GDALDataset::Open(
psOptionsForBinary->osFilename.c_str(),
GDAL_OF_UPDATE | GDAL_OF_VECTOR,
psOptionsForBinary->aosAllowInputDrivers.List(),
psOptionsForBinary->aosOpenOptions.List(), nullptr);
}
else if (!psOptionsForBinary->osSQLStatement.empty())
{
poDS = GDALDataset::Open(
psOptionsForBinary->osFilename.c_str(),
GDAL_OF_READONLY | GDAL_OF_VECTOR,
psOptionsForBinary->aosAllowInputDrivers.List(),
psOptionsForBinary->aosOpenOptions.List(), nullptr);
if (poDS != nullptr && psOptionsForBinary->bVerbose)
{
printf("Had to open data source read-only.\n");
#ifdef __AFL_HAVE_MANUAL_CONTROL
psOptionsForBinary->bReadOnly = true;
#endif
}
}
}
int nRet = 0;
if (poDS == nullptr)
{
nRet = 1;
VSIStatBuf sStat;
CPLString message;
message.Printf("ogrinfo failed - unable to open '%s'.",
psOptionsForBinary->osFilename.c_str());
if (VSIStat(psOptionsForBinary->osFilename.c_str(), &sStat) == 0)
{
GDALDriverH drv =
GDALIdentifyDriverEx(psOptionsForBinary->osFilename.c_str(),
GDAL_OF_RASTER, nullptr, nullptr);
if (drv)
{
message += " Did you intend to call gdalinfo?";
}
}
fprintf(stderr, "%s\n", message.c_str());
}
else
{
char *pszGDALVectorInfoOutput =
GDALVectorInfo(GDALDataset::ToHandle(poDS), psOptions);
if (pszGDALVectorInfoOutput)
printf("%s", pszGDALVectorInfoOutput);
else
nRet = 1;
CPLFree(pszGDALVectorInfoOutput);
}
delete poDS;
#ifdef __AFL_HAVE_MANUAL_CONTROL
}
#endif
GDALVectorInfoOptionsFree(psOptions);
CSLDestroy(argv);
GDALDumpOpenDatasets(stderr);
GDALDestroyDriverManager();
CPLDumpSharedList(nullptr);
GDALDestroy();
exit(nRet);
}
MAIN_END