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