Commit c1af5690 authored by Julien Osman's avatar Julien Osman

ENH: Change interface for GetMetadataValue: char* to std::string

parent 9c913556
......@@ -74,68 +74,71 @@ public:
/** Get the metadata value corresponding to a given path (meaning of this path
* depends on the specific implementation. Returns NULL when path is not found
* depends on the specific implementation. Returns empty string when path is not found,
* and hasValue is set to False.
* If band >= 0, the metadata value is looked in the specified band*/
virtual const char * GetMetadataValue(const char * path, int band=-1) const = 0;
virtual const std::string GetMetadataValue(const std::string path, bool& hasValue, int band=-1) const = 0;
bool HasValue(const char * path, int band=-1);
bool HasValue(std::string path, int band=-1);
// utility functions
template <typename T> T GetAs(const char *path, int band=-1) const
template <typename T> T GetAs(std::string path, int band=-1) const
{
bool hasValue;
std::string ret = GetMetadataValue(path, hasValue, band);
if (!hasValue)
{
const char * ret = GetMetadataValue(path, band);
if (ret == nullptr)
{
otbGenericExceptionMacro(MissingMetadataException,<<"Missing metadata '"<<path<<"'")
}
}
try
{
{
return boost::lexical_cast<T>(ret);
}
}
catch (boost::bad_lexical_cast&)
{
{
otbGenericExceptionMacro(MissingMetadataException,<<"Bad metadata value for '"<<path<<"', got: "<<ret)
}
}
}
/** Parse a metadata value to a std::vector,
* If size>=0, then the final std::vector size is checked and an exception
* is raised if it doesn't match the given size.*/
template < typename T> std::vector<T> GetAsVector(const char *path, const char sep=' ', int size=-1, int band=-1) const
template < typename T> std::vector<T> GetAsVector(std::string path, const char sep=' ', int size=-1, int band=-1) const
{
bool hasValue;
std::string ret = GetMetadataValue(path, hasValue, band);
if (!hasValue)
{
const char * ret = GetMetadataValue(path, band);
if (ret == nullptr)
{
otbGenericExceptionMacro(MissingMetadataException,<<"Missing metadata '"<<path<<"'")
}
}
string_view value(ret);
string_view filt_value = rstrip(lstrip(value,"[ "), "] ");
std::vector<T> output;
typedef part_range<splitter_on_delim> range_type;
const range_type parts = split_on(filt_value, sep);
for (auto const& part : parts)
{
{
// TODO: check if we can use lexical_cast on a string_view
std::string strPart = to<std::string>(part, "casting string_view to std::string");
if (strPart.empty())
{
{
continue;
}
}
try
{
{
output.push_back(boost::lexical_cast<T>(strPart));
}
}
catch (boost::bad_lexical_cast&)
{
{
otbGenericExceptionMacro(MissingMetadataException,<<"Bad metadata vector element in '"<<path<<"', got :"<<part)
}
}
}
if ((size >= 0) && (output.size() != (size_t)size))
{
{
otbGenericExceptionMacro(MissingMetadataException,<<"Bad number of elements in vector '"<<path<<"', expected "<<size<< ", got "<<output.size())
}
return output;
}
return output;
}
};
......
......@@ -47,7 +47,7 @@ public:
/** Get the metadata value corresponding to a given path
* Returns NULL when path is not found
* If band >= 0, the metadata value is looked in the specified band*/
const char * GetMetadataValue(const char * path, int band=1) const override;
const std::string GetMetadataValue(const std::string path, bool& hasValue, int band=1) const override;
std::string GetResourceFile(std::string="") const override;
......
......@@ -23,10 +23,11 @@
namespace otb
{
bool MetadataSupplierInterface::HasValue(const char * path, int band)
bool MetadataSupplierInterface::HasValue(const std::string path, int band)
{
const char * ret = GetMetadataValue(path, band);
return ret;
bool hasValue;
const std::string ret = GetMetadataValue(path, hasValue, band);
return hasValue;
}
......
......@@ -41,9 +41,17 @@ XMLMetadataSupplier::XMLMetadataSupplier(const std::string & fileName)
CPLDestroyXMLNode(psNode);
}
const char * XMLMetadataSupplier::GetMetadataValue(const char * path, int band) const
const std::string XMLMetadataSupplier::GetMetadataValue(const std::string path, bool& hasValue, int band) const
{
return CSLFetchNameValue(m_MetadataDic, path);
const char * ret = CSLFetchNameValue(m_MetadataDic, path);
if (ret)
hasValue = true;
else
{
hasValue = false;
ret = "";
}
return std::string(ret);
}
std::string XMLMetadataSupplier::GetResourceFile(std::string) const
......
......@@ -210,7 +210,7 @@ public:
std::vector<std::string> GetResourceFiles() const override;
/** Get metadata item in GDALDataset, domain can specified as "domain/key" */
const char * GetMetadataValue(const char * path, int band = -1) const override;
const std::string GetMetadataValue(const std::string path, bool& hasValue, int band = -1) const override;
/** Set metadata item in GDALDataset, domain can specified as prefix of the
* path, like "domain/key"*/
......
......@@ -1831,24 +1831,31 @@ std::vector<std::string> GDALImageIO::GetResourceFiles() const
return result;
}
const char * GDALImageIO::GetMetadataValue(const char * path, int band) const
const std::string GDALImageIO::GetMetadataValue(const std::string path, bool& hasValue, int band) const
{
// detect namespace if any
const char *slash = strchr(path,'/');
std::string domain("");
const char *domain_c = nullptr;
std::string key(path);
if (slash)
{
domain = std::string(path, (slash-path));
domain_c = domain.c_str();
key = std::string(slash+1);
}
std::size_t found = path.find_first_of("/");
if (found != std::string::npos)
{
domain = path.substr(0, found);
key = path.substr(found + 1);
}
const char* ret;
if (band >= 0)
{
return m_Dataset->GetDataSet()->GetRasterBand(band+1)->GetMetadataItem(key.c_str(), domain_c);
}
return m_Dataset->GetDataSet()->GetMetadataItem(key.c_str(), domain_c);
ret = m_Dataset->GetDataSet()->GetRasterBand(band+1)->GetMetadataItem(key.c_str(), domain.c_str());
else
ret = m_Dataset->GetDataSet()->GetMetadataItem(key.c_str(), domain.c_str());
if (ret)
hasValue = true;
else
{
hasValue = false;
ret = "";
}
return std::string(ret);
}
void GDALImageIO::SetMetadataValue(const char * path, const char * value, int band)
......@@ -1905,7 +1912,8 @@ void GDALImageIO::ImportMetadata()
// Keys Starting with: MDGeomNames[MDGeom::SensorGeometry] + '.' should
// be decoded by the (future) SensorModelFactory.
// Use ImageMetadataBase::FromKeywordlist to ingest the metadata
if (std::string(GetMetadataValue("METADATATYPE")) != "OTB")
bool hasValue;
if (std::string(GetMetadataValue("METADATATYPE", hasValue)) != "OTB")
return;
ImageMetadataBase::Keywordlist kwl;
GDALMetadataToKeywordlist(m_Dataset->GetDataSet()->GetMetadata(), kwl);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment