]> git.decadent.org.uk Git - dak.git/blob - tools/dsync-0.0/libdsync/contrib/slidingwindow.cc
utils.py
[dak.git] / tools / dsync-0.0 / libdsync / contrib / slidingwindow.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description                                                          /*{{{*/
3 // $Id: slidingwindow.cc,v 1.1 1999/11/05 05:47:06 jgg Exp $
4 /* ######################################################################
5
6    Sliding Window - Implements a sliding buffer over a file. 
7
8    It would be possible to implement an alternate version if 
9    _POSIX_MAPPED_FILES is not defined.. 
10    
11    ##################################################################### */
12                                                                         /*}}}*/
13 // Include files                                                        /*{{{*/
14 #ifdef __GNUG__
15 #pragma implementation "dsync/slidingwindow.h"
16 #endif
17
18 #include <dsync/slidingwindow.h>
19 #include <dsync/error.h>
20
21 #include <sys/mman.h>
22 #include <unistd.h>
23                                                                         /*}}}*/
24
25 // SlidingWindow::SlidingWindow - Constructor                           /*{{{*/
26 // ---------------------------------------------------------------------
27 /* */
28 SlidingWindow::SlidingWindow(FileFd &Fd,unsigned long MnSize) : Buffer(0),
29                               MinSize(MnSize), Fd(Fd)
30 {       
31    Offset = 0;
32    Left = 0;
33    PageSize = sysconf(_SC_PAGESIZE);
34       
35    if (MinSize < 1024*1024)
36       MinSize = 1024*1024;
37    MinSize = Align(MinSize);   
38 }
39                                                                         /*}}}*/
40 // SlidingWindow::~SlidingWindow - Destructor                           /*{{{*/
41 // ---------------------------------------------------------------------
42 /* Just unmap the mapping */
43 SlidingWindow::~SlidingWindow()
44 {
45    if (Buffer != 0)
46    {
47       if (munmap((char *)Buffer,Size) != 0)
48          _error->Warning("Unable to munmap");
49    }   
50 }
51                                                                         /*}}}*/
52 // SlidingWindow::Extend - Make Start - End longer                                                                      /*{{{*/
53 // ---------------------------------------------------------------------
54 /* Start == End when the file is exhausted, false is an IO error. */
55 bool SlidingWindow::Extend(unsigned char *&Start,unsigned char *&End)
56 {
57    unsigned long Remainder = 0;
58    
59    // Restart
60    if (Start == 0 || Buffer == 0)
61    {
62       Offset = 0;
63       Left = Fd.Size();
64    }
65    else
66    {
67       if (AlignDn((unsigned long)(Start - Buffer)) == 0)
68          return _error->Error("SlidingWindow::Extend called with too small a 'Start'");
69
70       // Scanning is finished.
71       if (Left < (off_t)Size)
72       {
73          End = Start;
74          return true;
75       }
76       
77       Offset += AlignDn((unsigned long)(Start - Buffer));
78       Left -= AlignDn((unsigned long)(Start - Buffer));
79       Remainder = (Start - Buffer) % PageSize;      
80    }
81
82    // Release the old region
83    if (Buffer != 0)
84    {
85       if (munmap((char *)Buffer,Size) != 0)
86          return _error->Errno("munmap","Unable to munmap");
87       Buffer = 0;
88    }
89
90    // Maximize the amount that can be mapped
91    if (Left < (off_t)MinSize)
92       Size = Align(Left);
93    else
94       Size = MinSize;
95    
96    // Map it
97    Buffer = (unsigned char *)mmap(0,Size,PROT_READ,MAP_PRIVATE,Fd.Fd(),Offset);
98    if (Buffer == (unsigned char *)-1)
99       return _error->Errno("mmap","Couldn't make mmap %lu->%lu bytes",(unsigned long)Offset,
100                            Size);
101    
102    // Reposition
103    if (Left < (off_t)Size)
104       End = Buffer + Left;
105    else
106       End = Buffer + Size;
107    Start = Buffer + Remainder;
108    return true;
109 }
110                                                                         /*}}}*/