]> git.lyx.org Git - lyx.git/blob - src/support/lyxsum.C
to much stuff for my liking...
[lyx.git] / src / support / lyxsum.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *           Copyright 2001 The LyX Team.
6  *
7  * ======================================================
8  */
9
10
11 #include <config.h>
12
13 #include <algorithm>
14 #include <boost/crc.hpp>
15
16 #include "support/lyxlib.h"
17 #include "debug.h"
18
19 // Various implementations of lyx::sum(), depending on what methods
20 // are available. Order is faster to slowest.
21 #if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
22
23 // Make sure we get modern version of mmap and friends with void*,
24 // not `compatibility' version with caddr_t.
25 #define _POSIX_C_SOURCE 199506L
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31 #include <sys/mman.h>
32
33 using std::ifstream;
34 using std::endl;
35 using std::for_each;
36 using std::istreambuf_iterator;
37 using std::istream_iterator;
38 using std::ios;
39
40
41 unsigned long lyx::sum(string const & file)
42 {
43         lyxerr[Debug::FILES] << "lyx::sum() using mmap (lightning fast)"
44                              << endl;
45         
46         int fd = open(file.c_str(), O_RDONLY);
47         if (!fd)
48                 return 0;
49         
50         struct stat info;
51         fstat(fd, &info);
52         
53         void * mm = mmap(0, info.st_size, PROT_READ,
54                          MAP_PRIVATE, fd, 0);
55         // Some platforms have the wrong type for MAP_FAILED (compaq cxx).
56         if (mm == reinterpret_cast<void*>(MAP_FAILED)) {
57                 close(fd);
58                 return 0;
59         }
60         
61         char * beg = static_cast<char*>(mm);
62         char * end = beg + info.st_size;
63         
64         boost::crc_32_type crc;
65         crc.process_block(beg, end);
66         unsigned long result = crc.checksum();
67         
68         munmap(mm, info.st_size);
69         close(fd);
70         
71         return result;
72 }
73 #else // No mmap
74
75 #include <fstream>
76 #include <iterator>
77
78 namespace {
79
80 template<typename InputIterator>
81 inline
82 unsigned long do_crc(InputIterator first, InputIterator last)
83 {
84         boost::crc_32_type crc;
85         crc = for_each(first, last, crc);
86         return crc.checksum();
87 }
88
89 } // namespace
90
91 #if HAVE_DECL_ISTREAMBUF_ITERATOR
92 unsigned long lyx::sum(string const & file)
93 {
94         lyxerr[Debug::FILES] << "lyx::sum() using istreambuf_iterator (fast)"
95                              << endl;
96
97         ifstream ifs(file.c_str());
98         if (!ifs) return 0;
99         
100         istreambuf_iterator<char> beg(ifs);
101         istreambuf_iterator<char> end;
102         
103         return do_crc(beg,end);
104 }
105 #else
106 unsigned long lyx::sum(string const & file)
107 {
108         lyxerr[Debug::FILES]
109                 << "lyx::sum() using istream_iterator (slow as a snail)"
110                 << endl;
111         
112         ifstream ifs(file.c_str());
113         if (!ifs) return 0;
114         
115         ifs.unsetf(ios::skipws);
116         istream_iterator<char> beg(ifs);
117         istream_iterator<char> end;
118         
119         return do_crc(beg,end);
120 }
121 #endif
122 #endif // mmap