c2c39ce5e270b682ffc14e1c9c842ee79a28015f
[debian/amanda] / perl / Amanda / Xfer.pm
1 # This file was automatically generated by SWIG (http://www.swig.org).
2 # Version 1.3.39
3 #
4 # Do not make changes to this file unless you know what you are doing--modify
5 # the SWIG interface file instead.
6
7 package Amanda::Xfer;
8 use base qw(Exporter);
9 use base qw(DynaLoader);
10 require Amanda::MainLoop;
11 require Amanda::Device;
12 require Amanda::Types;
13 package Amanda::Xferc;
14 bootstrap Amanda::Xfer;
15 package Amanda::Xfer;
16 @EXPORT = qw();
17
18 # ---------- BASE METHODS -------------
19
20 package Amanda::Xfer;
21
22 sub TIEHASH {
23     my ($classname,$obj) = @_;
24     return bless $obj, $classname;
25 }
26
27 sub CLEAR { }
28
29 sub FIRSTKEY { }
30
31 sub NEXTKEY { }
32
33 sub FETCH {
34     my ($self,$field) = @_;
35     my $member_func = "swig_${field}_get";
36     $self->$member_func();
37 }
38
39 sub STORE {
40     my ($self,$field,$newval) = @_;
41     my $member_func = "swig_${field}_set";
42     $self->$member_func($newval);
43 }
44
45 sub this {
46     my $ptr = shift;
47     return tied(%$ptr);
48 }
49
50
51 # ------- FUNCTION WRAPPERS --------
52
53 package Amanda::Xfer;
54
55 *xfer_new = *Amanda::Xferc::xfer_new;
56 *xfer_unref = *Amanda::Xferc::xfer_unref;
57 *xfer_get_status = *Amanda::Xferc::xfer_get_status;
58 *xfer_repr = *Amanda::Xferc::xfer_repr;
59 *xfer_start = *Amanda::Xferc::xfer_start;
60 *xfer_cancel = *Amanda::Xferc::xfer_cancel;
61 *xfer_element_unref = *Amanda::Xferc::xfer_element_unref;
62 *xfer_element_repr = *Amanda::Xferc::xfer_element_repr;
63 *xfer_source_device = *Amanda::Xferc::xfer_source_device;
64 *xfer_source_random = *Amanda::Xferc::xfer_source_random;
65 *xfer_source_pattern = *Amanda::Xferc::xfer_source_pattern;
66 *xfer_source_fd = *Amanda::Xferc::xfer_source_fd;
67 *xfer_filter_xor = *Amanda::Xferc::xfer_filter_xor;
68 *xfer_dest_device = *Amanda::Xferc::xfer_dest_device;
69 *xfer_dest_null = *Amanda::Xferc::xfer_dest_null;
70 *xfer_dest_fd = *Amanda::Xferc::xfer_dest_fd;
71 *xfer_get_amglue_source = *Amanda::Xferc::xfer_get_amglue_source;
72
73 # ------- VARIABLE STUBS --------
74
75 package Amanda::Xfer;
76
77 *XFER_INIT = *Amanda::Xferc::XFER_INIT;
78 *XFER_START = *Amanda::Xferc::XFER_START;
79 *XFER_RUNNING = *Amanda::Xferc::XFER_RUNNING;
80 *XFER_DONE = *Amanda::Xferc::XFER_DONE;
81 *XMSG_INFO = *Amanda::Xferc::XMSG_INFO;
82 *XMSG_ERROR = *Amanda::Xferc::XMSG_ERROR;
83 *XMSG_DONE = *Amanda::Xferc::XMSG_DONE;
84 *XMSG_CANCEL = *Amanda::Xferc::XMSG_CANCEL;
85
86 @EXPORT_OK = ();
87 %EXPORT_TAGS = ();
88
89 =head1 NAME
90
91 Amanda::Xfer - the transfer architecture
92
93 =head1 SYNOPSIS
94
95   use Amanda::MainLoop;
96   use Amanda::Xfer qw( :constants );
97   use POSIX;
98
99   my $infd = POSIX::open("input", POSIX::O_RDONLY, 0);
100   my $outfd = POSIX::open("output", POSIX::O_CREAT|POSIX::O_WRONLY, 0640);
101   my $xfer = Amanda::Xfer->new([
102     Amanda::Xfer::Source::Fd->new($infd),
103     Amanda::Xfer::Dest::Fd->new($outfd)
104   ]);
105   $xfer->get_source()->set_callback(sub {
106       my ($src, $xmsg, $xfer) = @_;
107       print "Message from $xfer: $xmsg\n"; # use stringify operations
108       if ($xfer->get_status() == $XFER_DONE) {
109           $src->remove();
110           Amanda::MainLoop::quit();
111       }
112   });
113   $xfer->start();
114   Amanda::MainLoop::run();
115   
116 See L<http://wiki.zmanda.com/index.php/XFA> for background on the transfer
117 architecture.
118
119 =head1 API STATUS
120
121 Fluid.
122
123 =head1 Amanda::Xfer Objects
124
125 A new transfer is created with C<< Amanda::Xfer->new() >>, which takes an arrayref
126 giving the transfer elements which should compose the transfer.
127
128 The resulting object has the following methods:
129
130 =over
131
132 =item get_source()
133
134 Get the L<Amanda::MainLoop> event source through which messages will be
135 delivered for this transfer.  Use its C<set_callback> method to connect a perl
136 sub for processing events.  You I<must> C<release> the source when the
137 transfer is complete!
138
139 The callback from this event source receives three arguments: the event source,
140 the message, and a reference to the controlling transfer.  See the description of
141 C<Amanda::Xfer::Msg>, below, for details.
142
143 =item start()
144
145 Start this transfer.  Processing takes place asynchronously, and messages will
146 begin queueing up immediately.
147
148 =item cancel()
149
150 Stop transferring data.  The transfer will send an C<XMSG_CANCEL>, "drain" any
151 buffered data as best it can, and then complete normally with an C<XMSG_DONE>.
152
153 =item get_status()
154
155 Get the transfer's status.  The result will be one of C<$XFER_INIT>,
156 C<$XFER_START>, C<$XFER_RUNNING>, or C<$XFER_DONE>.  These symbols are
157 available for import with the tag C<:constants>.
158
159 =item repr()
160
161 Return a string representation of this transfer, suitable for use in debugging
162 messages.  This method is automatically invoked when a transfer is interpolated
163 into a string:
164   print "Starting $xfer\n";
165
166 =back
167
168 =head1 Amanda::Xfer::Element objects
169
170 The individual transfer elements that compose a transfer are instances of
171 subclasses of Amanda::Xfer::Element.  All such objects have a C<repr()> method,
172 similar to that for transfers, and support a similar kind of string
173 interpolation.
174
175 Note that the names of these classes contain the words "Source", "Filter", and
176 "Dest".  This is merely suggestive of their intended purpose -- there are no
177 such abstract classes.
178
179 =head2 Transfer Sources
180
181 =head3 Amanda::Xfer::Source::Device
182
183   Amanda::Xfer::Source::Device->new($device);
184
185 This source reads data from a device.  The device should already be queued up
186 for reading (C<$device->seek_file(..)>).  The element will read until the end
187 of the device file.
188
189 =head3 Amanda::Xfer::Source::Fd
190
191   Amanda::Xfer::Source::Fd->new(fileno($fh));
192
193 This source reads data from a file descriptor.  It reads until EOF, but does
194 not close the descriptor.  Be careful not to let Perl close the file for you!
195
196 =head3 Amanda::Xfer::Source::Random
197
198   Amanda::Xfer::Source::Random->new($length, $seed);
199
200 This source provides I<length> bytes of random data (or an unlimited amount
201 of data if I<length> is zero).  C<$seed> is the seed used
202 to generate the random numbers; this seed can be used in a destination to
203 check for correct output.
204
205 =head3 Amanda::Xfer::Source::Pattern
206
207   Amanda::Xfer::Source::Pattern->new($length, $pattern);
208
209 This source provides I<length> bytes containing copies of
210 I<pattern>. If I<length> is zero, the source provides an unlimited
211 number of bytes.
212
213 =head2 Transfer Filters
214
215 =head3 Amanda::Xfer::Filter:Xor
216
217   Amanda::Xfer::Filter::Xor->new($key);
218
219 This filter applies a bytewise XOR operation to the data flowing through it.
220
221 =head2 Transfer Destinations
222
223 =head3 Amanda::Xfer::Dest::Device
224
225   Amanda::Xfer::Dest::Device->new($device, $max_memory);
226
227 This source writes data to a device.  The device should already be queued up
228 for writing (C<$device->start_file(..)>).  No more than C<$max_memory> will be
229 used for buffers.  Use zero for the default buffer size.  On completion of the
230 transfer, the file will be finished.
231
232 =head3 Amanda::Xfer::Dest::Fd
233
234   Amanda::Xfer::Dest::Fd->new(fileno($fh));
235
236 This destination writes data to a file descriptor.  The file is not closed
237 after the transfer is completed.  Be careful not to let Perl close the file
238 for you!
239
240 =head3 Amanda::Xfer::Dest::Null
241
242   Amanda::Xfer::Dest::Null->new($seed);
243
244 This destination discards the data it receives.  If C<$seed> is nonzero, then
245 the element will validate that it receives the data that
246 C<Amanda::Xfer::Source::Random> produced with the same seed.  No validation is
247 performed if C<$seed> is zero.
248
249 =head1 Amanda::Xfer::Msg objects
250
251 Messages are simple hashrefs, with a few convenience methods.  Like transfers,
252 they have a C<repr()> method that formats the message nicely, and is available
253 through string interpolation:
254   print "Received message $msg\n";
255
256 Every message has the following keys:
257
258 =over
259
260 =item type
261
262 The message type -- one of the C<xmsg_type> constants available from the import
263 tag C<:constants>.
264
265 =item elt
266
267 The transfer element that sent the message.
268
269 =item version
270
271 The version of the message.  This is used to support extensibility of the protocol.
272
273 =back
274
275 The canonical description of the message types and keys is in C<xfer-src/xmsg.h>, and is
276 not duplicated here.
277
278 =cut
279
280 push @EXPORT_OK, qw(xfer_status_to_string);
281 push @{$EXPORT_TAGS{"xfer_status"}}, qw(xfer_status_to_string);
282
283 my %_xfer_status_VALUES;
284 #Convert an enum value to a single string
285 sub xfer_status_to_string {
286     my ($enumval) = @_;
287
288     for my $k (keys %_xfer_status_VALUES) {
289         my $v = $_xfer_status_VALUES{$k};
290
291         #is this a matching flag?
292         if ($enumval == $v) {
293             return $k;
294         }
295     }
296
297 #default, just return the number
298     return $enumval;
299 }
300
301 push @EXPORT_OK, qw($XFER_INIT);
302 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_INIT);
303
304 $_xfer_status_VALUES{"XFER_INIT"} = $XFER_INIT;
305
306 push @EXPORT_OK, qw($XFER_START);
307 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_START);
308
309 $_xfer_status_VALUES{"XFER_START"} = $XFER_START;
310
311 push @EXPORT_OK, qw($XFER_RUNNING);
312 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_RUNNING);
313
314 $_xfer_status_VALUES{"XFER_RUNNING"} = $XFER_RUNNING;
315
316 push @EXPORT_OK, qw($XFER_DONE);
317 push @{$EXPORT_TAGS{"xfer_status"}}, qw($XFER_DONE);
318
319 $_xfer_status_VALUES{"XFER_DONE"} = $XFER_DONE;
320
321 #copy symbols in xfer_status to constants
322 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"xfer_status"}};
323
324 push @EXPORT_OK, qw(xmsg_type_to_string);
325 push @{$EXPORT_TAGS{"xmsg_type"}}, qw(xmsg_type_to_string);
326
327 my %_xmsg_type_VALUES;
328 #Convert an enum value to a single string
329 sub xmsg_type_to_string {
330     my ($enumval) = @_;
331
332     for my $k (keys %_xmsg_type_VALUES) {
333         my $v = $_xmsg_type_VALUES{$k};
334
335         #is this a matching flag?
336         if ($enumval == $v) {
337             return $k;
338         }
339     }
340
341 #default, just return the number
342     return $enumval;
343 }
344
345 push @EXPORT_OK, qw($XMSG_INFO);
346 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_INFO);
347
348 $_xmsg_type_VALUES{"XMSG_INFO"} = $XMSG_INFO;
349
350 push @EXPORT_OK, qw($XMSG_ERROR);
351 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_ERROR);
352
353 $_xmsg_type_VALUES{"XMSG_ERROR"} = $XMSG_ERROR;
354
355 push @EXPORT_OK, qw($XMSG_DONE);
356 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_DONE);
357
358 $_xmsg_type_VALUES{"XMSG_DONE"} = $XMSG_DONE;
359
360 push @EXPORT_OK, qw($XMSG_CANCEL);
361 push @{$EXPORT_TAGS{"xmsg_type"}}, qw($XMSG_CANCEL);
362
363 $_xmsg_type_VALUES{"XMSG_CANCEL"} = $XMSG_CANCEL;
364
365 #copy symbols in xmsg_type to constants
366 push @{$EXPORT_TAGS{"constants"}},  @{$EXPORT_TAGS{"xmsg_type"}};
367
368 package Amanda::Xfer::Xfer;
369
370 sub new { 
371     my $pkg = shift;
372
373
374     Amanda::Xfer::xfer_new(@_);
375 }
376 *DESTROY = *Amanda::Xfer::xfer_unref;
377 use overload '""' => sub { $_[0]->repr(); };
378 *repr = *Amanda::Xfer::xfer_repr;
379 *get_status = *Amanda::Xfer::xfer_get_status;
380 *get_source = *Amanda::Xfer::xfer_get_amglue_source;
381 *start = *Amanda::Xfer::xfer_start;
382 *cancel = *Amanda::Xfer::xfer_cancel;
383
384 package Amanda::Xfer::Element;
385 *DESTROY = *Amanda::Xfer::xfer_element_unref;
386 use overload '""' => sub { $_[0]->repr(); };
387 *repr = *Amanda::Xfer::xfer_element_repr;
388
389 package Amanda::Xfer::Element::Glue;
390
391 use vars qw(@ISA);
392 @ISA = qw( Amanda::Xfer::Element );
393
394 package Amanda::Xfer::Source::Device;
395
396 use vars qw(@ISA);
397 @ISA = qw( Amanda::Xfer::Element );
398
399 sub new { 
400     my $pkg = shift;
401
402
403     Amanda::Xfer::xfer_source_device(@_);
404 }
405
406 package Amanda::Xfer::Source::Fd;
407
408 use vars qw(@ISA);
409 @ISA = qw( Amanda::Xfer::Element );
410
411 sub new { 
412     my $pkg = shift;
413
414
415     Amanda::Xfer::xfer_source_fd(@_);
416 }
417
418 package Amanda::Xfer::Source::Random;
419
420 use vars qw(@ISA);
421 @ISA = qw( Amanda::Xfer::Element );
422
423 sub new { 
424     my $pkg = shift;
425
426
427     Amanda::Xfer::xfer_source_random(@_);
428 }
429
430 package Amanda::Xfer::Source::Pattern;
431
432 use vars qw(@ISA);
433 @ISA = qw( Amanda::Xfer::Element );
434
435 sub new { 
436     my $pkg = shift;
437
438
439     Amanda::Xfer::xfer_source_pattern(@_);
440 }
441
442 package Amanda::Xfer::Filter::Xor;
443
444 use vars qw(@ISA);
445 @ISA = qw( Amanda::Xfer::Element );
446
447 sub new { 
448     my $pkg = shift;
449
450
451     Amanda::Xfer::xfer_filter_xor(@_);
452 }
453
454 package Amanda::Xfer::Dest::Device;
455
456 use vars qw(@ISA);
457 @ISA = qw( Amanda::Xfer::Element );
458
459 sub new { 
460     my $pkg = shift;
461
462
463     Amanda::Xfer::xfer_dest_device(@_);
464 }
465
466 package Amanda::Xfer::Dest::Fd;
467
468 use vars qw(@ISA);
469 @ISA = qw( Amanda::Xfer::Element );
470
471 sub new { 
472     my $pkg = shift;
473
474
475     Amanda::Xfer::xfer_dest_fd(@_);
476 }
477
478 package Amanda::Xfer::Dest::Null;
479
480 use vars qw(@ISA);
481 @ISA = qw( Amanda::Xfer::Element );
482
483 sub new { 
484     my $pkg = shift;
485
486
487     Amanda::Xfer::xfer_dest_null(@_);
488 }
489
490 package Amanda::Xfer::Msg;
491
492 use Data::Dumper;
493 use overload '""' => sub { $_[0]->repr(); };
494
495 sub repr {
496     my ($self) = @_;
497     local $Data::Dumper::Indent = 0;
498     local $Data::Dumper::Terse = 1;
499     local $Data::Dumper::Useqq = 1;
500
501     my $typestr = Amanda::Xfer::xmsg_type_to_string($self->{'type'});
502     my $str = "{ type => \$$typestr, elt => $self->{'elt'}, version => $self->{'version'},";
503
504     my %skip = ( "type" => 1, "elt" => 1, "version" => 1 );
505     for my $k (keys %$self) {
506         next if $skip{$k};
507         $str .= " $k => " . Dumper($self->{$k}) . ",";
508     }
509
510     # strip the trailing comma and add a closing brace
511     $str =~ s/,$/ }/g;
512
513     return $str;
514 }
515
516 package Amanda::Xfer;
517
518 # make Amanda::Xfer->new equivalent to Amanda::Xfer::Xfer->new (don't
519 # worry, the blessings work out just fine)
520 *new = *Amanda::Xfer::Xfer::new;
521 1;