OSDN Git Service

Change symbolic links to regular files.
[islib/islib.git] / binary_compare.cpp
1 //
2 // Inclusion of standard header file
3 //
4 #include <fstream>
5 #include <stdexcept>
6
7 //
8 // Inclusion of system header file
9 //
10 #include <sys/stat.h>
11 #include <sys/types.h>
12
13 //
14 // Inclusion of library header file
15 //
16 #include <boost/filesystem/fstream.hpp>
17 #include <boost/filesystem/operations.hpp>
18 #include <boost/filesystem/path.hpp>
19
20 //
21 // Inclusion of local header file
22 //
23 #include "binary_compare.hpp"
24 #include "islibfunc.hpp"
25
26 namespace islib
27   {
28     //
29     // Definition of function
30     //
31     // Return value: 0:   file path 1 and file path 2 equal to each other.
32     //               < 0: file path 1 is less than file path 2.
33     //               > 0: file path 1 is greater than file path 2.
34     //
35     int
36     binary_compare
37       (
38         boost::filesystem::path const &file_path_1,
39         boost::filesystem::path const &file_path_2
40       )
41       {
42         class local
43           {
44           public:
45             local
46               (
47                 boost::filesystem::path const &file_path_1_,
48                 boost::filesystem::path const &file_path_2_
49               )
50               {
51                 throw_if ( std::invalid_argument ( "islib::binary_compare: file_path_1_.empty ()" ), file_path_1_.empty () );
52                 throw_if ( std::invalid_argument ( "islib::binary_compare: file_path_2_.empty ()" ), file_path_2_.empty () );
53                 throw_if ( std::invalid_argument ( "islib::binary_compare: !boost::filesystem::is_regular ( file_path_1_ )" ), !boost::filesystem::is_regular ( file_path_1_ ) );
54                 throw_if ( std::invalid_argument ( "islib::binary_compare: !boost::filesystem::is_regular ( file_path_2_ )" ), !boost::filesystem::is_regular ( file_path_2_ ) );
55               }
56
57             ~local
58               ()
59               throw
60                 ()
61               {
62               }
63           }
64         a_local ( file_path_1, file_path_2 );
65
66         if ( file_path_1 == file_path_2 )
67           return 0;
68
69         struct stat file_status_1;
70         struct stat file_status_2;
71
72         islib::stat_ ( file_path_1, &file_status_1 );
73         islib::stat_ ( file_path_2, &file_status_2 );
74
75         if ( file_status_1.st_dev == file_status_2.st_dev && file_status_1.st_ino == file_status_2.st_ino )
76           return 0;
77
78         if ( file_status_1.st_size != file_status_2.st_size )
79           return static_cast < int > ( file_status_1.st_size ) - static_cast < int > ( file_status_2.st_size );
80
81         boost::filesystem::ifstream file_stream_1 ( file_path_1 );
82         boost::filesystem::ifstream file_stream_2 ( file_path_2 );
83         off_t number_of_read_bytes = 0;
84
85         while ( true )
86           {
87             if ( number_of_read_bytes == file_status_1.st_size )
88               break;
89
90             throw_if ( std::runtime_error ( "islib::binary_compare: !file_stream_1 || !file_stream_2" ), !file_stream_1 || !file_stream_2 );
91
92             char character_1;
93             char character_2;
94
95             file_stream_1.get ( character_1 );
96             file_stream_2.get ( character_2 );
97
98             if ( character_1 != character_2 )
99               return static_cast < int > ( static_cast < unsigned int > ( character_1 ) ) - static_cast < int > ( static_cast < unsigned int > ( character_2 ) );
100
101             ++number_of_read_bytes;
102           }
103
104         return 0;
105       }
106   }
107
108 //
109 // End of file
110 //