~ubuntu-branches/ubuntu/saucy/deja-dup/saucy

« back to all changes in this revision

Viewing changes to common/RecursiveOp.vala

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2012-06-05 13:45:39 UTC
  • mfrom: (1.1.43)
  • Revision ID: package-import@ubuntu.com-20120605134539-l35tewhkjfq4qp6e
Tags: 23.2-0ubuntu1
* New upstream release
* debian/control:
  - Add libpeas-dev to Build-Depends
  - Update valac and libglib2.0-dev versions
  - Bump debhelper version to 9
* debian/compat:
  - Bump to 9
* debian/rules:
  - Don't install new .la and .a files from upstream
* debian/patches/allow-resuming-encrypted-backup.patch:
  - Dropped, included upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
2
 
/*
3
 
    This file is part of Déjà Dup.
4
 
    For copyright information, see AUTHORS.
5
 
 
6
 
    Déjà Dup is free software: you can redistribute it and/or modify
7
 
    it under the terms of the GNU General Public License as published by
8
 
    the Free Software Foundation, either version 3 of the License, or
9
 
    (at your option) any later version.
10
 
 
11
 
    Déjà Dup is distributed in the hope that it will be useful,
12
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
    GNU General Public License for more details.
15
 
 
16
 
    You should have received a copy of the GNU General Public License
17
 
    along with Déjà Dup.  If not, see <http://www.gnu.org/licenses/>.
18
 
*/
19
 
 
20
 
using GLib;
21
 
 
22
 
namespace DejaDup {
23
 
 
24
 
internal abstract class RecursiveOp : Object
25
 
{
26
 
  public signal void done();
27
 
  public signal void raise_error(File src, File dst, string errstr);
28
 
  
29
 
  public File src {get; construct;}
30
 
  public File dst {get; construct;}
31
 
  
32
 
  protected FileType src_type;
33
 
  protected FileType dst_type;
34
 
  protected virtual void handle_file() {} // src is file
35
 
  protected virtual void handle_dir() {} // src is dir
36
 
  protected virtual void finish_dir() {} // src is dir we are done with
37
 
  protected abstract RecursiveOp clone_for_info(FileInfo info);
38
 
  
39
 
  int refs;
40
 
  
41
 
  bool idle_action()
42
 
  {
43
 
    start_async();
44
 
    return false;
45
 
  }
46
 
  
47
 
  public void start()
48
 
  {
49
 
    Idle.add(idle_action);
50
 
    var loop = new MainLoop(null, false);
51
 
    done.connect((m) => {loop.quit();});
52
 
    loop.run();
53
 
  }
54
 
  
55
 
  public void start_async()
56
 
  {
57
 
    if (src != null)
58
 
      src_type = src.query_file_type(FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
59
 
    if (dst != null)
60
 
      dst_type = dst.query_file_type(FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
61
 
    
62
 
    switch (src_type) {
63
 
    case FileType.DIRECTORY:
64
 
      do_dir();
65
 
      break;
66
 
    default:
67
 
      handle_file();
68
 
      break;
69
 
    }
70
 
    
71
 
    check_ref();
72
 
  }
73
 
 
74
 
  void recurse_on_info(FileInfo info)
75
 
  {
76
 
    add_ref();
77
 
    var op = clone_for_info(info);
78
 
    op.ref();
79
 
    op.done.connect((m) => {remove_ref(); m.unref();});
80
 
    op.raise_error.connect((m, s, d, e) => {raise_error(s, d, e);}); // percolate up
81
 
    op.start_async();
82
 
  }
83
 
 
84
 
  static const int NUM_ENUMERATED = 16;
85
 
  async void do_dir()
86
 
  {
87
 
    handle_dir();
88
 
 
89
 
    // Now descend
90
 
    add_ref();
91
 
    try {
92
 
      var enumerator = yield src.enumerate_children_async(
93
 
                         FILE_ATTRIBUTE_STANDARD_NAME,
94
 
                         FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
95
 
                         Priority.DEFAULT, null);
96
 
 
97
 
      while (true) {
98
 
        var infos = yield enumerator.next_files_async(NUM_ENUMERATED,
99
 
                                                      Priority.DEFAULT, null);
100
 
 
101
 
        foreach (FileInfo info in infos)
102
 
          recurse_on_info(info);
103
 
 
104
 
        if (infos.length() != NUM_ENUMERATED) {
105
 
          remove_ref(); // parent dir itself
106
 
          break;
107
 
        }
108
 
      }
109
 
    }
110
 
    catch (Error e) {
111
 
      raise_error(src, dst, e.message);
112
 
      remove_ref(); // parent dir itself
113
 
    }
114
 
  }
115
 
  
116
 
  void add_ref() {
117
 
    ++refs;
118
 
  }
119
 
  
120
 
  void remove_ref() {
121
 
    --refs;
122
 
    check_ref();
123
 
  }
124
 
  
125
 
  void check_ref() {
126
 
    if (refs == 0) {
127
 
      if (src_type == FileType.DIRECTORY)
128
 
        finish_dir();
129
 
      done();
130
 
    }
131
 
  }
132
 
}
133
 
 
134
 
} // end namespace
135