Skip to content

Commit 4d959ed

Browse files
committed
geotag: use more std::filesysten
Simplifies code a bit. Signed-off-by: Rosen Penev <[email protected]>
1 parent 0a09ff1 commit 4d959ed

File tree

1 file changed

+43
-98
lines changed

1 file changed

+43
-98
lines changed

samples/geotag.cpp

Lines changed: 43 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,14 @@
1212

1313
namespace fs = std::filesystem;
1414

15-
#ifdef _WIN32
16-
#include <windows.h>
17-
#if _MSC_VER < 1400
18-
#define strcpy_s(d, l, s) strcpy(d, s)
19-
#define strcat_s(d, l, s) strcat(d, s)
20-
#endif
21-
#endif
22-
23-
#ifndef _MSC_VER
24-
#include <dirent.h>
25-
#define stricmp strcasecmp
26-
#endif
27-
28-
#ifndef _MAX_PATH
29-
#define _MAX_PATH 1024
15+
#ifndef _WIN32
16+
#define _stricmp strcasecmp
3017
#endif
3118

3219
namespace {
3320
// prototypes
3421
class Options;
35-
int getFileType(const char* path, Options& options);
36-
int getFileType(std::string& path, Options& options);
22+
int getFileType(const fs::path& path, Options& options);
3723

3824
std::string getExifTime(time_t t);
3925
time_t parseTime(const char*, bool bAdjust = false);
@@ -93,11 +79,10 @@ class Position;
9379

9480
// globals
9581
using TimeDict_t = std::map<time_t, Position>;
96-
using TimeDict_i = std::map<time_t, Position>::iterator;
97-
using strings_t = std::vector<std::string>;
82+
using paths_t = std::vector<fs::path>;
9883
const char* gDeg = nullptr; // string "°" or "deg"
9984
TimeDict_t gTimeDict;
100-
strings_t gFiles;
85+
paths_t gFiles;
10186

10287
// Position (from gpx file)
10388
class Position final {
@@ -393,65 +378,19 @@ std::string getExifTime(const time_t t) {
393378
return result;
394379
}
395380

396-
std::string makePath(const std::string& dir, const fs::path& file) {
397-
auto ret = fs::path(dir) / file;
398-
return ret.string();
399-
}
400-
401381
// file utilities
402-
bool readDir(const char* path, Options& options) {
403-
bool bResult = false;
404-
405-
#ifdef _MSC_VER
406-
DWORD attrs = GetFileAttributes(path);
407-
bool bOKAttrs = attrs != INVALID_FILE_ATTRIBUTES;
408-
bool bIsDir = (attrs & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
409-
410-
if (bOKAttrs && bIsDir) {
411-
bResult = true;
412-
413-
char search[_MAX_PATH + 10];
414-
strcpy_s(search, _MAX_PATH, path);
415-
strcat_s(search, _MAX_PATH, "\\*");
416-
417-
WIN32_FIND_DATA ffd;
418-
HANDLE hFind = FindFirstFile(search, &ffd);
419-
BOOL bGo = hFind != INVALID_HANDLE_VALUE;
420-
421-
if (bGo) {
422-
while (bGo) {
423-
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
424-
// _tprintf(TEXT(" %s <DIR>\n"), ffd.cFileName);
425-
} else {
426-
auto pathName = makePath(path, ffd.cFileName);
427-
if (getFileType(pathName, options) == typeImage) {
428-
gFiles.push_back(std::move(pathName));
429-
}
430-
}
431-
bGo = FindNextFile(hFind, &ffd) != 0;
432-
}
433-
// CloseHandle(hFind);
434-
}
435-
}
436-
#else
437-
DIR* dir = opendir(path);
438-
if (dir != nullptr) {
439-
bResult = true;
440-
441-
// print all the files and directories within directory
442-
while (auto ent = readdir(dir)) {
443-
std::string pathName = makePath(path, ent->d_name);
444-
if (ent->d_name[0] != '.') {
445-
// printf("reading %s => %s\n",ent->d_name,pathName.c_str());
446-
if (getFileType(pathName, options) == typeImage) {
447-
gFiles.push_back(std::move(pathName));
448-
}
382+
bool readDir(const fs::path& path, Options& options) {
383+
try {
384+
for (const auto& entry : fs::directory_iterator(path)) {
385+
auto pathName = entry.path();
386+
if (entry.is_regular_file() && getFileType(pathName, options) == typeImage) {
387+
gFiles.push_back(std::move(pathName));
449388
}
450389
}
451-
closedir(dir);
390+
return true;
391+
} catch (const fs::filesystem_error&) {
392+
return false;
452393
}
453-
#endif
454-
return bResult;
455394
}
456395

457396
inline size_t sip(std::ifstream& f, std::vector<char>& buffer, size_t len) {
@@ -463,7 +402,7 @@ inline size_t sip(std::ifstream& f, std::vector<char>& buffer, size_t len) {
463402
return len;
464403
}
465404

466-
bool readXML(const char* path, Options& options) {
405+
bool readXML(const fs::path& path, Options& options) {
467406
std::ifstream file(path);
468407
if (!file) {
469408
return false;
@@ -506,7 +445,7 @@ bool readXML(const char* path, Options& options) {
506445
return bResult;
507446
}
508447

509-
bool readImage(const char* path, Options& /* options */) {
448+
bool readImage(const fs::path& path, Options& /* options */) {
510449
using namespace Exiv2;
511450
bool bResult = false;
512451

@@ -521,7 +460,7 @@ bool readImage(const char* path, Options& /* options */) {
521460
return bResult;
522461
}
523462

524-
time_t readImageTime(const std::string& path, std::string* pS = nullptr) {
463+
time_t readImageTime(const fs::path& path, std::string* pS = nullptr) {
525464
using namespace Exiv2;
526465

527466
time_t result = 0;
@@ -556,26 +495,24 @@ bool sina(const char* s, const char** a) {
556495
const char* A = a[i];
557496
while (*A == '-')
558497
A++;
559-
bResult = stricmp(s, A) == 0;
498+
bResult = _stricmp(s, A) == 0;
560499
i++;
561500
}
562501
return bResult;
563502
}
564503

565-
int readFile(const char* path, const Options& /* options */) {
504+
int readFile(const fs::path& path, const Options& /* options */) {
566505
if (!fs::exists(path)) {
567506
return typeUnknown;
568507
}
569508

570-
const char* ext = strstr(path, ".");
571-
if (ext) {
572-
const char* docs[] = {".doc", ".txt", nullptr};
573-
const char* code[] = {".cpp", ".h", ".pl", ".py", ".pyc", nullptr};
574-
if (sina(ext, docs))
509+
for (auto doc : {".doc", ".txt"})
510+
if (path.extension() == doc)
575511
return typeDoc;
576-
if (sina(ext, code))
512+
513+
for (auto code : {".cpp", ".h", ".pl", ".py", ".pyc"})
514+
if (path.extension() == code)
577515
return typeCode;
578-
}
579516

580517
return typeFile;
581518
}
@@ -594,10 +531,7 @@ Position* searchTimeDict(TimeDict_t& td, const time_t& time, long long delta) {
594531
return result;
595532
}
596533

597-
int getFileType(std::string& path, Options& options) {
598-
return getFileType(path.c_str(), options);
599-
}
600-
int getFileType(const char* path, Options& options) {
534+
int getFileType(const fs::path& path, Options& options) {
601535
if (readXML(path, options))
602536
return typeXML;
603537
if (readDir(path, options))
@@ -664,7 +598,7 @@ int parseTZ(const char* adjust) {
664598
return (3600 * h) + (60 * m);
665599
}
666600

667-
bool mySort(const std::string& a, const std::string& b) {
601+
bool mySort(const fs::path& a, const fs::path& b) {
668602
time_t A = readImageTime(a);
669603
time_t B = readImageTime(b);
670604
return (A < B);
@@ -772,13 +706,16 @@ int main(int argc, const char* argv[]) {
772706
if (options.verbose)
773707
printf("%s %s ", arg, types[type]);
774708
if (type == typeImage) {
775-
time_t t = readImageTime(std::string(arg));
709+
time_t t = readImageTime(fs::path(arg));
776710
auto p = fs::absolute(fs::path(arg));
777-
std::string path = p.string();
778-
if (t && !path.empty()) {
711+
if (t && !p.empty()) {
779712
if (options.verbose)
780-
printf("%s %ld %s", path.c_str(), static_cast<long int>(t), asctime(localtime(&t)));
781-
gFiles.push_back(std::move(path));
713+
#ifdef _WIN32
714+
printf("%ls %ld %s", p.c_str(), static_cast<long int>(t), asctime(localtime(&t)));
715+
#else
716+
printf("%s %ld %s", p.c_str(), static_cast<long int>(t), asctime(localtime(&t)));
717+
#endif
718+
gFiles.push_back(std::move(p));
782719
}
783720
}
784721
if (type == typeUnknown) {
@@ -815,7 +752,7 @@ int main(int argc, const char* argv[]) {
815752
/*
816753
if ( options.verbose ) {
817754
printf("Time Dictionary\n");
818-
for ( TimeDict_i it = gTimeDict.begin() ; it != gTimeDict.end() ; it++ ) {
755+
for (auto it = gTimeDict.begin() ; it != gTimeDict.end() ; it++ ) {
819756
std::string sTime = getExifTime(it->first);
820757
Position* pPos = &it->second;
821758
std::string sPos = Position::toExifString(pPos->lat(),false,true)
@@ -851,9 +788,17 @@ int main(int argc, const char* argv[]) {
851788
exifData["Exif.GPSInfo.GPSTimeStamp"] = Position::toExifTimeStamp(stamp);
852789
exifData["Exif.Image.GPSTag"] = 4908;
853790

791+
#ifdef _WIN32
792+
printf("%ls %s % 2d\n", path.c_str(), pPos->toString().c_str(), pPos->delta());
793+
#else
854794
printf("%s %s % 2d\n", path.c_str(), pPos->toString().c_str(), pPos->delta());
795+
#endif
855796
} else {
797+
#ifdef _WIN32
798+
printf("%ls *** not in time dict ***\n", path.c_str());
799+
#else
856800
printf("%s *** not in time dict ***\n", path.c_str());
801+
#endif
857802
}
858803
if (!options.dryrun)
859804
image->writeMetadata();

0 commit comments

Comments
 (0)