Bump the revision number
[backups/.git] / filedata.cpp
1 #include <string>
2 #include <vector>
3 #include <iostream>
4
5 #include "filedata.hpp"
6
7 using namespace std;
8
9 vector<string> split( const string &line, char c, int limit = -1 ) {
10   string::size_type start = 0, end = 0;
11
12   vector<string> out;
13   while( 0 != limit-- && end != line.size() ) {
14     if( 0 == limit ) {
15       end = line.size();
16     } else {
17       end = line.find( c, start );
18       if( end == string::npos ) {
19         end = line.size();
20       }
21     }
22     out.push_back( line.substr( start, end-start ) );
23     start = end + 1;
24   }
25   return out;
26 }
27
28 const FileData::LastBackupCmp FileData::lastbackupcmp = FileData::LastBackupCmp();
29 const FileData::SizeCmp       FileData::sizecmp       = FileData::SizeCmp();
30 const FileData::NameCmp       FileData::namecmp       = FileData::NameCmp();
31
32 ostream &operator<<( ostream &o, const FileData *d) {
33   return operator<<( o, *d );
34 }
35
36 ostream &operator<<( ostream &o, const FileData &d ) {
37   o << d.getFileType()       << ' ';
38   o << d.getPermissions()    << ' ';
39   o << d.getUserName()       << ' ';
40   o << d.getGroupName()      << ' ';
41   o << d.getFileSize()       << ' ';
42   o << d.getModifiedDate()   << ' ';
43   o << d.getLastBackupDate() << ' ';
44   o << d.getFileName()       << '\0';
45
46   return o;
47 }
48
49 istream &operator>>( istream &i, FileData *d ) {
50   return operator>>( i, *d );
51 }
52
53 istream &operator>>( istream &i, FileData &d ) {
54   string file_string;
55
56   int c;
57   // Todo, don't use char_traits<char> directly here
58   for( c = i.get(); 0 != c && char_traits<char>::eof() != c; c = i.get() ) {
59     file_string.push_back( c );
60   }
61   if( char_traits<char>::eof() == c ) {
62     i.setstate( ios_base::eofbit );
63   }
64
65   if( 0 != file_string.size() ) {
66     // Example entry
67     // type perms user group size datemodified name (8 total)
68     // f 0600 cnb cnb 424 20051015205340 0 ./.git/index
69     vector<string> vals = split( file_string, ' ', 8 );
70     d.setFileType(       vals[0][0] );
71     d.setPermissions(    vals[1] );
72     d.setUserName(       vals[2] );
73     d.setGroupName(      vals[3] );
74     d.setFileSize(       atoll( vals[4].c_str() ) );
75     d.setModifiedDate(   atoll( vals[5].c_str() ) );
76     d.setLastBackupDate( atoll( vals[6].c_str() ) );
77     d.setFileName(       vals[7] );
78   }
79
80   return i;
81 }
82
83 bool needs_backup( const FileData *before, const FileData *after ) {
84   assert( before->getFileName() == after->getFileName() );
85
86   if( after->getLastBackupDate()  <  after->getModifiedDate() ) return true;
87
88   if( before->getFileType()       != after->getFileType()     ) return true;
89   if( before->getPermissions()    != after->getPermissions()  ) return true;
90   if( before->getUserName()       != after->getUserName()     ) return true;
91   if( before->getGroupName()      != after->getGroupName()    ) return true;
92   if( before->getFileSize()       != after->getFileSize()     ) return true;
93
94   return false;
95 }