b83d70b556590608ef984f093a3d79a752db722a
[debian/amanda] / perl / Amanda / Device.swg
1 /*
2  * Copyright (c) Zmanda, Inc.  All Rights Reserved.
3  *
4  * This library is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 2.1
6  * as published by the Free Software Foundation.
7  *
8  * This library is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
11  * License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this library; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
16  *
17  * Contact information: Zmanda Inc., 465 S Mathlida Ave, Suite 300
18  * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
19  */
20
21 %module "Amanda::Device"
22 %include "amglue/amglue.swg"
23 %include "exception.i"
24
25 %{
26 #include "device.h"
27 #include "property.h"
28 #include "fileheader.h"
29 %}
30
31 /* import dumptype_t, among others */
32 %import "Amanda/Types.swg";
33
34 %perlcode %{
35 =head1 NAME
36
37 Amanda::Device - interact with Amanda data-storage devices
38
39 =head1 SYNOPSIS
40
41   use Amanda::Device qw( :constants );
42
43   my $dev = Amanda::Device->new($device_name);
44   if ($dev->read_label() == $DEVICE_STATUS_SUCCESS) {
45       print "Label on $device_name is '$dev->volume_label'\n";
46   }
47   
48 See http://wiki.zmanda.com/index.php/Device_API for details on how Devices are used.
49
50 =head1 API STATUS
51
52 Stable
53
54 =head1 Amanda::Device Objects
55
56 See the wiki for descriptions of these functions.  Note that C instance variables
57 are represented by accessor functions of the same name.
58
59 =over
60
61 =item C<configure($use_global_config)>
62
63 =item C<read_label()>
64
65 =item C<start($mode, $label, $timestamp)>
66
67 =item C<finish()>
68
69 =item C<start_file($jobinfo)>
70
71 where C<$jobinfo> is a C<dumpfile_t> (see L<Amanda::Types>)
72
73 =item C<write_block($size, $data, $short_block)>
74
75 Note that Perl code is not expected to handle on-device data, so there
76 is currently no way to provide data to this function from Perl.  This may
77 change in future revisions.
78
79 =item C<write_from_fd($queue_fd)>
80
81 where C<$fd> is an integer file descriptor, not a filehandle
82
83 =item C<finish_file()>
84
85 =item C<seek_file($file)>
86
87 =item C<seek_block($block)>
88
89 =item C<read_block($size)>
90
91 =item C<read_to_fd($queue_fd)>
92
93 where C<$fd> is an integer file descriptor, not a filehandle
94
95 Note that Perl code is not expected to handle on-device data, so there
96 is currently no way to access the data this function returns.  This may
97 change in future revisions.
98
99 =item C<property_list()>
100
101 returns a list of properties, each represented as a hash:
102
103   { 'access' => $access_flags,
104     'name' => $property_name,
105     'description' => $property_description }
106
107 =item C<property_get($property_name)>
108
109 returns the property, with the appropriate Perl type, or undef.  In array
110 context, returns the list C<($value, $surety, $source)>.
111
112 =item C<property_set($property_name, $value)>
113
114 =item C<property_set_ex($property_name, $value, $surety, $source)>
115
116 where C<$value> is of an appropriate type for the given property, C<$surety> is
117 a C<$PROPERTY_SURETY_*> constant, and C<$source> is a C<$PROPERTY_SOURCE_*>
118 constant.
119
120 =item C<recycle_file($filenum)>
121
122 =item C<file()> (accessor function)
123
124 =item C<block()> (accessor function)
125
126 =item C<in_file()> (accessor function)
127
128 =item C<device_name()> (accessor function)
129
130 =item C<access_mode()> (accessor function)
131
132 =item C<is_eof()> (accessor function)
133
134 =item C<volume_label()> (accessor function)
135
136 =item C<volume_time()> (accessor function)
137
138 =item C<min_block_size()> (accessor function)
139
140 =item C<max_block_size()> (accessor function)
141
142 =item C<block_size()> (accessor function)
143
144 =item C<volume_header()> (accessor function)
145
146 =back
147
148 =head1 CONSTANTS
149
150 This module defines a large number of constants.  Again, consult the
151 wiki or C<device.h> for the details on their meaning.  These constants
152 are available from the package namespace (e.g.,
153 C<Amanda::Device::ACCESS_WRITE>), or imported with the C<:constant>
154 import tag.
155
156 =cut
157 %}
158
159 %init %{
160     /* Initialize the Device API on load */
161     device_api_init();
162 %}
163
164 %{
165
166 /* Utility functions for typemaps, below */
167
168 static SV *
169 set_sv_from_gvalue(GValue *value)
170 {
171     GType fundamental = G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value));
172     SV *sv = NULL;
173
174     /* complex reference types */
175     switch (fundamental) {
176         case G_TYPE_LONG:
177             sv = sv_2mortal(amglue_newSVi64(g_value_get_long(value)));
178             break;
179
180         case G_TYPE_ULONG:
181             sv = sv_2mortal(amglue_newSVu64(g_value_get_ulong(value)));
182             break;
183
184         case G_TYPE_INT64:
185             sv = sv_2mortal(amglue_newSVi64(g_value_get_int64(value)));
186             break;
187
188         case G_TYPE_UINT64:
189             sv = sv_2mortal(amglue_newSVu64(g_value_get_uint64(value)));
190             break;
191
192         case G_TYPE_BOXED: {
193             GType boxed_type = G_VALUE_TYPE(value);
194             QualifiedSize qs;
195             HV *hv;
196
197             if (boxed_type == QUALIFIED_SIZE_TYPE) {
198                 qs = *(QualifiedSize*)(g_value_get_boxed(value));
199                 
200                 /* build a hash */
201                 hv = (HV *)sv_2mortal((SV *)newHV());
202                 hv_store(hv, "accuracy", 8, newSViv(qs.accuracy), 0);
203                 hv_store(hv, "bytes", 5, amglue_newSVi64(qs.bytes), 0);
204
205                 sv = newRV((SV *)hv);
206                 return newRV((SV *)hv);
207             } else {
208                 warn("Unsupported boxed property type #%d", (int)boxed_type);
209
210                 sv = sv_newmortal();
211                 sv_setsv(sv, &PL_sv_undef);
212                 return sv;
213             }
214         }
215     }
216
217     /* simple types that can be constructed with sv_set*v */
218     sv = sv_newmortal();
219     switch (fundamental) {
220         case G_TYPE_CHAR:
221             sv_setiv(sv, g_value_get_char(value));
222             break;
223
224         case G_TYPE_UCHAR:
225             sv_setuv(sv, g_value_get_uchar(value));
226             break;
227
228         case G_TYPE_BOOLEAN:
229             sv_setiv(sv, g_value_get_boolean(value));
230             break;
231
232         case G_TYPE_INT:
233             sv_setiv(sv, g_value_get_int(value));
234             break;
235
236         case G_TYPE_UINT:
237             sv_setuv(sv, g_value_get_uint(value));
238             break;
239
240         case G_TYPE_FLOAT:
241             sv_setnv(sv, g_value_get_float(value));
242             break;
243
244         case G_TYPE_DOUBLE:
245             sv_setnv(sv, g_value_get_double(value));
246             break;
247
248         case G_TYPE_STRING:
249             sv_setpv(sv, g_value_get_string(value));
250             break;
251
252         case G_TYPE_ENUM:
253             sv_setiv(sv, g_value_get_enum(value));
254             break;
255
256         case G_TYPE_FLAGS:
257             sv_setiv(sv, g_value_get_flags(value));
258             break;
259
260         /* Unsupported */
261         default:
262         case G_TYPE_POINTER:
263         case G_TYPE_INTERFACE:
264         case G_TYPE_OBJECT:
265         case G_TYPE_PARAM:
266             warn("Unsupported fundamental property type #%d", (int)fundamental);
267             sv_setsv(sv, &PL_sv_undef);
268             break;
269     }
270
271     return sv;
272 }
273
274 static gboolean
275 set_gvalue_from_sv(SV *sv, GValue *value)
276 {
277     GType fundamental = G_TYPE_FUNDAMENTAL(G_VALUE_TYPE(value));
278     switch (fundamental) {
279         case G_TYPE_CHAR:
280             if (!SvIOK(sv)) return FALSE;
281             g_value_set_char(value, SvIV(sv));
282             break;
283
284         case G_TYPE_UCHAR:
285             if (!SvIOK(sv)) return FALSE;
286             g_value_set_uchar(value, SvUV(sv));
287             break;
288
289         case G_TYPE_BOOLEAN:
290             if (!SvIOK(sv)) return FALSE;
291             g_value_set_boolean(value, SvIV(sv));
292             break;
293
294         case G_TYPE_INT:
295             g_value_set_int(value, amglue_SvI32(sv));
296             break;
297
298         case G_TYPE_UINT:
299             g_value_set_uint(value, amglue_SvU32(sv));
300             break;
301
302         case G_TYPE_LONG:
303             g_value_set_int64(value, amglue_SvI64(sv));
304             break;
305
306         case G_TYPE_ULONG:
307             g_value_set_uint64(value, amglue_SvU64(sv));
308             break;
309
310         case G_TYPE_INT64:
311             g_value_set_int64(value, amglue_SvI64(sv));
312             break;
313
314         case G_TYPE_UINT64:
315             g_value_set_uint64(value, amglue_SvU64(sv));
316             break;
317
318         case G_TYPE_FLOAT:
319             if (!SvNOK(sv)) return FALSE;
320             g_value_set_float(value, SvNV(sv));
321             break;
322
323         case G_TYPE_DOUBLE:
324             if (!SvNOK(sv)) return FALSE;
325             g_value_set_double(value, SvNV(sv));
326             break;
327
328         case G_TYPE_STRING:
329             if (!SvPOK(sv)) return FALSE;
330             g_value_set_string(value, SvPV_nolen(sv));
331             break;
332
333         case G_TYPE_ENUM: 
334             if (!SvIOK(sv)) return FALSE;
335             g_value_set_enum(value, SvIV(sv));
336             break;
337
338         case G_TYPE_FLAGS:
339             if (!SvIOK(sv)) return FALSE;
340             g_value_set_flags(value, SvIV(sv));
341             break;
342
343         /* Unsupported */
344         default:
345         case G_TYPE_POINTER:
346         case G_TYPE_INTERFACE:
347         case G_TYPE_BOXED: /* note: *getting* boxed values is supported */
348         case G_TYPE_OBJECT:
349         case G_TYPE_PARAM:
350             return FALSE;
351     }
352
353     return TRUE;
354 }
355
356 %}
357
358 /*
359  * Device struct, %extend-ed into a Perl class
360  */
361
362 typedef struct queue_fd_t {
363     /* Instance variables -- all readonly */
364     %immutable;
365     int fd;
366     char *errmsg;
367
368     %mutable;
369
370     /* methods */
371     %extend {
372         /* constructor */
373         queue_fd_t(int fd) {
374             return queue_fd_new(fd, NULL);
375         }
376
377         /* destructor */
378         ~queue_fd_t() {
379             amfree(self->errmsg);
380             g_free(self);
381         }
382     }
383 } queue_fd_t;
384
385 typedef struct Device {
386
387     /* methods */
388     %extend {
389         /* constructor */
390         Device(char *device_name) {
391             return device_open(device_name);
392         }
393
394         ~Device() {
395             g_object_unref(self);
396         }
397
398         gboolean
399         configure(gboolean use_global_config) {
400             return device_configure(self, use_global_config);
401         }
402
403         char *
404         error() {
405             return device_error(self);
406         }
407
408         char *
409         status_error() {
410             return device_status_error(self);
411         }
412
413         char *
414         error_or_status() {
415             return device_error_or_status(self);
416         }
417
418         DeviceStatusFlags
419         read_label() {
420             return device_read_label(self);
421         }
422
423         gboolean
424         start(DeviceAccessMode mode, char *label, char *timestamp) {
425             return device_start(self, mode, label, timestamp);
426         }
427
428         gboolean
429         finish() {
430             return device_finish(self);
431         }
432
433         gboolean
434         start_file(dumpfile_t *jobInfo) {
435             return device_start_file(self, jobInfo);
436         }
437
438         gboolean
439         write_block(guint size, gpointer data) {
440             return device_write_block(self, size, data);
441         }
442
443         gboolean
444         write_from_fd(queue_fd_t *queue_fd) {
445             return device_write_from_fd(self, queue_fd);
446         }
447
448         gboolean
449         finish_file() {
450             return device_finish_file(self);
451         }
452
453         dumpfile_t*
454         seek_file(guint file) {
455             return device_seek_file(self, file);
456         }
457
458         gboolean
459         seek_block(guint64 block) {
460             return device_seek_block(self, block);
461         }
462
463         int
464         read_block(gpointer buffer, int *size) {
465             return device_read_block(self, buffer, size);
466         }
467
468         gboolean read_to_fd(queue_fd_t *queue_fd) {
469             return device_read_to_fd(self, queue_fd);
470         }
471
472         %typemap(out) const GSList * {
473             GSList *iter;
474
475             /* Count the DeviceProperties */
476             EXTEND(SP, g_slist_length($1)); /* make room for return values */
477
478             /* Note that we set $result several times. the nature of
479              * SWIG's wrapping is such that incrementing argvi points
480              * $result to the next location in perl's argument stack.
481              */
482
483             for (iter = $1; iter; iter = g_slist_next(iter)) {
484                 DeviceProperty *prop = iter->data;
485                 HV *hash = newHV();
486                 SV *rv = newRV_noinc((SV *)hash);
487
488                 hv_store(hash, "name", 4,
489                         newSVpv(prop->base->name, 0), 0);
490                 hv_store(hash, "description", 11,
491                         newSVpv(prop->base->description, 0), 0);
492                 hv_store(hash, "access", 6,
493                         newSViv(prop->access), 0);
494                 $result = sv_2mortal(rv);
495                 argvi++;
496             }
497         }
498         const GSList * property_list(void) {
499             return device_property_get_list(self);
500         }
501
502         %typemap(out) const GSList *; /* remove typemap */
503
504         /* A typemap to convert a property name to a DevicePropertyBase. */
505         %typemap(in) DevicePropertyBase * {
506             char *pname = NULL;
507
508             if (SvPOK($input))
509                 pname = SvPV_nolen($input);
510
511             if (pname) $1 = (DevicePropertyBase *)device_property_get_by_name(pname);
512             if (!pname || !$1) {
513                 SWIG_exception_fail(SWIG_ValueError, "Invalid property name");
514             }
515         }
516
517         /* A typemap to convert the GValue in property_get to a return value.  The
518          * (in) typemap sets up storage for the parameters, while the (argout) converts
519          * them to a perl SV. */
520         %typemap(in,numinputs=0) (GValue *out_val, PropertySurety *surety,
521                                   PropertySource *source, gboolean *val_found)
522                             (GValue val,
523                              PropertySurety surety,
524                              PropertySource source,
525                              gboolean found) {
526             memset(&val, 0, sizeof(val));
527             $1 = &val;
528             if (GIMME_V == G_ARRAY) {
529                 $2 = &surety;
530                 $3 = &source;
531             }
532             $4 = &found;
533         }
534         %typemap(argout) (GValue *out_val, PropertySurety *surety,
535                           PropertySource *source, gboolean *val_found) {
536             /* if the result is valid */
537             if (*$4) {
538                 /* move data from $1 to $result, somehow */
539                 $result = set_sv_from_gvalue($1);
540                 argvi++;
541
542                 /* free any memory for the GValue */
543                 g_value_unset($1);
544
545                 if (GIMME_V == G_ARRAY) {
546                     $result = newSViv(*$2);
547                     argvi++;
548                     $result = newSViv(*$3);
549                     argvi++;
550                 }
551             }
552             /* otherwise, return nothing */
553         }
554
555         void
556         property_get(DevicePropertyBase *pbase, GValue *out_val, PropertySurety *surety,
557                      PropertySource *source, gboolean *val_found) {
558             *val_found = device_property_get_ex(self, pbase->ID, out_val, surety, source);
559         }
560
561         /* delete typemaps */
562         %typemap(in) (GValue *out_val, gboolean *val_found);
563         %typemap(argout) (GValue *out_val, gboolean *val_found);
564
565         /* We cheat a little bit here and just pass the native Perl type in to
566          * the function.  This is the easiest way to make sure we know the property
567          * information (in particular, its type) before trying to convert the SV.  */
568         %typemap(in) SV *sv "$1 = $input;"
569
570         gboolean
571         property_set(DevicePropertyBase *pbase, SV *sv) {
572             GValue gval;
573             memset(&gval, 0, sizeof(gval));
574             g_value_init(&gval, pbase->type);
575             if (!set_gvalue_from_sv(sv, &gval))
576                 goto fail;
577
578             if (!device_property_set(self, pbase->ID, &gval))
579                 goto fail;
580
581             g_value_unset(&gval);
582             return TRUE;
583         fail:
584             g_value_unset(&gval);
585             return FALSE;
586         }
587
588         gboolean
589         property_set_ex(DevicePropertyBase *pbase, SV *sv,
590                         PropertySurety surety, PropertySource source) {
591             GValue gval;
592             memset(&gval, 0, sizeof(gval));
593             g_value_init(&gval, pbase->type);
594             if (!set_gvalue_from_sv(sv, &gval))
595                 goto fail;
596
597             if (!device_property_set_ex(self, pbase->ID, &gval, surety, source))
598                 goto fail;
599
600             g_value_unset(&gval);
601             return TRUE;
602         fail:
603             g_value_unset(&gval);
604             return FALSE;
605         }
606
607         gboolean recycle_file(guint filenum) {
608             return device_recycle_file(self, filenum);
609         }
610         
611         /* accessor functions */
612
613         int file(void) { return self->file; }
614         guint64 block(void) { return self->block; }
615         gboolean in_file(void) { return self->in_file; }
616         char * device_name(void) { return self->device_name; }
617         DeviceAccessMode access_mode(void) { return self->access_mode; }
618         gboolean is_eof(void) { return self->is_eof; }
619         char * volume_label(void) { return self->volume_label; }
620         char * volume_time(void) { return self->volume_time; }
621         DeviceStatusFlags status(void) { return self->status; }
622         gsize min_block_size(void) { return self->min_block_size; }
623         gsize max_block_size(void) { return self->max_block_size; }
624         gsize block_size(void) { return self->block_size; }
625         dumpfile_t *volume_header(void) { return self->volume_header; }
626     };
627
628 } Device;
629
630 /*
631  * Constants
632  */
633
634 amglue_add_flag_tag_fns(DeviceAccessMode);
635 amglue_add_constant_short(ACCESS_NULL, "NULL", DeviceAccessMode);
636 amglue_add_constant_short(ACCESS_READ, "READ", DeviceAccessMode);
637 amglue_add_constant_short(ACCESS_WRITE, "WRITE", DeviceAccessMode);
638 amglue_add_constant_short(ACCESS_APPEND, "APPEND", DeviceAccessMode);
639
640 /* (this is really a macro, but SWIG will Do The Right Thing */
641 gboolean IS_WRITABLE_ACCESS_MODE(DeviceAccessMode mode);
642 amglue_export_tag(DeviceAccessMode, IS_WRITABLE_ACCESS_MODE);
643 amglue_copy_to_tag(DeviceAccessMode, constants);
644
645 amglue_add_flag_tag_fns(DeviceStatusFlags);
646 amglue_add_constant_short(DEVICE_STATUS_SUCCESS, "SUCCESS", DeviceStatusFlags);
647 amglue_add_constant_short(DEVICE_STATUS_DEVICE_ERROR, "DEVICE_ERROR", DeviceStatusFlags);
648 amglue_add_constant_short(DEVICE_STATUS_DEVICE_BUSY, "DEVICE_BUSY", DeviceStatusFlags);
649 amglue_add_constant_short(DEVICE_STATUS_VOLUME_MISSING, "VOLUME_MISSING", DeviceStatusFlags);
650 amglue_add_constant_short(DEVICE_STATUS_VOLUME_UNLABELED, "VOLUME_UNLABELED", DeviceStatusFlags);
651 amglue_add_constant_short(DEVICE_STATUS_VOLUME_ERROR, "VOLUME_ERROR", DeviceStatusFlags);
652 amglue_add_constant_noshort(DEVICE_STATUS_FLAGS_MAX, DeviceStatusFlags);
653 amglue_copy_to_tag(DeviceStatusFlags, constants);
654
655 amglue_add_flag_tag_fns(PropertyPhaseFlags);
656 amglue_add_constant_short(PROPERTY_PHASE_BEFORE_START, "BEFORE_START", PropertyPhaseFlags);
657 amglue_add_constant_short(PROPERTY_PHASE_BETWEEN_FILE_WRITE, "BETWEEN_FILE_WRITE", PropertyPhaseFlags);
658 amglue_add_constant_short(PROPERTY_PHASE_INSIDE_FILE_WRITE, "INSIDE_FILE_WRITE", PropertyPhaseFlags);
659 amglue_add_constant_short(PROPERTY_PHASE_BETWEEN_FILE_READ, "BETWEEN_FILE_READ", PropertyPhaseFlags);
660 amglue_add_constant_short(PROPERTY_PHASE_INSIDE_FILE_READ, "INSIDE_FILE_READ", PropertyPhaseFlags);
661 amglue_add_constant_noshort(PROPERTY_PHASE_MAX, PropertyPhaseFlags);
662 amglue_add_constant_noshort(PROPERTY_PHASE_MASK, PropertyPhaseFlags);
663 amglue_add_constant_noshort(PROPERTY_PHASE_SHIFT, PropertyPhaseFlags);
664 amglue_copy_to_tag(PropertyPhaseFlags, constants);
665
666 amglue_add_flag_tag_fns(PropertyAccessFlags);
667 amglue_add_constant_short(PROPERTY_ACCESS_GET_BEFORE_START, 
668                     "GET_BEFORE_START", PropertyAccessFlags);
669 amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_WRITE, 
670                     "GET_BETWEEN_FILE_WRITE", PropertyAccessFlags);
671 amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_WRITE, 
672                     "GET_INSIDE_FILE_WRITE", PropertyAccessFlags);
673 amglue_add_constant_short(PROPERTY_ACCESS_GET_BETWEEN_FILE_READ, 
674                     "GET_BETWEEN_FILE_READ", PropertyAccessFlags);
675 amglue_add_constant_short(PROPERTY_ACCESS_GET_INSIDE_FILE_READ, 
676                     "GET_INSIDE_FILE_READ", PropertyAccessFlags);
677 amglue_add_constant_short(PROPERTY_ACCESS_SET_BEFORE_START, 
678                     "SET_BEFORE_START", PropertyAccessFlags);
679 amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_WRITE, 
680                     "SET_BETWEEN_FILE_WRITE", PropertyAccessFlags);
681 amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_WRITE, 
682                     "SET_INSIDE_FILE_WRITE", PropertyAccessFlags);
683 amglue_add_constant_short(PROPERTY_ACCESS_SET_BETWEEN_FILE_READ, 
684                     "SET_BETWEEN_FILE_READ", PropertyAccessFlags);
685 amglue_add_constant_short(PROPERTY_ACCESS_SET_INSIDE_FILE_READ, 
686                     "SET_INSIDE_FILE_READ", PropertyAccessFlags);
687 amglue_add_constant_noshort(PROPERTY_ACCESS_GET_MASK, PropertyAccessFlags);
688 amglue_add_constant_noshort(PROPERTY_ACCESS_SET_MASK, PropertyAccessFlags);
689 amglue_copy_to_tag(PropertyAccessFlags, constants);
690
691 amglue_add_enum_tag_fns(ConcurrencyParadigm);
692 amglue_add_constant_short(CONCURRENCY_PARADIGM_EXCLUSIVE, "EXCLUSIVE", ConcurrencyParadigm);
693 amglue_add_constant_short(CONCURRENCY_PARADIGM_SHARED_READ, "SHARED_READ", ConcurrencyParadigm);
694 amglue_add_constant_short(CONCURRENCY_PARADIGM_RANDOM_ACCESS, "RANDOM_ACCESS", ConcurrencyParadigm);
695 amglue_copy_to_tag(ConcurrencyParadigm, constants);
696
697 amglue_add_enum_tag_fns(StreamingRequirement);
698 amglue_add_constant_short(STREAMING_REQUIREMENT_NONE, "NONE", StreamingRequirement);
699 amglue_add_constant_short(STREAMING_REQUIREMENT_DESIRED, "DESIRED", StreamingRequirement);
700 amglue_add_constant_short(STREAMING_REQUIREMENT_REQUIRED, "REQUIRED", StreamingRequirement);
701 amglue_copy_to_tag(StreamingRequirement, constants);
702
703 amglue_add_enum_tag_fns(MediaAccessMode);
704 amglue_add_constant_short(MEDIA_ACCESS_MODE_READ_ONLY, "READ_ONLY", MediaAccessMode);
705 amglue_add_constant_short(MEDIA_ACCESS_MODE_WORM, "WORM", MediaAccessMode);
706 amglue_add_constant_short(MEDIA_ACCESS_MODE_READ_WRITE, "READ_WRITE", MediaAccessMode);
707 amglue_add_constant_short(MEDIA_ACCESS_MODE_WRITE_ONLY, "WRITE_ONLY", MediaAccessMode);
708 amglue_copy_to_tag(MediaAccessMode, constants);
709
710 amglue_add_enum_tag_fns(SizeAccuracy);
711 amglue_add_constant_short(SIZE_ACCURACY_UNKNOWN, "UNKNOWN", SizeAccuracy);
712 amglue_add_constant_short(SIZE_ACCURACY_ESTIMATE, "ESTIMATE", SizeAccuracy);
713 amglue_add_constant_short(SIZE_ACCURACY_REAL, "REAL", SizeAccuracy);
714 amglue_copy_to_tag(SizeAccuracy, constants);
715
716 amglue_add_flag_tag_fns(PropertySurety);
717 amglue_add_constant_short(PROPERTY_SURETY_BAD, "SURETY_BAD", PropertySurety);
718 amglue_add_constant_short(PROPERTY_SURETY_GOOD, "SURETY_GOOD", PropertySurety);
719 amglue_copy_to_tag(PropertySurety, constants);
720
721 amglue_add_flag_tag_fns(PropertySource);
722 amglue_add_constant_short(PROPERTY_SOURCE_DEFAULT, "SOURCE_DEFAULT", PropertySource);
723 amglue_add_constant_short(PROPERTY_SOURCE_DETECTED, "SOURCE_DETECTED", PropertySource);
724 amglue_add_constant_short(PROPERTY_SOURCE_USER, "SOURCE_USER", PropertySource);
725 amglue_copy_to_tag(PropertySource, constants);
726
727 %perlcode %{
728
729 # SWIG produces a sub-package for the Device "class", in this case named 
730 # Amanda::Device::Device.  For user convenience, we allow Amanda::Device->new(..) to
731 # do the same thing.  This is a wrapper function, and not just a typeglob assignment,
732 # because we want to get the right blessing.
733 sub new {
734     my $pkg = shift;
735     Amanda::Device::Device->new(@_);
736 }
737 %}