1/* 2Copyright (C) 2008-2014, Parrot Foundation. 3 4=head1 NAME 5 6src/pmc/sockaddr.pmc - Sockaddr PMC 7 8=head1 DESCRIPTION 9 10The Sockaddr PMC holds a C<sockaddr> struct and saves its length (to 11distinguish C<sockaddr_in> and C<sockaddr_in6>). 12 13=head2 Vtable Functions 14 15These are the vtable functions for the Sockaddr class. 16 17=over 4 18 19=cut 20 21*/ 22 23/* HEADERIZER HFILE: none */ 24/* HEADERIZER BEGIN: static */ 25/* HEADERIZER END: static */ 26 27pmclass Sockaddr auto_attrs { 28 ATTR INTVAL family; 29 ATTR INTVAL type; 30 ATTR INTVAL protocol; 31 ATTR INTVAL len; /* Length of the sockaddr struct */ 32 ATTR void *pointer; /* Pointer to a sockaddr struct */ 33 34/* 35 36=item C<void init()> 37 38Initializes the PMC. 39 40=cut 41 42*/ 43 44 VTABLE void init() { 45 Parrot_Sockaddr_attributes * const attrs = 46 (Parrot_Sockaddr_attributes *) PMC_data(SELF); 47 48 attrs->type = 0; 49 attrs->protocol = 0; 50 attrs->pointer = NULL; 51 attrs->len = 0; 52 53 PObj_custom_destroy_SET(SELF); 54 } 55 56/* 57 58=item C<void destroy()> 59 60Destroys the PMC and frees all allocated memory. 61 62=cut 63 64*/ 65 66 VTABLE void destroy() :no_wb { 67 Parrot_Sockaddr_attributes * const data = PARROT_SOCKADDR(SELF); 68 69 if (data) { 70 if (data->pointer) 71 mem_gc_free(INTERP, data->pointer); 72 data->pointer = NULL; 73 } 74 } 75 76/* 77 78=item C<PMC *clone()> 79 80Creates a new Sockaddr PMC with the same contents and length as the current 81one. 82 83=cut 84 85*/ 86 87 VTABLE PMC *clone() :no_wb { 88 PMC * const dest = Parrot_pmc_new(INTERP, SELF->vtable->base_type); 89 const Parrot_Sockaddr_attributes * const old_attrs = PARROT_SOCKADDR(SELF); 90 Parrot_Sockaddr_attributes * const new_attrs = PARROT_SOCKADDR(dest); 91 92 new_attrs->type = old_attrs->type; 93 new_attrs->protocol = old_attrs->protocol; 94 new_attrs->len = old_attrs->len; 95 96 if (old_attrs->len) { 97 new_attrs->pointer = Parrot_gc_allocate_memory_chunk(INTERP, 98 old_attrs->len); 99 memcpy(new_attrs->pointer, old_attrs->pointer, old_attrs->len); 100 } 101 102 return dest; 103 } 104 105/* 106 107=item C<INTVAL get_bool()> 108 109Returns true if the Sockaddr is defined. 110 111=cut 112 113*/ 114 115 VTABLE INTVAL get_bool() :no_wb { 116 const Parrot_Sockaddr_attributes * const data = PARROT_SOCKADDR(SELF); 117 UNUSED(INTERP) 118 119 return data->pointer ? 1 : 0; 120 } 121 122/* 123 124=item C<INTVAL get_integer()> 125 126Returns the length of the sockaddr struct. 127 128=cut 129 130*/ 131 132 VTABLE INTVAL get_integer() :no_wb { 133 INTVAL len; 134 135 GET_ATTR_len(INTERP, SELF, len); 136 return len; 137 } 138 139/* 140 141=item C<void *get_pointer()> 142 143Returns a pointer to the C<sockaddr_in> or C<sockaddr_in6>. 144 145=cut 146 147*/ 148 149 VTABLE void *get_pointer() :no_wb { 150 const Parrot_Sockaddr_attributes * const data = PARROT_SOCKADDR(SELF); 151 UNUSED(INTERP) 152 return data->pointer; 153 } 154 155/* 156 157=item C<STRING *get_string()> 158 159Returns the string representation of this sockaddr by calling C<getnameinfo(3)>. 160 161=cut 162 163*/ 164 VTABLE STRING *get_string() :no_wb { 165 const Parrot_Sockaddr_attributes * const data = PARROT_SOCKADDR(SELF); 166 167 if (!data->pointer) 168 return Parrot_sprintf_c(INTERP, "(?)"); 169 170 return Parrot_io_internal_getnameinfo(INTERP, data->pointer, data->len); 171 } 172 173/* 174 175=item C<INTVAL get_integer_keyed_int(INTVAL what)> 176 177Returns family, type or protocol. Used for debugging. 178 179=cut 180 181*/ 182 VTABLE INTVAL get_integer_keyed_int(INTVAL what) :no_wb { 183 const Parrot_Sockaddr_attributes * const data = PARROT_SOCKADDR(SELF); 184 UNUSED(INTERP) 185 186 switch (what) { 187 case 0: 188 return data->family; 189 case 1: 190 return data->type; 191 case 2: 192 return data->protocol; 193 default: 194 return -1; 195 } 196 } 197 198} 199 200/* 201 202=back 203 204=cut 205 206*/ 207 208/* 209 * Local variables: 210 * c-file-style: "parrot" 211 * End: 212 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 213 */ 214