Merge pull request #2109 from Exiv2/main_StringView
Refactoring & cleanup
This commit is contained in:
commit
c5a9dfd9af
2
.gitignore
vendored
2
.gitignore
vendored
@ -25,3 +25,5 @@ doc/html
|
||||
contrib/vms/.vagrant
|
||||
/.vscode
|
||||
.vs/
|
||||
|
||||
*cppcheck*
|
||||
|
||||
@ -83,7 +83,6 @@ namespace {
|
||||
public:
|
||||
//! C'tor
|
||||
Timestamp() = default;
|
||||
//! Read the timestamp of a file
|
||||
int read(const std::string& path);
|
||||
//! Read the timestamp from a broken-down time in buffer \em tm.
|
||||
int read(struct tm* tm);
|
||||
@ -176,11 +175,6 @@ namespace Action {
|
||||
registry_.clear();
|
||||
}
|
||||
|
||||
void TaskFactory::registerTask(TaskType type, Task::UniquePtr task)
|
||||
{
|
||||
registry_[type] = std::move(task);
|
||||
}
|
||||
|
||||
TaskFactory::TaskFactory()
|
||||
{
|
||||
registry_.emplace(adjust, std::make_unique<Adjust>());
|
||||
@ -268,7 +262,7 @@ namespace Action {
|
||||
|
||||
int Print::printSummary()
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -284,11 +278,8 @@ namespace Action {
|
||||
std::cout << path_ << std::endl;
|
||||
|
||||
// Filesize
|
||||
struct stat buf;
|
||||
if (0 == stat(path_.c_str(), &buf)) {
|
||||
printLabel(_("File size"));
|
||||
std::cout << buf.st_size << " " << _("Bytes") << std::endl;
|
||||
}
|
||||
printLabel(_("File size"));
|
||||
std::cout << fs::file_size(path_) << " " << _("Bytes") << std::endl;
|
||||
|
||||
// MIME type
|
||||
printLabel(_("MIME type"));
|
||||
@ -402,7 +393,7 @@ namespace Action {
|
||||
|
||||
int Print::printList()
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -596,7 +587,6 @@ namespace Action {
|
||||
if (Params::instance().printItems_ & Params::prHex) {
|
||||
if (!first)
|
||||
std::cout << std::endl;
|
||||
first = false;
|
||||
Exiv2::DataBuf buf(md.size());
|
||||
md.copy(buf.data(), pImage->byteOrder());
|
||||
Exiv2::hexdump(std::cout, buf.c_data(), buf.size());
|
||||
@ -607,7 +597,7 @@ namespace Action {
|
||||
|
||||
int Print::printComment()
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -624,7 +614,7 @@ namespace Action {
|
||||
|
||||
int Print::printPreviewList()
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -658,7 +648,7 @@ namespace Action {
|
||||
int Rename::run(const std::string& path)
|
||||
{
|
||||
try {
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -740,7 +730,7 @@ namespace Action {
|
||||
try {
|
||||
path_ = path;
|
||||
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -900,7 +890,7 @@ namespace Action {
|
||||
|
||||
int Extract::writeThumbnail() const
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -947,7 +937,7 @@ namespace Action {
|
||||
|
||||
int Extract::writePreviews() const
|
||||
{
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -983,7 +973,7 @@ namespace Action {
|
||||
int Extract::writeIccProfile(const std::string& target) const
|
||||
{
|
||||
int rc = 0;
|
||||
if (!Exiv2::fileExists(path_, true)) {
|
||||
if (!Exiv2::fileExists(path_)) {
|
||||
std::cerr << path_ << ": " << _("Failed to open the file\n");
|
||||
rc = -1;
|
||||
}
|
||||
@ -1049,7 +1039,7 @@ namespace Action {
|
||||
// -i{tgt}- reading from stdin?
|
||||
bool bStdin = (Params::instance().target_ & Params::ctStdInOut) != 0;
|
||||
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
@ -1106,12 +1096,12 @@ namespace Action {
|
||||
Params::instance().getStdin(xmpBlob);
|
||||
rc = insertXmpPacket(path,xmpBlob,true);
|
||||
} else {
|
||||
if (!Exiv2::fileExists(xmpPath, true)) {
|
||||
if (!Exiv2::fileExists(xmpPath)) {
|
||||
std::cerr << xmpPath
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
rc = -1;
|
||||
}
|
||||
if (rc == 0 && !Exiv2::fileExists(path, true)) {
|
||||
if (rc == 0 && !Exiv2::fileExists(path)) {
|
||||
std::cerr << path
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
rc = -1;
|
||||
@ -1152,7 +1142,7 @@ namespace Action {
|
||||
Params::instance().getStdin(iccProfile);
|
||||
rc = insertIccProfile(path,std::move(iccProfile));
|
||||
} else {
|
||||
if (!Exiv2::fileExists(iccProfilePath, true)) {
|
||||
if (!Exiv2::fileExists(iccProfilePath)) {
|
||||
std::cerr << iccProfilePath
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
rc = -1;
|
||||
@ -1168,7 +1158,7 @@ namespace Action {
|
||||
{
|
||||
int rc = 0;
|
||||
// test path exists
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " << _("Failed to open the file\n");
|
||||
rc=-1;
|
||||
}
|
||||
@ -1192,12 +1182,12 @@ namespace Action {
|
||||
int Insert::insertThumbnail(const std::string& path)
|
||||
{
|
||||
std::string thumbPath = newFilePath(path, "-thumb.jpg");
|
||||
if (!Exiv2::fileExists(thumbPath, true)) {
|
||||
if (!Exiv2::fileExists(thumbPath)) {
|
||||
std::cerr << thumbPath
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path
|
||||
<< ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
@ -1220,7 +1210,7 @@ namespace Action {
|
||||
int Modify::run(const std::string& path)
|
||||
{
|
||||
try {
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1452,7 +1442,7 @@ namespace Action {
|
||||
monthAdjustment_ = Params::instance().yodAdjust_[Params::yodMonth].adjustment_;
|
||||
dayAdjustment_ = Params::instance().yodAdjust_[Params::yodDay].adjustment_;
|
||||
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " << _("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1579,7 +1569,7 @@ namespace Action {
|
||||
int FixIso::run(const std::string& path)
|
||||
{
|
||||
try {
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " <<_("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1632,7 +1622,7 @@ namespace Action {
|
||||
int FixCom::run(const std::string& path)
|
||||
{
|
||||
try {
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": " <<_("Failed to open the file\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1821,7 +1811,7 @@ namespace {
|
||||
|
||||
// read the source metadata
|
||||
int rc = -1 ;
|
||||
if (!Exiv2::fileExists(source, true)) {
|
||||
if (!Exiv2::fileExists(source)) {
|
||||
std::cerr << source << ": " << _("Failed to open the file\n");
|
||||
return rc;
|
||||
}
|
||||
@ -1893,7 +1883,6 @@ namespace {
|
||||
|
||||
// #1148 use Raw XMP packet if there are no XMP modification commands
|
||||
int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
|
||||
// printTarget("in metacopy",Params::instance().target_,true);
|
||||
if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
|
||||
// std::cout << "short cut" << std::endl;
|
||||
// http://www.cplusplus.com/doc/tutorial/files/
|
||||
@ -1946,7 +1935,8 @@ namespace {
|
||||
}
|
||||
|
||||
// delete temporary target
|
||||
if ( bStdout ) std::remove(target.c_str());
|
||||
if ( bStdout )
|
||||
fs::remove(target.c_str());
|
||||
|
||||
return rc;
|
||||
} // metacopy
|
||||
@ -2046,14 +2036,7 @@ namespace {
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// Workaround for MinGW rename which does not overwrite existing files
|
||||
remove(newPath.c_str());
|
||||
if (std::rename(path.c_str(), newPath.c_str()) == -1) {
|
||||
std::cerr << Params::instance().progname() << ": " << _("Failed to rename") << " " << path << " " << _("to")
|
||||
<< " " << newPath << ": " << Exiv2::strError() << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
fs::rename(path, newPath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2096,7 +2079,7 @@ namespace {
|
||||
|
||||
int printStructure(std::ostream& out, Exiv2::PrintStructureOption option, const std::string &path)
|
||||
{
|
||||
if (!Exiv2::fileExists(path, true)) {
|
||||
if (!Exiv2::fileExists(path)) {
|
||||
std::cerr << path << ": "
|
||||
<< _("Failed to open the file\n");
|
||||
return -1;
|
||||
|
||||
@ -123,20 +123,6 @@ namespace Action {
|
||||
*/
|
||||
Task::UniquePtr create(TaskType type);
|
||||
|
||||
/*!
|
||||
@brief Register a task prototype together with its type.
|
||||
|
||||
The task factory creates new tasks of a given type by cloning its
|
||||
associated prototype. Additional tasks can be registered. If called
|
||||
for a type which already exists in the list, the corresponding
|
||||
prototype is replaced.
|
||||
|
||||
@param type Task type.
|
||||
@param task Pointer to the prototype. Ownership is transferred to the
|
||||
task factory. That's what the auto pointer indicates.
|
||||
*/
|
||||
void registerTask(TaskType type, Task::UniquePtr task);
|
||||
|
||||
private:
|
||||
//! Prevent construction other than through instance().
|
||||
TaskFactory();
|
||||
|
||||
@ -160,7 +160,6 @@ int main(int argc, char* const argv[])
|
||||
assert(task);
|
||||
|
||||
// Process all files
|
||||
int n = 1;
|
||||
int s = static_cast<int>(params.files_.size());
|
||||
if (params.action_ & Action::extract && params.target_ & Params::ctStdInOut && s > 1) {
|
||||
std::cerr << params.progname() << ": " << _("Only one file is allowed when extracting to stdout") << std::endl;
|
||||
@ -168,6 +167,7 @@ int main(int argc, char* const argv[])
|
||||
}
|
||||
else {
|
||||
int w = s > 9 ? s > 99 ? 3 : 2 : 1;
|
||||
int n = 1;
|
||||
for (auto&& file : params.files_) {
|
||||
// If extracting to stdout then ignore verbose
|
||||
if (params.verbose_ && !(params.action_ & Action::extract && params.target_ & Params::ctStdInOut)) {
|
||||
@ -248,25 +248,6 @@ void Params::usage(std::ostream& os) const
|
||||
<< _("Image metadata manipulation tool.\n");
|
||||
}
|
||||
|
||||
std::string Params::printTarget(const std::string &before, int target, bool bPrint, std::ostream& out)
|
||||
{
|
||||
std::string t;
|
||||
if ( target & Params::ctExif ) t+= 'e';
|
||||
if ( target & Params::ctXmpSidecar ) t+= 'X';
|
||||
if ( target & Params::ctXmpRaw ) t+= target & Params::ctXmpSidecar ? 'X' : 'R' ;
|
||||
if ( target & Params::ctIptc ) t+= 'i';
|
||||
if ( target & Params::ctIccProfile ) t+= 'C';
|
||||
if ( target & Params::ctIptcRaw ) t+= 'I';
|
||||
if ( target & Params::ctXmp ) t+= 'x';
|
||||
if ( target & Params::ctComment ) t+= 'c';
|
||||
if ( target & Params::ctThumb ) t+= 't';
|
||||
if ( target & Params::ctPreview ) t+= 'p';
|
||||
if ( target & Params::ctStdInOut ) t+= '-';
|
||||
|
||||
if ( bPrint ) out << before << " :" << t << std::endl;
|
||||
return t;
|
||||
}
|
||||
|
||||
void Params::help(std::ostream& os) const
|
||||
{
|
||||
usage(os);
|
||||
|
||||
@ -339,10 +339,6 @@ public:
|
||||
//! Print version information to an output stream.
|
||||
static void version(bool verbose = false, std::ostream& os = std::cout);
|
||||
|
||||
//! Print target_
|
||||
static std::string printTarget(const std::string& before, int target, bool bPrint = false,
|
||||
std::ostream& out = std::cout);
|
||||
|
||||
//! getStdin binary data read from stdin to DataBuf
|
||||
/*
|
||||
stdin can be used by multiple images in the exiv2 command line:
|
||||
|
||||
@ -240,7 +240,7 @@ namespace Exiv2 {
|
||||
comprehensive error messages where only a BasicIo instance is
|
||||
available.
|
||||
*/
|
||||
virtual std::string path() const =0;
|
||||
virtual const std::string& path() const noexcept =0;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -472,7 +472,7 @@ namespace Exiv2 {
|
||||
//! Returns true if the file position has reached the end, otherwise false.
|
||||
bool eof() const override;
|
||||
//! Returns the path of the file
|
||||
std::string path() const override;
|
||||
const std::string& path() const noexcept override;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -654,7 +654,7 @@ namespace Exiv2 {
|
||||
//!Returns true if the IO position has reached the end, otherwise false.
|
||||
bool eof() const override;
|
||||
//! Returns a dummy path, indicating that memory access is used
|
||||
std::string path() const override;
|
||||
const std::string& path() const noexcept override;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -898,7 +898,7 @@ namespace Exiv2 {
|
||||
//!Returns true if the IO position has reached the end, otherwise false.
|
||||
bool eof() const override;
|
||||
//!Returns the URL of the file.
|
||||
std::string path() const override;
|
||||
const std::string& path() const noexcept override;
|
||||
|
||||
/*!
|
||||
@brief Mark all the bNone blocks to bKnow. This avoids allocating memory
|
||||
@ -1008,12 +1008,6 @@ namespace Exiv2 {
|
||||
@throw Error In case of failure.
|
||||
*/
|
||||
EXIV2API long writeFile(const DataBuf& buf, const std::string& path);
|
||||
/*!
|
||||
@brief replace each substring of the subject that matches the given search string with the given replacement.
|
||||
@return the subject after replacing.
|
||||
*/
|
||||
EXIV2API std::string ReplaceStringInPlace(std::string subject, const std::string& search,
|
||||
const std::string& replace);
|
||||
#ifdef EXV_USE_CURL
|
||||
/*!
|
||||
@brief The callback function is called by libcurl to write the data
|
||||
|
||||
@ -25,7 +25,8 @@
|
||||
|
||||
// included header files
|
||||
#include "image.hpp"
|
||||
#include "iostream"
|
||||
|
||||
#include <set>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
@ -127,7 +128,7 @@ namespace Exiv2
|
||||
//@{
|
||||
void readMetadata() override /* override */;
|
||||
void writeMetadata() override /* override */;
|
||||
void setComment(const std::string& comment) override /* override */;
|
||||
void setComment(std::string_view comment) override /* override */;
|
||||
void printStructure(std::ostream& out, Exiv2::PrintStructureOption option, int depth) override;
|
||||
//@}
|
||||
|
||||
|
||||
@ -85,7 +85,7 @@ namespace Exiv2 {
|
||||
void setIptcData(const IptcData& iptcData) override;
|
||||
|
||||
/// @throws Error(kerInvalidSettingForImage)
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -6,29 +6,8 @@
|
||||
///// Start of Visual Studio Support /////
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define _MSC_VER_2010 1600
|
||||
#define _MSC_VER_2008 1500
|
||||
|
||||
// Constants required by Microsoft SDKs to define SHGetFolderPathA and others
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
// Visual Studio 2012 and earlier
|
||||
# if _MSC_VER < 1800
|
||||
# define _WIN32_WINNT 0x0501
|
||||
# else
|
||||
# define _WIN32_WINNT 0x0600
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if _MSC_VER >= _MSC_VER_2008
|
||||
#pragma warning(disable : 4996) // Disable warnings about 'deprecated' standard functions
|
||||
#pragma warning(disable : 4251) // Disable warnings from std templates about exporting interfaces
|
||||
#endif
|
||||
|
||||
/* On Microsoft compilers pid_t has to be set to int. */
|
||||
#ifndef HAVE_PID_T
|
||||
typedef int pid_t;
|
||||
#endif
|
||||
|
||||
#endif // _MSC_VER
|
||||
///// End of Visual Studio Support /////
|
||||
@ -93,16 +72,4 @@ typedef int pid_t;
|
||||
#endif
|
||||
//////////////////////////////////////
|
||||
|
||||
|
||||
// https://softwareengineering.stackexchange.com/questions/291141/how-to-handle-design-changes-for-auto-ptr-deprecation-in-c11
|
||||
#if __cplusplus >= 201103L
|
||||
#include <memory>
|
||||
#include <sys/types.h>
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
template <typename T>
|
||||
using auto_ptr = std::unique_ptr<T>;
|
||||
#endif
|
||||
|
||||
#endif // _CONFIG_H_
|
||||
|
||||
@ -81,7 +81,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. CR2 format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -32,11 +32,6 @@
|
||||
// included header files
|
||||
#include "metadatum.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Exiv2
|
||||
@brief Not supported.
|
||||
Calling this function will throw an instance of Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -34,10 +34,6 @@
|
||||
// included header files
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <exception>
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -63,18 +63,7 @@ namespace Exiv2
|
||||
@note Source: http://www.geekhideout.com/urlcode.shtml
|
||||
@todo This function can probably be hidden into the implementation details
|
||||
*/
|
||||
EXIV2API std::string urlencode(const char* str);
|
||||
|
||||
/*!
|
||||
@brief Decode the input url.
|
||||
@param str The url needs decoding.
|
||||
@return the url-decoded version of str.
|
||||
|
||||
@note Be sure to 'free' the returned string after use with 'delete []'.
|
||||
Source: http://www.geekhideout.com/urlcode.shtml
|
||||
@todo This function can probably be hidden into the implementation details
|
||||
*/
|
||||
EXIV2API char* urldecode(const char* str);
|
||||
EXIV2API std::string urlencode(std::string_view str);
|
||||
|
||||
/*!
|
||||
@brief Like urlencode(char* str) but accept the input url in the std::string and modify it.
|
||||
@ -125,15 +114,7 @@ namespace Exiv2
|
||||
and its type, see stat(2). <b>errno</b> is left unchanged
|
||||
in case of an error.
|
||||
*/
|
||||
EXIV2API bool fileExists(const std::string& path, bool ct = false);
|
||||
|
||||
/*!
|
||||
@brief Get the path of file URL.
|
||||
|
||||
@param url The file URL in the format file:///path or file://host/path
|
||||
@return the path of file URL.
|
||||
*/
|
||||
EXIV2API std::string pathOfFileUrl(const std::string& url);
|
||||
EXIV2API bool fileExists(const std::string& path);
|
||||
|
||||
/*!
|
||||
@brief Return a system error message and the error code (errno).
|
||||
|
||||
@ -86,7 +86,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. Calling this function will throw an instance
|
||||
of Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -25,8 +25,6 @@
|
||||
|
||||
#include "datasets.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
||||
namespace Exiv2 {
|
||||
/*!
|
||||
|
||||
@ -30,10 +30,6 @@
|
||||
#include "image_types.hpp"
|
||||
#include "xmp_exiv2.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
@ -199,12 +195,10 @@ namespace Exiv2 {
|
||||
writeXmpFromPacket(true) or setXmpPacket().
|
||||
*/
|
||||
virtual void clearXmpData();
|
||||
/*!
|
||||
@brief Set the image comment. The new comment is not written
|
||||
to the image until the writeMetadata() method is called.
|
||||
@param comment String containing comment.
|
||||
*/
|
||||
virtual void setComment(const std::string& comment);
|
||||
|
||||
/// @brief Set the image comment. The comment is written to the image when writeMetadata() is called.
|
||||
virtual void setComment(std::string_view comment);
|
||||
|
||||
/*!
|
||||
@brief Erase any buffered comment. Comment is not removed
|
||||
from the actual image until the writeMetadata() method is called.
|
||||
|
||||
@ -32,7 +32,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
namespace Exiv2 {
|
||||
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Exiv2
|
||||
@brief Todo: Not supported yet(?). Calling this function will throw
|
||||
an instance of Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -89,7 +89,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. MRW format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -76,7 +76,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. ORF format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -70,7 +70,7 @@ namespace Exiv2 {
|
||||
/*!
|
||||
@brief Not supported. Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -25,11 +25,6 @@
|
||||
|
||||
// included header files
|
||||
#include "image.hpp"
|
||||
#include "basicio.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
@ -87,7 +82,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. RAF format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -80,7 +80,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. RW2 format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -26,11 +26,6 @@
|
||||
// included header files
|
||||
#include "metadatum.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -86,7 +86,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. Calling this function will throw an instance
|
||||
of Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -77,7 +77,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. TIFF format does not contain a comment.
|
||||
Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -27,13 +27,11 @@
|
||||
#include "slice.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <cstdint>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
/*!
|
||||
@brief Macro to make calls to member functions through a pointer more readable.
|
||||
@ -42,12 +40,6 @@
|
||||
*/
|
||||
#define EXV_CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define EXV_UNUSED [[gnu::unused]]
|
||||
#else
|
||||
#define EXV_UNUSED
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// forward declarations
|
||||
struct tm;
|
||||
@ -576,11 +568,6 @@ namespace Exiv2 {
|
||||
// This is abs() - given the existence of broken compilers with Koenig
|
||||
// lookup issues and other problems, I code this explicitly. (Remember,
|
||||
// IntType may be a user-defined type).
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable : 4146 )
|
||||
#undef max
|
||||
#undef min
|
||||
#endif
|
||||
if (n < zero) {
|
||||
if (n == std::numeric_limits<IntType>::min()) {
|
||||
n = std::numeric_limits<IntType>::max();
|
||||
@ -590,9 +577,6 @@ namespace Exiv2 {
|
||||
}
|
||||
if (m < zero)
|
||||
m = -m;
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( default : 4146 )
|
||||
#endif
|
||||
|
||||
// As n and m are now positive, we can be sure that %= returns a
|
||||
// positive value (the standard guarantees this for built-in types,
|
||||
|
||||
@ -27,11 +27,9 @@
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <climits>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
@ -65,7 +65,7 @@ namespace Exiv2 {
|
||||
/*!
|
||||
@brief Not supported. Calling this function will throw an Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
void setIptcData(const IptcData& /*iptcData*/) override;
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -64,7 +64,7 @@ namespace Exiv2 {
|
||||
@brief Not supported. XMP sidecar files do not contain a comment.
|
||||
Calling this function will throw an instance of Error(kerInvalidSettingForImage).
|
||||
*/
|
||||
void setComment(const std::string& comment) override;
|
||||
void setComment(std::string_view comment) override;
|
||||
//@}
|
||||
|
||||
//! @name Accessors
|
||||
|
||||
@ -36,6 +36,7 @@ add_library( exiv2lib_int OBJECT
|
||||
tifffwd_int.hpp
|
||||
timegm.h
|
||||
unused.h
|
||||
utils.hpp utils.cpp
|
||||
)
|
||||
|
||||
set(PUBLIC_HEADERS
|
||||
|
||||
261
src/basicio.cpp
261
src/basicio.cpp
@ -34,18 +34,22 @@
|
||||
#include "image_int.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <cstring> // std::memcpy
|
||||
#include <fcntl.h> // _O_BINARY in FileIo::FileIo
|
||||
#include <sys/stat.h> // for stat, chmod
|
||||
#include <sys/types.h> // for stat, chmod
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream> // write the temporary file
|
||||
#include <fcntl.h> // _O_BINARY in FileIo::FileIo
|
||||
#include <cstdio> // for remove, rename
|
||||
#include <cstdlib> // for alloc, realloc, free
|
||||
#include <ctime> // timestamp for the name of temporary file
|
||||
#include <sys/types.h> // for stat, chmod
|
||||
#include <sys/stat.h> // for stat, chmod
|
||||
#include <cstdio> // for remove, rename
|
||||
#include <cstdlib> // for alloc, realloc, free
|
||||
#include <cstring> // std::memcpy
|
||||
#include <ctime> // timestamp for the name of temporary file
|
||||
#include <filesystem>
|
||||
#include <fstream> // write the temporary file
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
#ifdef EXV_HAVE_SYS_MMAN_H
|
||||
# include <sys/mman.h> // for mmap and munmap
|
||||
@ -63,20 +67,25 @@
|
||||
|
||||
#define mode_t unsigned short
|
||||
|
||||
// Platform specific headers for handling extended attributes (xattr)
|
||||
#if defined(__APPLE__)
|
||||
# include <sys/xattr.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW__) || (defined(WIN32) && !defined(__CYGWIN__))
|
||||
// Windows doesn't provide nlink_t
|
||||
using nlink_t = short;
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace {
|
||||
/// @brief replace each substring of the subject that matches the given search string with the given replacement.
|
||||
void ReplaceStringInPlace(std::string& subject, const std::string& search, const std::string& replace)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = subject.find(search, pos)) != std::string::npos) {
|
||||
subject.replace(pos, search.length(), replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Exiv2 {
|
||||
void BasicIo::readOrThrow(byte* buf, long rcount, ErrorCode err) {
|
||||
const long nread = read(buf, rcount);
|
||||
@ -117,7 +126,6 @@ namespace Exiv2 {
|
||||
StructStat() = default;
|
||||
mode_t st_mode{0}; //!< Permissions
|
||||
off_t st_size{0}; //!< Size
|
||||
nlink_t st_nlink{0}; //!< Number of hard links (broken on Windows, see winNumberOfLinks())
|
||||
};
|
||||
// #endif
|
||||
// METHODS
|
||||
@ -130,12 +138,6 @@ namespace Exiv2 {
|
||||
int switchMode(OpMode opMode);
|
||||
//! stat wrapper for internal use
|
||||
int stat(StructStat& buf) const;
|
||||
//! copy extended attributes (xattr) from another file
|
||||
void copyXattrFrom(const FileIo& src);
|
||||
#if defined WIN32 && !defined __CYGWIN__
|
||||
// Windows function to determine the number of hardlinks (on NTFS)
|
||||
DWORD winNumberOfLinks() const;
|
||||
#endif
|
||||
// NOT IMPLEMENTED
|
||||
Impl(const Impl& rhs) = delete; //!< Copy constructor
|
||||
Impl& operator=(const Impl& rhs) = delete; //!< Assignment
|
||||
@ -211,96 +213,11 @@ namespace Exiv2 {
|
||||
ret = ::stat(path_.c_str(), &st);
|
||||
if (0 == ret) {
|
||||
buf.st_size = st.st_size;
|
||||
buf.st_nlink = st.st_nlink;
|
||||
buf.st_mode = st.st_mode;
|
||||
}
|
||||
return ret;
|
||||
} // FileIo::Impl::stat
|
||||
|
||||
#if defined(__APPLE__)
|
||||
void FileIo::Impl::copyXattrFrom(const FileIo& src)
|
||||
#else
|
||||
void FileIo::Impl::copyXattrFrom(const FileIo&)
|
||||
#endif
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
ssize_t namebufSize = ::listxattr(src.p_->path_.c_str(), 0, 0, 0);
|
||||
if (namebufSize < 0) {
|
||||
throw Error(kerCallFailed, src.p_->path_, strError(), "listxattr");
|
||||
}
|
||||
if (namebufSize == 0) {
|
||||
// No extended attributes in source file
|
||||
return;
|
||||
}
|
||||
char* namebuf = new char[namebufSize];
|
||||
if (::listxattr(src.p_->path_.c_str(), namebuf, namebufSize, 0) != namebufSize) {
|
||||
throw Error(kerCallFailed, src.p_->path_, strError(), "listxattr");
|
||||
}
|
||||
for (ssize_t namebufPos = 0; namebufPos < namebufSize;) {
|
||||
const char *name = namebuf + namebufPos;
|
||||
namebufPos += strlen(name) + 1;
|
||||
const ssize_t valueSize = ::getxattr(src.p_->path_.c_str(), name, 0, 0, 0, 0);
|
||||
if (valueSize < 0) {
|
||||
throw Error(kerCallFailed, src.p_->path_, strError(), "getxattr");
|
||||
}
|
||||
char* value = new char[valueSize];
|
||||
if (::getxattr(src.p_->path_.c_str(), name, value, valueSize, 0, 0) != valueSize) {
|
||||
throw Error(kerCallFailed, src.p_->path_, strError(), "getxattr");
|
||||
}
|
||||
// #906. Mountain Lion 'sandbox' terminates the app when we call setxattr
|
||||
#ifndef __APPLE__
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
EXV_DEBUG << "Copying xattr \"" << name << "\" with value size " << valueSize << "\n";
|
||||
#endif
|
||||
if (::setxattr(path_.c_str(), name, value, valueSize, 0, 0) != 0) {
|
||||
throw Error(kerCallFailed, path_, strError(), "setxattr");
|
||||
}
|
||||
delete [] value;
|
||||
#endif
|
||||
}
|
||||
delete [] namebuf;
|
||||
#else
|
||||
// No xattr support for this platform.
|
||||
#endif
|
||||
} // FileIo::Impl::copyXattrFrom
|
||||
|
||||
#if defined WIN32 && !defined __CYGWIN__
|
||||
DWORD FileIo::Impl::winNumberOfLinks() const
|
||||
{
|
||||
DWORD nlink = 1;
|
||||
|
||||
HANDLE hFd = (HANDLE)_get_osfhandle(fileno(fp_));
|
||||
if (hFd != INVALID_HANDLE_VALUE) {
|
||||
using GetFileInformationByHandle_t = BOOL(WINAPI*)(HANDLE, LPBY_HANDLE_FILE_INFORMATION);
|
||||
HMODULE hKernel = ::GetModuleHandleA("kernel32.dll");
|
||||
if (hKernel) {
|
||||
GetFileInformationByHandle_t pfcn_GetFileInformationByHandle = (GetFileInformationByHandle_t)GetProcAddress(hKernel, "GetFileInformationByHandle");
|
||||
if (pfcn_GetFileInformationByHandle) {
|
||||
BY_HANDLE_FILE_INFORMATION fi = {0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
if (pfcn_GetFileInformationByHandle(hFd, &fi)) {
|
||||
nlink = fi.nNumberOfLinks;
|
||||
}
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
else EXV_DEBUG << "GetFileInformationByHandle failed\n";
|
||||
#endif
|
||||
}
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
else EXV_DEBUG << "GetProcAddress(hKernel, \"GetFileInformationByHandle\") failed\n";
|
||||
#endif
|
||||
}
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
else EXV_DEBUG << "GetModuleHandleA(\"kernel32.dll\") failed\n";
|
||||
#endif
|
||||
}
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
else EXV_DEBUG << "_get_osfhandle failed: INVALID_HANDLE_VALUE\n";
|
||||
#endif
|
||||
|
||||
return nlink;
|
||||
} // FileIo::Impl::winNumberOfLinks
|
||||
|
||||
#endif // defined WIN32 && !defined __CYGWIN__
|
||||
|
||||
FileIo::FileIo(const std::string& path)
|
||||
: p_(new Impl(path))
|
||||
{
|
||||
@ -435,10 +352,10 @@ namespace Exiv2 {
|
||||
|
||||
byte buf[4096];
|
||||
long readCount = 0;
|
||||
long writeCount = 0;
|
||||
long writeTotal = 0;
|
||||
while ((readCount = src.read(buf, sizeof(buf)))) {
|
||||
writeTotal += writeCount = static_cast<long>(std::fwrite(buf, 1, readCount, p_->fp_));
|
||||
long writeCount = static_cast<long>(std::fwrite(buf, 1, readCount, p_->fp_));
|
||||
writeTotal += writeCount;
|
||||
if (writeCount != readCount) {
|
||||
// try to reset back to where write stopped
|
||||
src.seek(writeCount-readCount, BasicIo::cur);
|
||||
@ -460,56 +377,21 @@ namespace Exiv2 {
|
||||
fileIo->close();
|
||||
// Check if the file can be written to, if it already exists
|
||||
if (open("a+b") != 0) {
|
||||
/// \todo Use std::filesystem once C++17 can be used
|
||||
// Remove the (temporary) file
|
||||
::remove(fileIo->path().c_str());
|
||||
fs::remove(fileIo->path().c_str());
|
||||
throw Error(kerFileOpenFailed, path(), "a+b", strError());
|
||||
}
|
||||
close();
|
||||
|
||||
bool statOk = true;
|
||||
mode_t origStMode = 0;
|
||||
std::string spf;
|
||||
char* pf = nullptr;
|
||||
spf = path();
|
||||
pf = const_cast<char*>(spf.c_str());
|
||||
auto pf = path().c_str();
|
||||
|
||||
// Get the permissions of the file, or linked-to file, on platforms which have lstat
|
||||
#ifdef EXV_HAVE_LSTAT
|
||||
|
||||
struct stat buf1;
|
||||
if (::lstat(pf, &buf1) == -1) {
|
||||
statOk = false;
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
EXV_WARNING << Error(kerCallFailed, pf, strError(), "::lstat") << "\n";
|
||||
#endif
|
||||
}
|
||||
origStMode = buf1.st_mode;
|
||||
DataBuf lbuf; // So that the allocated memory is freed. Must have same scope as pf
|
||||
// In case path() is a symlink, get the path of the linked-to file
|
||||
if (statOk && S_ISLNK(buf1.st_mode)) {
|
||||
lbuf.alloc(buf1.st_size + 1);
|
||||
lbuf.clear();
|
||||
pf = reinterpret_cast<char*>(lbuf.data());
|
||||
if (::readlink(path().c_str(), pf, lbuf.size() - 1) == -1) {
|
||||
throw Error(kerCallFailed, path(), strError(), "readlink");
|
||||
}
|
||||
// We need the permissions of the file, not the symlink
|
||||
if (::stat(pf, &buf1) == -1) {
|
||||
statOk = false;
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
EXV_WARNING << Error(kerCallFailed, pf, strError(), "::stat") << "\n";
|
||||
#endif
|
||||
}
|
||||
origStMode = buf1.st_mode;
|
||||
}
|
||||
#else // EXV_HAVE_LSTAT
|
||||
Impl::StructStat buf1;
|
||||
if (p_->stat(buf1) == -1) {
|
||||
statOk = false;
|
||||
}
|
||||
origStMode = buf1.st_mode;
|
||||
#endif // !EXV_HAVE_LSTAT
|
||||
|
||||
{
|
||||
#if defined(WIN32) && defined(REPLACEFILE_IGNORE_MERGE_ERRORS)
|
||||
@ -526,10 +408,8 @@ namespace Exiv2 {
|
||||
BOOL ret = pfcn_ReplaceFileA(pf, fileIo->path().c_str(), NULL, REPLACEFILE_IGNORE_MERGE_ERRORS, NULL, NULL);
|
||||
if (ret == 0) {
|
||||
if (GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||
if (::rename(fileIo->path().c_str(), pf) == -1) {
|
||||
throw Error(kerFileRenameFailed, fileIo->path(), pf, strError());
|
||||
}
|
||||
::remove(fileIo->path().c_str());
|
||||
fs::rename(fileIo->path().c_str(), pf);
|
||||
fs::remove(fileIo->path().c_str());
|
||||
}
|
||||
else {
|
||||
throw Error(kerFileRenameFailed, fileIo->path(), pf, strError());
|
||||
@ -538,22 +418,18 @@ namespace Exiv2 {
|
||||
}
|
||||
else {
|
||||
if (fileExists(pf) && ::remove(pf) != 0) {
|
||||
throw Error(kerCallFailed, pf, strError(), "::remove");
|
||||
throw Error(kerCallFailed, pf, strError(), "fs::remove");
|
||||
}
|
||||
if (::rename(fileIo->path().c_str(), pf) == -1) {
|
||||
throw Error(kerFileRenameFailed, fileIo->path(), pf, strError());
|
||||
}
|
||||
::remove(fileIo->path().c_str());
|
||||
fs::rename(fileIo->path().c_str(), pf);
|
||||
fs::remove(fileIo->path().c_str());
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (fileExists(pf) && ::remove(pf) != 0) {
|
||||
throw Error(kerCallFailed, pf, strError(), "::remove");
|
||||
if (fileExists(pf) && fs::remove(pf) != 0) {
|
||||
throw Error(kerCallFailed, pf, strError(), "fs::remove");
|
||||
}
|
||||
if (::rename(fileIo->path().c_str(), pf) == -1) {
|
||||
throw Error(kerFileRenameFailed, fileIo->path(), pf, strError());
|
||||
}
|
||||
::remove(fileIo->path().c_str());
|
||||
fs::rename(fileIo->path().c_str(), pf);
|
||||
fs::remove(fileIo->path().c_str());
|
||||
#endif
|
||||
// Check permissions of new file
|
||||
struct stat buf2;
|
||||
@ -720,7 +596,7 @@ namespace Exiv2 {
|
||||
return std::feof(p_->fp_) != 0;
|
||||
}
|
||||
|
||||
std::string FileIo::path() const
|
||||
const std::string& FileIo::path() const noexcept
|
||||
{
|
||||
return p_->path_;
|
||||
}
|
||||
@ -802,18 +678,17 @@ namespace Exiv2 {
|
||||
{
|
||||
return type_ == bNone;
|
||||
}
|
||||
bool isInMem () const
|
||||
{
|
||||
return type_ == bMemory;
|
||||
}
|
||||
|
||||
bool isKnown () const
|
||||
{
|
||||
return type_ == bKnown;
|
||||
}
|
||||
|
||||
byte* getData () const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
size_t getSize () const
|
||||
{
|
||||
return size_;
|
||||
@ -1044,9 +919,10 @@ namespace Exiv2 {
|
||||
return p_->eof_;
|
||||
}
|
||||
|
||||
std::string MemIo::path() const
|
||||
const std::string& MemIo::path() const noexcept
|
||||
{
|
||||
return "MemIo";
|
||||
static std::string _path{"MemIo"};
|
||||
return _path;
|
||||
}
|
||||
|
||||
void MemIo::populateFakeData() {
|
||||
@ -1107,7 +983,7 @@ namespace Exiv2 {
|
||||
}
|
||||
|
||||
XPathIo::~XPathIo() {
|
||||
if (isTemp_ && remove(tempFilePath_.c_str()) != 0) {
|
||||
if (isTemp_ && !fs::remove(tempFilePath_)) {
|
||||
// error when removing file
|
||||
// printf ("Warning: Unable to remove the temp file %s.\n", tempFilePath_.c_str());
|
||||
}
|
||||
@ -1116,13 +992,12 @@ namespace Exiv2 {
|
||||
void XPathIo::transfer(BasicIo& src) {
|
||||
if (isTemp_) {
|
||||
// replace temp path to gent path.
|
||||
std::string currentPath = path();
|
||||
setPath(ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT));
|
||||
// rename the file
|
||||
auto currentPath = path();
|
||||
ReplaceStringInPlace(currentPath, XPathIo::TEMP_FILE_EXT, XPathIo::GEN_FILE_EXT);
|
||||
setPath(currentPath);
|
||||
|
||||
tempFilePath_ = path();
|
||||
if (rename(currentPath.c_str(), tempFilePath_.c_str()) != 0) {
|
||||
// printf("Warning: Failed to rename the temp file. \n");
|
||||
}
|
||||
fs::rename(currentPath, tempFilePath_);
|
||||
isTemp_ = false;
|
||||
// call super class method
|
||||
FileIo::transfer(src);
|
||||
@ -1371,21 +1246,18 @@ namespace Exiv2 {
|
||||
size_t left = 0;
|
||||
size_t right = 0;
|
||||
size_t blockIndex = 0;
|
||||
size_t i = 0;
|
||||
size_t readCount = 0;
|
||||
size_t blockSize = 0;
|
||||
auto buf = new byte [p_->blockSize_];
|
||||
std::vector<byte> buf(p_->blockSize_);
|
||||
size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_;
|
||||
|
||||
// find $left
|
||||
src.seek(0, BasicIo::beg);
|
||||
bool findDiff = false;
|
||||
while (blockIndex < nBlocks && !src.eof() && !findDiff) {
|
||||
blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
size_t blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
|
||||
readCount = static_cast<size_t>(src.read(buf, static_cast<long>(blockSize)));
|
||||
size_t readCount = static_cast<size_t>(src.read(buf.data(), static_cast<long>(blockSize)));
|
||||
byte* blockData = p_->blocksMap_[blockIndex].getData();
|
||||
for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
|
||||
for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
|
||||
if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) {
|
||||
findDiff = true;
|
||||
} else {
|
||||
@ -1400,14 +1272,14 @@ namespace Exiv2 {
|
||||
blockIndex = nBlocks;
|
||||
while (blockIndex > 0 && right < src.size() && !findDiff) {
|
||||
blockIndex--;
|
||||
blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
size_t blockSize = p_->blocksMap_[blockIndex].getSize();
|
||||
if(src.seek(-1 * (blockSize + right), BasicIo::end)) {
|
||||
findDiff = true;
|
||||
} else {
|
||||
bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
|
||||
readCount = src.read(buf, static_cast<long>(blockSize));
|
||||
size_t readCount = src.read(buf.data(), static_cast<long>(blockSize));
|
||||
byte* blockData = p_->blocksMap_[blockIndex].getData();
|
||||
for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
|
||||
for (size_t i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
|
||||
if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) {
|
||||
findDiff = true;
|
||||
} else {
|
||||
@ -1417,8 +1289,6 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
|
||||
delete []buf;
|
||||
|
||||
// submit to the remote machine.
|
||||
long dataSize = static_cast<long>(src.size() - left - right);
|
||||
if (dataSize > 0) {
|
||||
@ -1585,7 +1455,7 @@ namespace Exiv2 {
|
||||
return p_->eof_;
|
||||
}
|
||||
|
||||
std::string RemoteIo::path() const
|
||||
const std::string& RemoteIo::path() const noexcept
|
||||
{
|
||||
return p_->path_;
|
||||
}
|
||||
@ -1989,15 +1859,6 @@ namespace Exiv2 {
|
||||
return file.write(buf.c_data(), buf.size());
|
||||
}
|
||||
|
||||
std::string ReplaceStringInPlace(std::string subject, const std::string& search,
|
||||
const std::string& replace) {
|
||||
size_t pos = 0;
|
||||
while((pos = subject.find(search, pos)) != std::string::npos) {
|
||||
subject.replace(pos, search.length(), replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
return subject;
|
||||
}
|
||||
|
||||
#ifdef EXV_USE_CURL
|
||||
size_t curlWriter(char* data, size_t size, size_t nmemb,
|
||||
|
||||
@ -627,11 +627,11 @@ namespace Exiv2
|
||||
}
|
||||
}
|
||||
|
||||
void BmffImage::setComment(const std::string& /*comment*/)
|
||||
void BmffImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// bmff files are read-only
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "BMFF"));
|
||||
} // BmffImage::setComment
|
||||
}
|
||||
|
||||
void BmffImage::openOrThrow()
|
||||
{
|
||||
|
||||
@ -61,7 +61,7 @@ namespace Exiv2
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "BMP"));
|
||||
}
|
||||
|
||||
void BmpImage::setComment(const std::string& /*comment*/)
|
||||
void BmpImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "BMP"));
|
||||
}
|
||||
|
||||
@ -437,7 +437,7 @@ namespace Exiv2 {
|
||||
|
||||
|
||||
// Categories, tag 0x0023
|
||||
EXV_UNUSED constexpr TagDetails canonCategories[] = {
|
||||
[[maybe_unused]] constexpr TagDetails canonCategories[] = {
|
||||
{ 0x0001, N_("People") },
|
||||
{ 0x0002, N_("Scenery") },
|
||||
{ 0x0004, N_("Events") },
|
||||
@ -2110,7 +2110,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
//! ManualFlashOutput, tag 0x0029
|
||||
EXV_UNUSED constexpr TagDetails canonCsManualFlashOutput[] = {
|
||||
[[maybe_unused]] constexpr TagDetails canonCsManualFlashOutput[] = {
|
||||
{ 0x0000, N_("n/a") },
|
||||
{ 0x0500, N_("Full") },
|
||||
{ 0x0502, N_("Medium") },
|
||||
|
||||
@ -37,11 +37,6 @@
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -33,10 +33,6 @@
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -37,13 +37,14 @@
|
||||
#include "unused.h"
|
||||
|
||||
// + standard includes
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <stdio.h> // for snprintf (C99)
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdio.h> // for snprintf (C99)
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#if defined WIN32 && !defined __CYGWIN__
|
||||
# include <windows.h>
|
||||
@ -284,8 +285,6 @@ namespace Exiv2 {
|
||||
//@{
|
||||
//! Get the value of the erase flag, see also setErase(bool on).
|
||||
bool erase() const { return erase_; }
|
||||
//! Get the value of the overwrite flag, see also setOverwrite(bool on).
|
||||
bool overwrite() const { return overwrite_; }
|
||||
//@}
|
||||
|
||||
private:
|
||||
@ -293,7 +292,6 @@ namespace Exiv2 {
|
||||
bool prepareIptcTarget(const char* to, bool force =false);
|
||||
bool prepareXmpTarget(const char* to, bool force =false);
|
||||
std::string computeExifDigest(bool tiff);
|
||||
std::string computeIptcDigest();
|
||||
|
||||
// DATA
|
||||
static const Conversion conversion_[]; //<! Conversion rules
|
||||
@ -1084,7 +1082,6 @@ namespace Exiv2 {
|
||||
else {
|
||||
sec = (min - static_cast<int>(min)) * 60.0;
|
||||
min = static_cast<double>(static_cast<int>(min));
|
||||
sep2 = ',';
|
||||
}
|
||||
|
||||
if ( in.bad() || !(ref == 'N' || ref == 'S' || ref == 'E' || ref == 'W')
|
||||
@ -1256,28 +1253,6 @@ namespace Exiv2 {
|
||||
writeExifDigest();
|
||||
}
|
||||
|
||||
std::string Converter::computeIptcDigest()
|
||||
{
|
||||
#ifdef EXV_HAVE_XMP_TOOLKIT
|
||||
std::ostringstream res;
|
||||
MD5_CTX context;
|
||||
unsigned char digest[16];
|
||||
|
||||
MD5Init(&context);
|
||||
|
||||
DataBuf data = IptcParser::encode(*iptcData_);
|
||||
MD5Update(&context, data.c_data(), data.size());
|
||||
MD5Final(digest, &context);
|
||||
res << std::setw(2) << std::setfill('0') << std::hex << std::uppercase;
|
||||
for (auto&& i : digest) {
|
||||
res << static_cast<int>(i);
|
||||
}
|
||||
return res.str();
|
||||
#else
|
||||
return std::string("");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// *************************************************************************
|
||||
// free functions
|
||||
@ -1288,6 +1263,7 @@ namespace Exiv2 {
|
||||
converter.cnvToXmp();
|
||||
}
|
||||
|
||||
/// \todo not used internally. We should at least have unit tests for this.
|
||||
void moveExifToXmp(ExifData& exifData, XmpData& xmpData)
|
||||
{
|
||||
Converter converter(exifData, xmpData);
|
||||
@ -1301,6 +1277,7 @@ namespace Exiv2 {
|
||||
converter.cnvFromXmp();
|
||||
}
|
||||
|
||||
/// \todo not used internally. We should at least have unit tests for this.
|
||||
void moveXmpToExif(XmpData& xmpData, ExifData& exifData)
|
||||
{
|
||||
Converter converter(exifData, xmpData);
|
||||
@ -1323,6 +1300,7 @@ namespace Exiv2 {
|
||||
converter.cnvToXmp();
|
||||
}
|
||||
|
||||
/// \todo not used internally. We should at least have unit tests for this.
|
||||
void moveIptcToXmp(IptcData& iptcData, XmpData& xmpData, const char *iptcCharset)
|
||||
{
|
||||
if (!iptcCharset) iptcCharset = iptcData.detectCharset();
|
||||
@ -1338,6 +1316,7 @@ namespace Exiv2 {
|
||||
converter.cnvFromXmp();
|
||||
}
|
||||
|
||||
/// \todo not used internally. We should at least have unit tests for this.
|
||||
void moveXmpToIptc(XmpData& xmpData, IptcData& iptcData)
|
||||
{
|
||||
Converter converter(iptcData, xmpData);
|
||||
|
||||
@ -81,7 +81,7 @@ namespace Exiv2 {
|
||||
printTiffStructure(io(),out,option,depth-1);
|
||||
}
|
||||
|
||||
void Cr2Image::setComment(const std::string& /*comment*/)
|
||||
void Cr2Image::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "CR2"));
|
||||
|
||||
@ -147,9 +147,6 @@ namespace Exiv2 {
|
||||
// Parse the image, starting with a CIFF header component
|
||||
CiffHeader header;
|
||||
header.read(pData, size);
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
header.print(std::cerr);
|
||||
#endif
|
||||
header.decode(*pCrwImage);
|
||||
|
||||
// a hack to get absolute offset of preview image inside CRW structure
|
||||
|
||||
@ -21,13 +21,13 @@
|
||||
#include "crwimage_int.hpp"
|
||||
#include "canonmn_int.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
#include "timegm.h"
|
||||
#include "unused.h"
|
||||
#include "error.hpp"
|
||||
#include "enforce.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <iostream>
|
||||
|
||||
// *****************************************************************************
|
||||
// local declarations
|
||||
@ -53,7 +53,6 @@ namespace {
|
||||
// *****************************************************************************
|
||||
// local definitions
|
||||
namespace {
|
||||
//! @cond IGNORE
|
||||
constexpr RotationMap::OmList RotationMap::omList_[] = {
|
||||
{ 1, 0 },
|
||||
{ 3, 180 },
|
||||
@ -87,7 +86,6 @@ namespace {
|
||||
}
|
||||
return d;
|
||||
}
|
||||
//! @endcond
|
||||
} // namespace
|
||||
|
||||
namespace Exiv2 {
|
||||
@ -503,16 +501,6 @@ namespace Exiv2 {
|
||||
}
|
||||
} // CiffComponent::writeDirEntry
|
||||
|
||||
void CiffHeader::print(std::ostream& os, const std::string& prefix) const
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
os << prefix
|
||||
<< _("Header, offset") << " = 0x" << std::setw(8) << std::setfill('0')
|
||||
<< std::hex << std::right << offset_ << "\n";
|
||||
if (pRootDir_) pRootDir_->print(os, byteOrder_, prefix);
|
||||
os.flags(f);
|
||||
} // CiffHeader::print
|
||||
|
||||
void CiffComponent::print(std::ostream& os,
|
||||
ByteOrder byteOrder,
|
||||
const std::string& prefix) const
|
||||
@ -617,10 +605,10 @@ namespace Exiv2 {
|
||||
CiffComponent* CiffDirectory::doFindComponent(uint16_t crwTagId,
|
||||
uint16_t crwDir) const
|
||||
{
|
||||
CiffComponent* cc;
|
||||
for (auto&& component : components_) {
|
||||
cc = component->findComponent(crwTagId, crwDir);
|
||||
if (cc) return cc;
|
||||
auto cc = component->findComponent(crwTagId, crwDir);
|
||||
if (cc)
|
||||
return cc;
|
||||
}
|
||||
return nullptr;
|
||||
} // CiffDirectory::doFindComponent
|
||||
|
||||
@ -26,8 +26,6 @@
|
||||
#include "image.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
|
||||
@ -481,13 +479,7 @@ namespace Exiv2 {
|
||||
@param image Image to add metadata to
|
||||
*/
|
||||
void decode(Image& image) const;
|
||||
/*!
|
||||
@brief Print debug info for the CRW image to \em os.
|
||||
|
||||
@param os Output stream to write to.
|
||||
@param prefix Prefix to be written before each line of output.
|
||||
*/
|
||||
void print(std::ostream& os, const std::string& prefix ="") const;
|
||||
//! Return the byte order (little or big endian).
|
||||
ByteOrder byteOrder() const { return byteOrder_; }
|
||||
/*!
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include "basicio.hpp"
|
||||
#include "error.hpp"
|
||||
#include "futils.hpp"
|
||||
#include "utils.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
// + standard includes
|
||||
@ -103,11 +104,6 @@ namespace {
|
||||
// closing part of all valid XMP trailers
|
||||
const std::string xmpTrailerEnd = "?>";
|
||||
|
||||
constexpr bool startsWith(const std::string_view& s, const std::string_view& start)
|
||||
{
|
||||
return s.find(start) == 0;
|
||||
}
|
||||
|
||||
//! Write data into temp file, taking care of errors
|
||||
void writeTemp(BasicIo& tempIo, const byte* data, size_t size)
|
||||
{
|
||||
@ -1098,7 +1094,7 @@ namespace Exiv2
|
||||
return "application/postscript";
|
||||
}
|
||||
|
||||
void EpsImage::setComment(const std::string& /*comment*/)
|
||||
void EpsImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
throw Error(kerInvalidSettingForImage, "Image comment", "EPS");
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
116
src/futils.cpp
116
src/futils.cpp
@ -27,19 +27,23 @@
|
||||
#include "image_int.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#ifdef EXV_HAVE_UNISTD_H
|
||||
#include <unistd.h> // for stat()
|
||||
#ifdef EXV_HAVE_UNISTD_H
|
||||
#include <unistd.h> // for stat()
|
||||
#endif
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <windows.h>
|
||||
#include <psapi.h> // For access to GetModuleFileNameEx
|
||||
@ -101,52 +105,43 @@ namespace Exiv2 {
|
||||
return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
|
||||
}
|
||||
|
||||
std::string urlencode(const char* str) {
|
||||
const char* pstr = str;
|
||||
// \todo try to use std::string for buf and avoid the creation of another string for just
|
||||
// returning the final value
|
||||
auto buf = new char[strlen(str) * 3 + 1];
|
||||
char* pbuf = buf;
|
||||
while (*pstr) {
|
||||
if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
|
||||
*pbuf++ = *pstr;
|
||||
else if (*pstr == ' ')
|
||||
*pbuf++ = '+';
|
||||
else
|
||||
*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
|
||||
pstr++;
|
||||
}
|
||||
*pbuf = '\0';
|
||||
std::string ret(buf);
|
||||
delete [] buf;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* urldecode(const char* str) {
|
||||
const char* pstr = str;
|
||||
auto buf = new char[(strlen(str) + 1)];
|
||||
char* pbuf = buf;
|
||||
while (*pstr) {
|
||||
if (*pstr == '%') {
|
||||
if (pstr[1] && pstr[2]) {
|
||||
*pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]);
|
||||
pstr += 2;
|
||||
}
|
||||
} else if (*pstr == '+') {
|
||||
*pbuf++ = ' ';
|
||||
} else {
|
||||
*pbuf++ = *pstr;
|
||||
std::string urlencode(std::string_view str)
|
||||
{
|
||||
std::string encoded;
|
||||
encoded.reserve(str.size() * 3);
|
||||
for (uint8_t c : str) {
|
||||
if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
|
||||
encoded += c;
|
||||
else if (c == ' ')
|
||||
encoded += '+';
|
||||
else {
|
||||
encoded += '%';
|
||||
encoded += to_hex(c >> 4);
|
||||
encoded += to_hex(c & 15);
|
||||
}
|
||||
pstr++;
|
||||
}
|
||||
*pbuf = '\0';
|
||||
return buf;
|
||||
encoded.shrink_to_fit();
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void urldecode(std::string& str) {
|
||||
char* decodeStr = Exiv2::urldecode(str.c_str());
|
||||
str = std::string(decodeStr);
|
||||
delete [] decodeStr;
|
||||
void urldecode(std::string& str)
|
||||
{
|
||||
size_t idxIn{0}, idxOut{0};
|
||||
size_t sizeStr = str.size();
|
||||
while (idxIn < sizeStr) {
|
||||
if (str[idxIn] == '%') {
|
||||
if (str[idxIn+1] && str[idxIn+2]) {
|
||||
str[idxOut++] = from_hex(str[idxIn+1]) << 4 | from_hex(str[idxIn+2]);
|
||||
idxIn += 2;
|
||||
}
|
||||
} else if (str[idxIn] == '+') {
|
||||
str[idxOut++] = ' ';
|
||||
} else {
|
||||
str[idxOut++] = str[idxIn];
|
||||
}
|
||||
idxIn++;
|
||||
}
|
||||
str.erase(idxOut);
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/questions/342409/how-do-i-base64-encode-decode-in-c
|
||||
@ -157,7 +152,6 @@ namespace Exiv2 {
|
||||
|
||||
int base64encode(const void* data_buf, size_t dataLength, char* result, size_t resultSize) {
|
||||
auto encoding_table = base64_encode;
|
||||
size_t mod_table[] = {0, 2, 1};
|
||||
|
||||
size_t output_length = 4 * ((dataLength + 2) / 3);
|
||||
int rc = result && data_buf && output_length < resultSize ? 1 : 0;
|
||||
@ -177,6 +171,7 @@ namespace Exiv2 {
|
||||
result[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
|
||||
}
|
||||
|
||||
const size_t mod_table[] = {0, 2, 1};
|
||||
for (size_t i = 0; i < mod_table[dataLength % 3]; i++)
|
||||
result[output_length - 1 - i] = '=';
|
||||
result[output_length]=0;
|
||||
@ -252,25 +247,12 @@ namespace Exiv2 {
|
||||
return result;
|
||||
} // fileProtocol
|
||||
|
||||
bool fileExists(const std::string& path, bool ct)
|
||||
bool fileExists(const std::string& path)
|
||||
{
|
||||
// special case: accept "-" (means stdin)
|
||||
if (path == "-" || fileProtocol(path) != pFile) {
|
||||
if (fileProtocol(path) != pFile) {
|
||||
return true;
|
||||
}
|
||||
|
||||
struct stat buf;
|
||||
int ret = ::stat(path.c_str(), &buf);
|
||||
if (0 != ret) return false;
|
||||
if (ct && !S_ISREG(buf.st_mode)) return false;
|
||||
return true;
|
||||
} // fileExists
|
||||
|
||||
std::string pathOfFileUrl(const std::string& url) {
|
||||
std::string path = url.substr(7);
|
||||
size_t found = path.find('/');
|
||||
if (found == std::string::npos) return path;
|
||||
return path.substr(found);
|
||||
return fs::exists(path);
|
||||
}
|
||||
|
||||
std::string strError()
|
||||
|
||||
@ -58,7 +58,7 @@ namespace Exiv2 {
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "GIF"));
|
||||
}
|
||||
|
||||
void GifImage::setComment(const std::string& /*comment*/)
|
||||
void GifImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "GIF"));
|
||||
|
||||
@ -239,8 +239,6 @@ int Exiv2::http(Exiv2::Dictionary& request,Exiv2::Dictionary& response,std::stri
|
||||
servername_p = Proxy.Host.c_str();
|
||||
port_p = Proxy.Port.c_str();
|
||||
page = url.c_str();
|
||||
std::string p(proxy?proxi:PROXI);
|
||||
// std::cerr << p << '=' << prox << " page = " << page << std::endl;
|
||||
}
|
||||
if ( !port [0] ) port = "80";
|
||||
if ( !port_p[0] ) port_p = "80";
|
||||
|
||||
@ -135,6 +135,12 @@ namespace {
|
||||
{ ImageType::none, nullptr, nullptr, amNone, amNone, amNone, amNone }
|
||||
};
|
||||
|
||||
std::string pathOfFileUrl(const std::string& url) {
|
||||
std::string path = url.substr(7);
|
||||
size_t found = path.find('/');
|
||||
return (found == std::string::npos) ? path : path.substr(found);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// *****************************************************************************
|
||||
@ -278,6 +284,7 @@ namespace Exiv2 {
|
||||
return Image::byteSwap(v,bSwap);
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
uint64_t Image::byteSwap8(const DataBuf& buf,size_t offset,bool bSwap)
|
||||
{
|
||||
uint64_t v = 0;
|
||||
@ -367,7 +374,6 @@ namespace Exiv2 {
|
||||
// Break for unknown tag types else we may segfault.
|
||||
if ( !typeValid(type) ) {
|
||||
EXV_ERROR << "invalid type in tiff structure" << type << std::endl;
|
||||
start = 0; // break from do loop
|
||||
throw Error(kerInvalidTypeValue);
|
||||
}
|
||||
|
||||
@ -519,7 +525,6 @@ namespace Exiv2 {
|
||||
out << Internal::indent(depth) << "END " << io.path() << std::endl;
|
||||
}
|
||||
out.flush();
|
||||
depth--;
|
||||
}
|
||||
|
||||
void Image::printTiffStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,int depth,size_t offset /*=0*/)
|
||||
@ -576,6 +581,7 @@ namespace Exiv2 {
|
||||
return xmpPacket_;
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
void Image::setMetadata(const Image& image)
|
||||
{
|
||||
if (checkMode(mdExif) & amWrite) {
|
||||
@ -624,7 +630,6 @@ namespace Exiv2 {
|
||||
|
||||
void Image::setXmpPacket(const std::string& xmpPacket)
|
||||
{
|
||||
xmpPacket_ = xmpPacket;
|
||||
if ( XmpParser::decode(xmpData_, xmpPacket) ) {
|
||||
throw Error(kerInvalidXMP);
|
||||
}
|
||||
@ -657,7 +662,7 @@ namespace Exiv2 {
|
||||
comment_.erase();
|
||||
}
|
||||
|
||||
void Image::setComment(const std::string& comment)
|
||||
void Image::setComment(std::string_view comment)
|
||||
{
|
||||
comment_ = comment;
|
||||
}
|
||||
@ -749,6 +754,7 @@ namespace Exiv2 {
|
||||
return ImageFactory::checkType(imageType_, *io_, false);
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
bool Image::supportsMetadata(MetadataId metadataId) const
|
||||
{
|
||||
return (supportedMetadata_ & metadataId) != 0;
|
||||
|
||||
@ -57,52 +57,6 @@ namespace Exiv2
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string binaryToHex(const byte* data, size_t size)
|
||||
{
|
||||
std::stringstream hexOutput;
|
||||
|
||||
auto tl = size_t(size / 16) * 16;
|
||||
auto tl_offset = size_t(size) - tl;
|
||||
|
||||
for (size_t loop = 0; loop < size; loop++) {
|
||||
if (data[loop] < 16) {
|
||||
hexOutput << "0";
|
||||
}
|
||||
hexOutput << std::hex << static_cast<int>(data[loop]);
|
||||
if ((loop % 8) == 7) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
if ((loop % 16) == 15 || loop == (tl + tl_offset - 1)) {
|
||||
int max = 15;
|
||||
if (loop >= tl) {
|
||||
max = int(tl_offset) - 1;
|
||||
for (int offset = 0; offset < int(16 - tl_offset); offset++) {
|
||||
if ((offset % 8) == 7) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
hexOutput << " ";
|
||||
}
|
||||
}
|
||||
hexOutput << " ";
|
||||
for (int offset = max; offset >= 0; offset--) {
|
||||
if (offset == (max - 8)) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
byte c = '.';
|
||||
if (data[loop - offset] >= 0x20 && data[loop - offset] <= 0x7E) {
|
||||
c = data[loop - offset];
|
||||
}
|
||||
hexOutput << static_cast<char>(c);
|
||||
}
|
||||
hexOutput << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
hexOutput << std::endl << std::endl << std::endl;
|
||||
|
||||
return hexOutput.str();
|
||||
}
|
||||
|
||||
std::string indent(int32_t d)
|
||||
{
|
||||
std::string result;
|
||||
|
||||
@ -120,14 +120,7 @@ namespace Exiv2 {
|
||||
return binaryToStringHelper<T>(sl);
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief format binary for display of raw data .
|
||||
*/
|
||||
std::string binaryToHex(const byte *data, size_t size);
|
||||
|
||||
/*!
|
||||
@brief indent output for kpsRecursive in \em printStructure() \em .
|
||||
*/
|
||||
/// @brief indent output for kpsRecursive in \em printStructure() \em .
|
||||
std::string indent(int32_t depth);
|
||||
|
||||
}} // namespace Internal, Exiv2
|
||||
|
||||
@ -327,11 +327,13 @@ namespace Exiv2 {
|
||||
FindIptcdatum(dataset, record));
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
void IptcData::sortByKey()
|
||||
{
|
||||
std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByKey);
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
void IptcData::sortByTag()
|
||||
{
|
||||
std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByTag);
|
||||
@ -350,8 +352,7 @@ namespace Exiv2 {
|
||||
size_t i = 0;
|
||||
while (i < bytes.size() - 3 && bytes.at(i) != 0x1c)
|
||||
i++;
|
||||
depth++;
|
||||
out << Internal::indent(depth) << "Record | DataSet | Name | Length | Data" << std::endl;
|
||||
out << Internal::indent(++depth) << "Record | DataSet | Name | Length | Data" << std::endl;
|
||||
while (i < bytes.size() - 3) {
|
||||
if (bytes.at(i) != 0x1c) {
|
||||
break;
|
||||
@ -370,7 +371,6 @@ namespace Exiv2 {
|
||||
<< std::endl;
|
||||
i += 5 + len;
|
||||
}
|
||||
depth--;
|
||||
}
|
||||
|
||||
const char *IptcData::detectCharset() const
|
||||
|
||||
@ -158,11 +158,11 @@ namespace Exiv2
|
||||
return "image/jp2";
|
||||
}
|
||||
|
||||
void Jp2Image::setComment(const std::string& /*comment*/)
|
||||
void Jp2Image::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// Todo: implement me!
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "JP2"));
|
||||
} // Jp2Image::setComment
|
||||
}
|
||||
|
||||
static void lf(std::ostream& out,bool& bLF)
|
||||
{
|
||||
@ -221,7 +221,6 @@ static void boxes_check(size_t b,size_t m)
|
||||
throw Error(kerNotAnImage, "JPEG-2000");
|
||||
}
|
||||
|
||||
long position = 0;
|
||||
Jp2BoxHeader box = {0,0};
|
||||
Jp2BoxHeader subBox = {0,0};
|
||||
Jp2ImageHeaderBox ihdr = {0,0,0,0,0,0,0,0};
|
||||
@ -231,7 +230,7 @@ static void boxes_check(size_t b,size_t m)
|
||||
|
||||
while (io_->read(reinterpret_cast<byte*>(&box), sizeof(box)) == sizeof(box)) {
|
||||
boxes_check(boxes++,boxem );
|
||||
position = io_->tell();
|
||||
long position = io_->tell();
|
||||
box.length = getLong(reinterpret_cast<byte*>(&box.length), bigEndian);
|
||||
box.type = getLong(reinterpret_cast<byte*>(&box.type), bigEndian);
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
@ -490,7 +489,6 @@ static void boxes_check(size_t b,size_t m)
|
||||
|
||||
if ( bPrint || bXMP || bICC || bIPTCErase ) {
|
||||
|
||||
long position = 0;
|
||||
Jp2BoxHeader box = {1,1};
|
||||
Jp2BoxHeader subBox = {1,1};
|
||||
Jp2UuidBox uuid = {{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
@ -498,7 +496,7 @@ static void boxes_check(size_t b,size_t m)
|
||||
|
||||
while (box.length && box.type != kJp2BoxTypeClose &&
|
||||
io_->read(reinterpret_cast<byte*>(&box), sizeof(box)) == sizeof(box)) {
|
||||
position = io_->tell();
|
||||
long position = io_->tell();
|
||||
box.length = getLong(reinterpret_cast<byte*>(&box.length), bigEndian);
|
||||
box.type = getLong(reinterpret_cast<byte*>(&box.type), bigEndian);
|
||||
enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata);
|
||||
|
||||
@ -32,11 +32,15 @@
|
||||
#include "tiffvisitor_int.hpp"
|
||||
#include "tiffimage.hpp"
|
||||
#include "tiffimage_int.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#ifndef __MINGW__
|
||||
@ -52,25 +56,6 @@
|
||||
#include <windows.h>
|
||||
#include <direct.h> // _getcwd
|
||||
#include <shlobj.h>
|
||||
/* older SDKs not have these */
|
||||
# ifndef CSIDL_MYMUSIC
|
||||
# define CSIDL_MYMUSIC 13
|
||||
# endif
|
||||
# ifndef CSIDL_MYVIDEO
|
||||
# define CSIDL_MYVIDEO 14
|
||||
# endif
|
||||
# ifndef CSIDL_INTERNET_CACHE
|
||||
# define CSIDL_INTERNET_CACHE 32
|
||||
# endif
|
||||
# ifndef CSIDL_COMMON_APPDATA
|
||||
# define CSIDL_COMMON_APPDATA 35
|
||||
# endif
|
||||
# ifndef CSIDL_MYPICTURES
|
||||
# define CSIDL_MYPICTURES 0x27
|
||||
# endif
|
||||
# ifndef CSIDL_COMMON_DOCUMENTS
|
||||
# define CSIDL_COMMON_DOCUMENTS 46
|
||||
# endif
|
||||
# ifndef CSIDL_PROFILE
|
||||
# define CSIDL_PROFILE 40
|
||||
# endif
|
||||
@ -96,7 +81,6 @@ namespace {
|
||||
namespace Exiv2 {
|
||||
namespace Internal {
|
||||
|
||||
// C++17 use std::filesystem
|
||||
// Function first looks for a config file in current working directory
|
||||
// on Win the file should be named "exiv2.ini"
|
||||
// on Lin the file should be named ".exiv2"
|
||||
@ -104,36 +88,27 @@ namespace Exiv2 {
|
||||
// which is the user profile path on win and the home dir on linux
|
||||
std::string getExiv2ConfigPath()
|
||||
{
|
||||
std::string dir;
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
std::string inifile("exiv2.ini");
|
||||
#else
|
||||
std::string inifile(".exiv2");
|
||||
#endif
|
||||
|
||||
// first lets get the current working directory to check if there is a config file
|
||||
char buffer[1024];
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
auto path = _getcwd(buffer, sizeof(buffer));
|
||||
#else
|
||||
auto path = getcwd(buffer, sizeof(buffer));
|
||||
#endif
|
||||
dir = std::string(path ? path : "");
|
||||
auto const filename = dir + EXV_SEPARATOR_CHR + inifile;
|
||||
// true if the file exists
|
||||
if (std::ifstream(filename).good()) {
|
||||
return filename;
|
||||
auto currentPath = fs::current_path();
|
||||
auto iniPath = currentPath / inifile;
|
||||
if (fs::exists(iniPath)) {
|
||||
return iniPath.string();
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW__)
|
||||
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path))) {
|
||||
dir = std::string(path);
|
||||
char buffer[1024];
|
||||
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, buffer))) {
|
||||
currentPath = buffer;
|
||||
}
|
||||
#else
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
dir = std::string(pw ? pw->pw_dir : "");
|
||||
currentPath = std::string(pw ? pw->pw_dir : "");
|
||||
#endif
|
||||
return dir + EXV_SEPARATOR_CHR + inifile;
|
||||
return (currentPath / inifile).string();
|
||||
}
|
||||
|
||||
std::string readExiv2Config(const std::string& section, const std::string& value, const std::string& def)
|
||||
@ -1223,11 +1198,8 @@ namespace Exiv2 {
|
||||
{
|
||||
// Not valid for models beginning
|
||||
std::string model = getExifModel(pRoot);
|
||||
for (auto& m : { "SLT-", "HV", "ILCA-" }) {
|
||||
if (model.find(m) == 0)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
const std::array strs { "SLT-", "HV", "ILCA-"};
|
||||
return std::any_of(strs.begin(), strs.end(), [&model](auto& m){return startsWith(model, m);}) ? -1 : 0;
|
||||
}
|
||||
|
||||
int sonyMisc2bSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot)
|
||||
|
||||
@ -24,12 +24,8 @@
|
||||
// included header files
|
||||
#include "tifffwd_int.hpp"
|
||||
#include "tags_int.hpp"
|
||||
#include "ini.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -63,7 +63,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
//! Lookup table to translate Minolta image quality values to readable labels
|
||||
EXV_UNUSED constexpr TagDetails minoltaImageQuality[] = {
|
||||
[[maybe_unused]] constexpr TagDetails minoltaImageQuality[] = {
|
||||
{ 0, N_("Raw") },
|
||||
{ 1, N_("Super Fine") },
|
||||
{ 2, N_("Fine") },
|
||||
@ -273,7 +273,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
//! Lookup table to translate Minolta Std camera settings AF points values to readable labels
|
||||
EXV_UNUSED constexpr TagDetails minoltaAFPointsStd[] = {
|
||||
[[maybe_unused]] constexpr TagDetails minoltaAFPointsStd[] = {
|
||||
{ 0, N_("Center") },
|
||||
{ 1, N_("Top") },
|
||||
{ 2, N_("Top-right") },
|
||||
@ -2490,16 +2490,5 @@ namespace Exiv2 {
|
||||
return EXV_PRINT_TAG(minoltaSonyZoneMatching)(os, value, metadata);
|
||||
}
|
||||
|
||||
std::ostream& printMinoltaSonyFlashExposureComp(std::ostream& os, const Value& value, const ExifData*)
|
||||
{
|
||||
std::ios::fmtflags f( os.flags() );
|
||||
if (value.count() != 1 || value.typeId() != signedRational) {
|
||||
return os << "(" << value << ")";
|
||||
}
|
||||
os << std::fixed << std::setprecision(2) << value.toFloat(0) << " EV";
|
||||
os.flags(f);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Exiv2
|
||||
|
||||
@ -136,9 +136,6 @@ namespace Exiv2 {
|
||||
//! Print Minolta/Sony ZoneMatching values to readable labels.
|
||||
std::ostream& printMinoltaSonyZoneMatching(std::ostream&, const Value&, const ExifData*);
|
||||
|
||||
//! Print Minolta/Sony FlashExposureComp values to readable labels.
|
||||
std::ostream& printMinoltaSonyFlashExposureComp(std::ostream&, const Value&, const ExifData*);
|
||||
|
||||
// TODO: Added shared methods here.
|
||||
|
||||
}} // namespace Internal, Exiv2
|
||||
|
||||
@ -79,7 +79,7 @@ namespace Exiv2 {
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "MRW"));
|
||||
}
|
||||
|
||||
void MrwImage::setComment(const std::string& /*comment*/)
|
||||
void MrwImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "MRW"));
|
||||
|
||||
@ -490,7 +490,7 @@ namespace Exiv2 {
|
||||
};
|
||||
|
||||
//! FocusMode, tag 0x0301
|
||||
EXV_UNUSED constexpr TagDetails olympusCsFocusMode[] = {
|
||||
[[maybe_unused]] constexpr TagDetails olympusCsFocusMode[] = {
|
||||
{ 0, N_("Single AF") },
|
||||
{ 1, N_("Sequential shooting AF") },
|
||||
{ 2, N_("Continuous AF") },
|
||||
|
||||
@ -72,7 +72,7 @@ namespace Exiv2 {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OrfImage::setComment(const std::string& /*comment*/)
|
||||
void OrfImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "ORF"));
|
||||
|
||||
@ -25,10 +25,6 @@
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -26,10 +26,6 @@
|
||||
#include "tags_int.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -25,11 +25,6 @@
|
||||
#include "types.hpp"
|
||||
#include "pngimage.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iosfwd>
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
@ -150,11 +151,11 @@ namespace Exiv2 {
|
||||
|
||||
static bool tEXtToDataBuf(const byte* bytes,long length,DataBuf& result)
|
||||
{
|
||||
static const char* hexdigits = "0123456789ABCDEF";
|
||||
static std::array<int, 256> value;
|
||||
static bool bFirst = true;
|
||||
if ( bFirst ) {
|
||||
value.fill(0);
|
||||
const char* hexdigits = "0123456789ABCDEF";
|
||||
for ( int i = 0 ; i < 16 ; i++ ) {
|
||||
value[tolower(hexdigits[i])]=i+1;
|
||||
value[toupper(hexdigits[i])]=i+1;
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
// included header files
|
||||
#include "config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <climits>
|
||||
#include <string>
|
||||
|
||||
@ -3943,6 +3943,7 @@ namespace Exiv2 {
|
||||
XmpProperties::NsRegistry XmpProperties::nsRegistry_;
|
||||
std::mutex XmpProperties::mutex_;
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
const XmpNsInfo* XmpProperties::lookupNsRegistry(const XmpNsInfo::Prefix& prefix)
|
||||
{
|
||||
std::lock_guard<std::mutex> scoped_read_lock(mutex_);
|
||||
@ -4095,6 +4096,7 @@ namespace Exiv2 {
|
||||
return pi;
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
const char* XmpProperties::nsDesc(const std::string& prefix)
|
||||
{
|
||||
return nsInfo(prefix)->desc_;
|
||||
|
||||
@ -127,7 +127,7 @@ namespace Exiv2 {
|
||||
return "image/x-photoshop";
|
||||
}
|
||||
|
||||
void PsdImage::setComment(const std::string& /*comment*/)
|
||||
void PsdImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "Photoshop"));
|
||||
@ -399,13 +399,15 @@ namespace Exiv2 {
|
||||
#endif
|
||||
// Copy colorData
|
||||
uint32_t readTotal = 0;
|
||||
long toRead = 0;
|
||||
while (readTotal < colorDataLength) {
|
||||
toRead = static_cast<long>(colorDataLength - readTotal) < lbuf.size()
|
||||
? static_cast<long>(colorDataLength - readTotal) : lbuf.size();
|
||||
if (io_->read(lbuf.data(), toRead) != toRead) throw Error(kerNotAnImage, "Photoshop");
|
||||
long toRead = static_cast<long>(colorDataLength - readTotal) < lbuf.size()
|
||||
? static_cast<long>(colorDataLength - readTotal)
|
||||
: lbuf.size();
|
||||
if (io_->read(lbuf.data(), toRead) != toRead)
|
||||
throw Error(kerNotAnImage, "Photoshop");
|
||||
readTotal += toRead;
|
||||
if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed);
|
||||
if (outIo.write(lbuf.c_data(), toRead) != toRead)
|
||||
throw Error(kerImageWriteFailed);
|
||||
}
|
||||
if (outIo.error()) throw Error(kerImageWriteFailed);
|
||||
|
||||
@ -505,15 +507,17 @@ namespace Exiv2 {
|
||||
if (outIo.write(buf, 4) != 4) throw Error(kerImageWriteFailed);
|
||||
|
||||
readTotal = 0;
|
||||
toRead = 0;
|
||||
while (readTotal < pResourceSize) {
|
||||
toRead = static_cast<long>(pResourceSize - readTotal) < lbuf.size()
|
||||
? static_cast<long>(pResourceSize - readTotal) : lbuf.size();
|
||||
/// \todo almost same code as in lines 403-410. Factor out & reuse!
|
||||
long toRead = static_cast<long>(pResourceSize - readTotal) < lbuf.size()
|
||||
? static_cast<long>(pResourceSize - readTotal)
|
||||
: lbuf.size();
|
||||
if (io_->read(lbuf.data(), toRead) != toRead) {
|
||||
throw Error(kerNotAnImage, "Photoshop");
|
||||
}
|
||||
readTotal += toRead;
|
||||
if (outIo.write(lbuf.c_data(), toRead) != toRead) throw Error(kerImageWriteFailed);
|
||||
if (outIo.write(lbuf.c_data(), toRead) != toRead)
|
||||
throw Error(kerImageWriteFailed);
|
||||
}
|
||||
if (outIo.error()) throw Error(kerImageWriteFailed);
|
||||
newResLength += pResourceSize + adjResourceNameLen + 12;
|
||||
@ -532,13 +536,11 @@ namespace Exiv2 {
|
||||
// Append ExifInfo resource block, if not yet written
|
||||
if (!exifDone) {
|
||||
newResLength += writeExifData(exifData_, outIo);
|
||||
exifDone = true;
|
||||
}
|
||||
|
||||
// Append XmpPacket resource block, if not yet written
|
||||
if (!xmpDone) {
|
||||
newResLength += writeXmpData(xmpData_, outIo);
|
||||
xmpDone = true;
|
||||
}
|
||||
|
||||
// Populate the fake data, only make sense for remoteio, httpio and sshio.
|
||||
|
||||
@ -81,7 +81,7 @@ namespace Exiv2 {
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "RAF"));
|
||||
}
|
||||
|
||||
void RafImage::setComment(const std::string& /*comment*/)
|
||||
void RafImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "RAF"));
|
||||
@ -96,12 +96,11 @@ namespace Exiv2 {
|
||||
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
|
||||
throw Error(kerNotAnImage, "RAF");
|
||||
}
|
||||
size_t address = 0 ;
|
||||
size_t address2 = 0 ;
|
||||
|
||||
const bool bPrint = option==kpsBasic || option==kpsRecursive;
|
||||
if ( bPrint ) {
|
||||
io_->seek(0,BasicIo::beg); // rewind
|
||||
address = io_->tell();
|
||||
size_t address = io_->tell();
|
||||
const char* format = " %8d | %8d | ";
|
||||
|
||||
{
|
||||
@ -174,7 +173,7 @@ namespace Exiv2 {
|
||||
byte jpg_img_offset [4];
|
||||
io_->read(jpg_img_offset, 4);
|
||||
byte jpg_img_length [4];
|
||||
address2 = io_->tell();
|
||||
size_t address2 = io_->tell();
|
||||
io_->read(jpg_img_length, 4);
|
||||
|
||||
long jpg_img_off = Exiv2::getULong(jpg_img_offset, bigEndian);
|
||||
|
||||
@ -83,7 +83,7 @@ namespace Exiv2 {
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "RW2"));
|
||||
}
|
||||
|
||||
void Rw2Image::setComment(const std::string& /*comment*/)
|
||||
void Rw2Image::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "RW2"));
|
||||
|
||||
@ -23,10 +23,6 @@
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "tiffimage_int.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
@ -25,11 +25,6 @@
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -25,11 +25,6 @@
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -22,14 +22,8 @@
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "tags.hpp"
|
||||
#include "types.hpp"
|
||||
#include "tiffcomposite_int.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
namespace Exiv2 {
|
||||
|
||||
@ -127,6 +127,7 @@ namespace Exiv2 {
|
||||
return sectionInfo[ti->sectionId_].name_;
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
uint16_t ExifTags::defaultCount(const ExifKey& key)
|
||||
{
|
||||
const TagInfo* ti = tagInfo(key.tag(), static_cast<Internal::IfdId>(key.ifdId()));
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
#include "sonymn_int.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
// *****************************************************************************
|
||||
// local declarations
|
||||
|
||||
@ -22,14 +22,7 @@
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "types.hpp"
|
||||
#include "tags.hpp"
|
||||
#include "value.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
@ -58,7 +58,7 @@ namespace Exiv2 {
|
||||
throw(Error(kerInvalidSettingForImage, "IPTC metadata", "TGA"));
|
||||
}
|
||||
|
||||
void TgaImage::setComment(const std::string& /*comment*/)
|
||||
void TgaImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "TGA"));
|
||||
@ -133,7 +133,7 @@ namespace Exiv2 {
|
||||
bool isTgaType(BasicIo& iIo, bool /*advance*/)
|
||||
{
|
||||
// not all TARGA files have a signature string, so first just try to match the file name extension
|
||||
std::string path = iIo.path();
|
||||
const std::string& path = iIo.path();
|
||||
if( path.rfind(".tga") != std::string::npos
|
||||
|| path.rfind(".TGA") != std::string::npos) {
|
||||
return true;
|
||||
|
||||
@ -22,16 +22,9 @@
|
||||
|
||||
// *****************************************************************************
|
||||
// included header files
|
||||
#include "value.hpp"
|
||||
#include "tifffwd_int.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <iosfwd>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
@ -26,9 +26,7 @@
|
||||
#include "tags_int.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
|
||||
// *****************************************************************************
|
||||
// Exiv2 namespace extensions
|
||||
|
||||
@ -162,7 +162,7 @@ namespace Exiv2 {
|
||||
return pixelHeightPrimary_;
|
||||
}
|
||||
|
||||
void TiffImage::setComment(const std::string& /*comment*/)
|
||||
void TiffImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "TIFF"));
|
||||
|
||||
@ -26,6 +26,8 @@
|
||||
#include "tiffvisitor_int.hpp"
|
||||
#include "i18n.h" // NLS support.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// Shortcuts for the newTiffBinaryArray templates.
|
||||
#define EXV_BINARY_ARRAY(arrayCfg, arrayDef) (newTiffBinaryArray0<&arrayCfg, EXV_COUNTOF(arrayDef), arrayDef>)
|
||||
#define EXV_SIMPLE_BINARY_ARRAY(arrayCfg) (newTiffBinaryArray1<&arrayCfg>)
|
||||
|
||||
@ -25,12 +25,6 @@
|
||||
#include "tifffwd_int.hpp"
|
||||
#include "tiffcomposite_int.hpp"
|
||||
#include "image.hpp"
|
||||
#include "tags_int.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
|
||||
@ -469,6 +469,7 @@ namespace Exiv2 {
|
||||
const uint16_t nMasks = (nPoints+15)/(sizeof(uint16_t) * 8);
|
||||
int nStart = 0;
|
||||
|
||||
/// \todo make this static
|
||||
struct {
|
||||
uint16_t tag ;
|
||||
uint16_t size ;
|
||||
|
||||
@ -26,15 +26,7 @@
|
||||
#include "tifffwd_int.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
// *****************************************************************************
|
||||
// namespace extensions
|
||||
@ -42,6 +34,8 @@ namespace Exiv2 {
|
||||
|
||||
class IptcData;
|
||||
class XmpData;
|
||||
class TiffImageEntry;
|
||||
class TiffDataEntryBase;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
|
||||
9
src/utils.cpp
Normal file
9
src/utils.cpp
Normal file
@ -0,0 +1,9 @@
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace Exiv2
|
||||
{
|
||||
bool startsWith(const std::string_view& s, const std::string_view& start)
|
||||
{
|
||||
return s.find(start) == 0;
|
||||
}
|
||||
}
|
||||
11
src/utils.hpp
Normal file
11
src/utils.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef EXIV2_UTILS_HPP
|
||||
#define EXIV2_UTILS_HPP
|
||||
|
||||
#include <string_view>
|
||||
|
||||
namespace Exiv2
|
||||
{
|
||||
bool startsWith(const std::string_view& s, const std::string_view& start);
|
||||
}
|
||||
|
||||
#endif // EXIV2_UTILS_HPP
|
||||
@ -804,7 +804,6 @@ namespace Exiv2 {
|
||||
std::string lang = "x-default";
|
||||
if (buf.length() > 5 && buf.substr(0, 5) == "lang=") {
|
||||
static const char* ALPHA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
static const char* ALPHA_NUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
const std::string::size_type pos = buf.find_first_of(' ');
|
||||
if (pos == std::string::npos) {
|
||||
@ -829,6 +828,7 @@ namespace Exiv2 {
|
||||
// Check language is in the correct format (see https://www.ietf.org/rfc/rfc3066.txt)
|
||||
std::string::size_type charPos = lang.find_first_not_of(ALPHA);
|
||||
if (charPos != std::string::npos) {
|
||||
static const char* ALPHA_NUM = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
if (lang.at(charPos) != '-' || lang.find_first_not_of(ALPHA_NUM, charPos+1) != std::string::npos)
|
||||
throw Error(kerInvalidLangAltValue, buf);
|
||||
}
|
||||
@ -1110,6 +1110,7 @@ namespace Exiv2 {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// \todo not used internally. At least we should test it
|
||||
void TimeValue::setTime( const Time& src )
|
||||
{
|
||||
std::memcpy(&time_, &src, sizeof(time_));
|
||||
|
||||
@ -36,13 +36,10 @@
|
||||
#endif
|
||||
|
||||
// + standard includes
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
// #1147
|
||||
#ifndef WIN32
|
||||
@ -139,7 +136,7 @@ static void output(std::ostream& os,const std::vector<std::regex>& greps,const c
|
||||
|
||||
static bool pushPath(std::string& path,std::vector<std::string>& libs,std::set<std::string>& paths)
|
||||
{
|
||||
bool result = Exiv2::fileExists(path,true) && paths.find(path) == paths.end() && path != "/" ;
|
||||
bool result = Exiv2::fileExists(path) && paths.find(path) == paths.end() && path != "/" ;
|
||||
if ( result ) {
|
||||
paths.insert(path);
|
||||
libs.push_back(path);
|
||||
@ -313,7 +310,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys
|
||||
int have_lensdata =0;
|
||||
int have_iconv =0;
|
||||
int have_memory =0;
|
||||
int have_lstat =0;
|
||||
int have_stdbool =0;
|
||||
int have_stdint =0;
|
||||
int have_stdlib =0;
|
||||
@ -362,10 +358,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys
|
||||
have_memory=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_LSTAT
|
||||
have_lstat=1;
|
||||
#endif
|
||||
|
||||
#ifdef EXV_HAVE_STDBOOL_H
|
||||
have_stdbool=1;
|
||||
#endif
|
||||
@ -492,7 +484,6 @@ void Exiv2::dumpLibraryInfo(std::ostream& os,const std::vector<std::regex>& keys
|
||||
output(os,keys,"have_lensdata" ,have_lensdata );
|
||||
output(os,keys,"have_iconv" ,have_iconv );
|
||||
output(os,keys,"have_memory" ,have_memory );
|
||||
output(os,keys,"have_lstat" ,have_lstat );
|
||||
output(os,keys,"have_stdbool" ,have_stdbool );
|
||||
output(os,keys,"have_stdint" ,have_stdint );
|
||||
output(os,keys,"have_stdlib" ,have_stdlib );
|
||||
|
||||
@ -50,6 +50,54 @@
|
||||
|
||||
#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))
|
||||
|
||||
namespace {
|
||||
[[maybe_unused]] std::string binaryToHex(const uint8_t* data, size_t size)
|
||||
{
|
||||
std::stringstream hexOutput;
|
||||
|
||||
auto tl = size_t(size / 16) * 16;
|
||||
auto tl_offset = size_t(size) - tl;
|
||||
|
||||
for (size_t loop = 0; loop < size; loop++) {
|
||||
if (data[loop] < 16) {
|
||||
hexOutput << "0";
|
||||
}
|
||||
hexOutput << std::hex << static_cast<int>(data[loop]);
|
||||
if ((loop % 8) == 7) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
if ((loop % 16) == 15 || loop == (tl + tl_offset - 1)) {
|
||||
int max = 15;
|
||||
if (loop >= tl) {
|
||||
max = int(tl_offset) - 1;
|
||||
for (int offset = 0; offset < int(16 - tl_offset); offset++) {
|
||||
if ((offset % 8) == 7) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
hexOutput << " ";
|
||||
}
|
||||
}
|
||||
hexOutput << " ";
|
||||
for (int offset = max; offset >= 0; offset--) {
|
||||
if (offset == (max - 8)) {
|
||||
hexOutput << " ";
|
||||
}
|
||||
uint8_t c = '.';
|
||||
if (data[loop - offset] >= 0x20 && data[loop - offset] <= 0x7E) {
|
||||
c = data[loop - offset];
|
||||
}
|
||||
hexOutput << static_cast<char>(c);
|
||||
}
|
||||
hexOutput << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
hexOutput << std::endl << std::endl << std::endl;
|
||||
|
||||
return hexOutput.str();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// *****************************************************************************
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
@ -96,7 +144,7 @@ namespace Exiv2 {
|
||||
// throw(Error(kerInvalidSettingForImage, "IPTC metadata", "WebP"));
|
||||
}
|
||||
|
||||
void WebPImage::setComment(const std::string& /*comment*/)
|
||||
void WebPImage::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "WebP"));
|
||||
@ -688,7 +736,7 @@ namespace Exiv2 {
|
||||
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(sizePayload) << "]" << std::endl;
|
||||
std::cout << Internal::binaryToHex(rawExifData.c_data(), sizePayload);
|
||||
std::cout << binaryToHex(rawExifData.c_data(), sizePayload);
|
||||
#endif
|
||||
|
||||
if (pos != -1) {
|
||||
@ -716,7 +764,7 @@ namespace Exiv2 {
|
||||
#ifdef EXIV2_DEBUG_MESSAGES
|
||||
std::cout << "Display Hex Dump [size:" << static_cast<unsigned long>(payload.size()) << "]"
|
||||
<< std::endl;
|
||||
std::cout << Internal::binaryToHex(payload.c_data(), payload.size());
|
||||
std::cout << binaryToHex(payload.c_data(), payload.size());
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
@ -833,8 +881,6 @@ namespace Exiv2 {
|
||||
if (iIo.tell() % 2) {
|
||||
if (iIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
|
||||
}
|
||||
|
||||
has_icc = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "convert.hpp"
|
||||
|
||||
// + standard includes
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
@ -61,7 +62,7 @@ namespace Exiv2 {
|
||||
return "application/rdf+xml";
|
||||
}
|
||||
|
||||
void XmpSidecar::setComment(const std::string& /*comment*/)
|
||||
void XmpSidecar::setComment(std::string_view /*comment*/)
|
||||
{
|
||||
// not supported
|
||||
throw(Error(kerInvalidSettingForImage, "Image comment", "XMP"));
|
||||
|
||||
@ -65,7 +65,7 @@ TEST(TheImageFactory, createsInstancesForFewSupportedTypesInFiles)
|
||||
EXPECT_NO_THROW(ImageFactory::create(ImageType::pgf, filePath));
|
||||
EXPECT_NO_THROW(ImageFactory::create(ImageType::png, filePath));
|
||||
|
||||
EXPECT_EQ(0, std::remove(filePath.c_str()));
|
||||
EXPECT_TRUE(fs::remove(filePath));
|
||||
}
|
||||
|
||||
TEST(TheImageFactory, cannotCreateInstancesForSomeTypesInFiles)
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <exiv2/futils.hpp>
|
||||
|
||||
// Auxiliary headers
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
#include <cerrno>
|
||||
@ -30,6 +31,8 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
using namespace Exiv2;
|
||||
|
||||
TEST(strError, returnSuccessAfterClosingFile)
|
||||
@ -42,7 +45,7 @@ TEST(strError, returnSuccessAfterClosingFile)
|
||||
std::string tmpFile("tmp.dat");
|
||||
std::ofstream auxFile(tmpFile.c_str());
|
||||
auxFile.close();
|
||||
std::remove(tmpFile.c_str());
|
||||
fs::remove(tmpFile.c_str());
|
||||
ASSERT_TRUE(strError().find("(errno = 0)") != std::string::npos);
|
||||
}
|
||||
|
||||
@ -97,15 +100,6 @@ TEST(urlencode, encodesGivenUrlWithSpace)
|
||||
ASSERT_STREQ("http%3a%2f%2fwww.geekhideout.com%2furl+code.shtml", url.c_str());
|
||||
}
|
||||
|
||||
TEST(urldecode, decodesGivenUrl)
|
||||
{
|
||||
const std::string expectedDecodedUrl ("http://www.geekhideout.com/urlcode.shtml");
|
||||
const std::string url ("http%3a%2f%2fwww.geekhideout.com%2furlcode.shtml");
|
||||
char * url3 = urldecode(url.c_str());
|
||||
ASSERT_STREQ(expectedDecodedUrl.c_str(), url3);
|
||||
delete [] url3;
|
||||
}
|
||||
|
||||
TEST(urldecode, decodesGivenUrlInPlace)
|
||||
{
|
||||
const std::string expectedDecodedUrl ("http://www.geekhideout.com/urlcode.shtml");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user