################################################################################ # # $Project: /Convert-Binary-C $ # $Author: mhx $ # $Date: 2011/04/10 12:32:33 +0200 $ # $Revision: 12 $ # $Source: /xsubs/member.xs $ # ################################################################################ # # Copyright (c) 2002-2011 Marcus Holland-Moritz. All rights reserved. # This program is free software; you can redistribute it and/or modify # it under the same terms as Perl itself. # ################################################################################ ################################################################################ # # METHOD: member # # WRITTEN BY: Marcus Holland-Moritz ON: Jan 2002 # CHANGED BY: ON: # ################################################################################ void CBC::member(type, offset = NULL) const char *type SV *offset PREINIT: CBC_METHOD(member); MemberInfo mi; int have_offset, off; PPCODE: off = (have_offset = DEFINED(offset)) ? SvIV(offset) : 0; CT_DEBUG_METHOD2("'%s', %d", type, off); CHECK_PARSE_DATA; CHECK_VOID_CONTEXT; NEED_PARSE_DATA; if (!get_member_info(aTHX_ THIS, type, &mi, 0)) Perl_croak(aTHX_ "Cannot find '%s'", type); check_allowed_types(aTHX_ &mi, method, ALLOW_STRUCTS | ALLOW_UNIONS | ALLOW_ARRAYS); if (mi.flags) { u_32 flags = mi.flags; /* bitfields are not a problem without offset given */ if (!have_offset) flags &= ~T_HASBITFIELD; WARN_FLAGS(type, flags); } if (have_offset) { if (off < 0 || off >= (int) mi.size) Perl_croak(aTHX_ "Offset %d out of range (0 <= offset < %d)", off, mi.size); if (GIMME_V == G_ARRAY) { ListIterator li; GMSInfo info; SV *member; int count; info.hit = LL_new(); info.off = LL_new(); info.pad = LL_new(); (void) get_member_string(aTHX_ &mi, off, &info); count = LL_count(info.hit) + LL_count(info.off) + LL_count(info.pad); EXTEND(SP, count); LL_foreach(member, li, info.hit) PUSHs(member); LL_foreach(member, li, info.off) PUSHs(member); LL_foreach(member, li, info.pad) PUSHs(member); LL_destroy(info.hit, NULL); LL_destroy(info.off, NULL); LL_destroy(info.pad, NULL); XSRETURN(count); } else { SV *member = get_member_string(aTHX_ &mi, off, NULL); PUSHs(member); XSRETURN(1); } } else { LinkedList list; SV *member; int count; list = GIMME_V == G_ARRAY ? LL_new() : NULL; count = get_all_member_strings(aTHX_ &mi, list); if (GIMME_V == G_ARRAY) { ListIterator li; EXTEND(SP, count); LL_foreach(member, li, list) PUSHs(member); LL_destroy(list, NULL); XSRETURN(count); } else XSRETURN_IV(count); }