1212
1313namespace 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
3219namespace {
3320// prototypes
3421class 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
3824std::string getExifTime (time_t t);
3925time_t parseTime (const char *, bool bAdjust = false );
@@ -93,11 +79,10 @@ class Position;
9379
9480// globals
9581using 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>;
9883const char * gDeg = nullptr ; // string "°" or "deg"
9984TimeDict_t gTimeDict ;
100- strings_t gFiles ;
85+ paths_t gFiles ;
10186
10287// Position (from gpx file)
10388class 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
457396inline 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