Imported Upstream version 3.3.0
[debian/amanda] / perl / amglue / directtcp.swg
1 /*
2  * Copyright (c) 2009, 2010 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program 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 General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 /*
22  * SWIG typemaps for DirectTCP-related stuff.
23  */
24
25 %typemap(out) DirectTCPAddr * {
26     /* we assume this is an *array* of addresses, and return an arrayref or, if
27      * the result is NULL, undef. */
28     DirectTCPAddr *iter = $1;
29     AV *av;
30     int i;
31
32     i = 0;
33     av = newAV();
34     while (iter && SU_GET_FAMILY(iter) != 0) {
35         char *addr = str_sockaddr_no_port(iter);
36         AV *tuple = newAV();
37
38         g_assert(NULL != av_store(tuple, 0, newSVpv(addr, 0)));
39         g_assert(NULL != av_store(tuple, 1, newSViv(SU_GET_PORT(iter))));
40         g_assert(NULL != av_store(av, i++, newRV_noinc((SV *)tuple)));
41         iter++;
42     }
43
44     $result = newRV_noinc((SV *)av);
45     argvi++;
46 }
47
48 %typemap(in,numinputs=0) DirectTCPAddr **addrs
49     (DirectTCPAddr *addrs) {
50     addrs = NULL;
51     $1 = &addrs;
52 }
53 %typemap(argout) DirectTCPAddr **addrs {
54     if ($1 && *$1) {
55         DirectTCPAddr *iter = *$1;
56         AV *av = newAV();
57         int i = 0;
58
59         while (iter && SU_GET_FAMILY(iter) != 0) {
60             char *addr = str_sockaddr_no_port(iter);
61             AV *tuple = newAV();
62
63             g_assert(NULL != av_store(tuple, 0, newSVpv(addr, 0)));
64             g_assert(NULL != av_store(tuple, 1, newSViv(SU_GET_PORT(iter))));
65             g_assert(NULL != av_store(av, i++, newRV_noinc((SV *)tuple)));
66             iter++;
67         }
68
69         $result = newRV_noinc((SV *)av);
70         argvi++;
71     }
72 }
73
74 %typemap(in) DirectTCPAddr *addrs {
75     AV *addrs_av;
76     int num_addrs, i;
77
78     if (!SvROK($input) || SvTYPE(SvRV($input)) != SVt_PVAV) {
79         SWIG_exception_fail(SWIG_TypeError, "must provide an arrayref of DirectTCPAddrs");
80     }
81     addrs_av = (AV *)SvRV($input);
82     num_addrs = av_len(addrs_av)+1;
83
84     $1 = g_new0(DirectTCPAddr, num_addrs+1);
85
86     for (i = 0; i < num_addrs; i++) {
87         SV **svp = av_fetch(addrs_av, i, 0);
88         AV *addr_av;
89         sockaddr_union addr;
90         IV port;
91
92         if (!svp || !SvROK(*svp) || SvTYPE(SvRV(*svp)) != SVt_PVAV
93                  || av_len((AV *)SvRV(*svp))+1 != 2) {
94             SWIG_exception_fail(SWIG_TypeError, "each DirectTCPAddr must be a 2-element arrayref");
95         }
96
97         addr_av = (AV *)SvRV(*svp);
98
99         /* get address */
100         svp = av_fetch(addr_av, 0, 0);
101         if (!svp || !SvPOK(*svp) || !str_to_sockaddr(SvPV_nolen(*svp), &addr)) {
102             SWIG_exception_fail(SWIG_TypeError, "invalid IPv4 addr in address");
103         }
104
105         /* get port */
106         svp = av_fetch(addr_av, 1, 0);
107         if (!svp || !SvIOK(*svp) || (port = SvIV(*svp)) <= 0 || port >= 65536) {
108             SWIG_exception_fail(SWIG_TypeError, "invalid port in address");
109         }
110         SU_SET_PORT(&addr, port);
111
112         copy_sockaddr($1, &addr);
113     }
114 }