]> git.lyx.org Git - lyx.git/blob - src/support/lyxsum.C
John's Layout Tabular UI improvements and Martins fixes to clearing the
[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
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 #ifdef WITH_WARNINGS
23 #warning lyx::sum() using mmap (lightning fast)
24 #endif
25
26 // Make sure we get modern version of mmap and friends with void*,
27 // not `compatibility' version with caddr_t.
28 #define _POSIX_C_SOURCE 199506L
29
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <sys/mman.h>
35
36 unsigned long lyx::sum(string const & file)
37 {
38         int fd = open(file.c_str(), O_RDONLY);
39         if(!fd)
40                 return 0;
41         
42         struct stat info;
43         fstat(fd, &info);
44         
45         void * mm = mmap(0, info.st_size, PROT_READ,
46                          MAP_PRIVATE, fd, 0);
47         // Some platforms have the wrong type for MAP_FAILED (compaq cxx).
48         if (mm == reinterpret_cast<void*>(MAP_FAILED)) {
49                 close(fd);
50                 return 0;
51         }
52         
53         char * beg = static_cast<char*>(mm);
54         char * end = beg + info.st_size;
55         
56         boost::crc_32_type crc;
57         crc.process_block(beg, end);
58         unsigned long result = crc.checksum();
59         
60         munmap(mm, info.st_size);
61         close(fd);
62         
63         return result;
64 }
65 #else // No mmap
66
67 #include <fstream>
68 #include <iterator>
69
70 namespace {
71
72 template<typename InputIterator>
73 inline
74 unsigned long do_crc(InputIterator first, InputIterator last)
75 {
76         boost::crc_32_type crc;
77         crc = std::for_each(first, last, crc);
78         return crc.checksum();
79 }
80
81 } // namespace
82
83 #if HAVE_DECL_ISTREAMBUF_ITERATOR
84 #ifdef WITH_WARNINGS
85 #warning lyx::sum() using istreambuf_iterator (fast)
86 #endif
87 unsigned long lyx::sum(string const & file)
88 {
89         std::ifstream ifs(file.c_str());
90         if (!ifs) return 0;
91         
92         std::istreambuf_iterator<char> beg(ifs);
93         std::istreambuf_iterator<char> end;
94         
95         return do_crc(beg,end);
96 }
97 #else
98 #ifdef WITH_WARNINGS
99 #warning lyx::sum() using istream_iterator (slow as a snail)
100 #endif
101 unsigned long lyx::sum(string const & file)
102 {
103         std::ifstream ifs(file.c_str());
104         if (!ifs) return 0;
105         
106         ifs.unsetf(std::ios::skipws);
107         std::istream_iterator<char> beg(ifs);
108         std::istream_iterator<char> end;
109         
110         return do_crc(beg,end);
111 }
112 #endif
113 #endif // mmap