The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
/*************************************************************************
 *
 *  $RCSfile$
 *
 *  $Revision$
 *
 *  last change: $Author$ $Date$
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Ralph Thomas
 *
 *   Copyright: 2000 by Sun Microsystems, Inc.
 *
 *   All Rights Reserved.
 *
 *   Contributor(s): Bustamam Harun
 *
 *
 ************************************************************************/

#define PERL_NO_GET_CONTEXT
#include "UNO.h"
#include "ppport.h"

#undef realloc

// UNO Runtime Instance
static PerlRT UNOInstance;

// helper functions
static void
UNOCroak(pTHX_ UNO_XAny any ) {
    SV *exc = AnyToSV(any);
    SV *errsv = get_sv("@", TRUE);
    sv_replace(errsv, exc);
    Perl_croak(aTHX_ Nullch);
}

static void
UNOCroak(pTHX_ ::com::sun::star::uno::Exception& e ) {
    UNOCroak(aTHX_ makeAny(e));
}

UNO::UNO() {
    ctx = NULL;
}

UNO::~UNO() {
    UNOInstance.prtInitialized = FALSE;
}

void
UNO::createServices() {
    UNOInstance.ssf = UNO_XSingleServiceFactory(
	UNOInstance.localCtx->getServiceManager()->createInstanceWithContext(
	    UNO_INVOCATION_OBJECT, UNOInstance.localCtx ), ::com::sun::star::uno::UNO_QUERY );

    if( ! UNOInstance.ssf.is() )
	throw ::com::sun::star::uno::RuntimeException(
	    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNO: couldn't instantiate Single Service Manager" )),
		UNO_XInterface () );

    UNOInstance.typecvt = UNO_XTypeConverter(
	UNOInstance.localCtx->getServiceManager()->createInstanceWithContext(
	    UNO_TYPECONVERTER_OBJECT, UNOInstance.localCtx ), ::com::sun::star::uno::UNO_QUERY );

    if( ! UNOInstance.typecvt.is() )
	throw ::com::sun::star::uno::RuntimeException(
	    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNO: couldn't instantiate typeconverter service" )),
		UNO_XInterface () );

    UNOInstance.reflection = UNO_XIdlReflection (
        UNOInstance.localCtx->getServiceManager()->createInstanceWithContext(
	    UNO_COREREFLECTION_OBJECT, UNOInstance.localCtx ), ::com::sun::star::uno::UNO_QUERY );

    if( ! UNOInstance.reflection.is() )
	throw ::com::sun::star::uno::RuntimeException(
	    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNO: couldn't instantiate reflection service" )),
		UNO_XInterface () );
}

UNO_Any::UNO_Any(char *sname) {
    ::rtl::OUString soname = ::rtl::OUString::createFromAscii(sname);

    UNO_XAny tstruct;
    UNO_XIdlClass idlclass(UNOInstance.reflection->forName(soname), ::com::sun::star::uno::UNO_QUERY);
    if (! idlclass.is()) {
	croak("UNO: failed to create IdlClass");
    }

    idlclass->createObject(tstruct);
    pany = tstruct;
}

UNO_Struct::UNO_Struct() {
}

UNO_Struct::UNO_Struct(char *sname) : UNO_Any(sname) {
    UNO_SAny args(1);
    UNO_XInterface tif;

    args[0] <<= pany;
    tif = UNOInstance.ssf->createInstanceWithArguments(args);
    if ( ! tif.is() ) {
	croak("UNO: Proxy creation failed");
    }

    xinvoke = UNO_XInvocation2(tif, ::com::sun::star::uno::UNO_QUERY);

    if ( ! xinvoke.is() ) {
	croak("UNO: XInvocation2 failed to be created");
    }

    TypeString = strdup(sname);
}

UNO_Struct::UNO_Struct(UNO_XAny tany) {
    UNO_SAny args(1);
    UNO_XInterface tif;

    args[0] <<= tany;
    tif = UNOInstance.ssf->createInstanceWithArguments(args);
    if ( ! tif.is() ) {
	croak("UNO: Proxy creation failed");
    }

    xinvoke = UNO_XInvocation2(tif, ::com::sun::star::uno::UNO_QUERY);

    if ( ! xinvoke.is() ) {
	croak("UNO: XInvocation2 failed to be created");
    }

    pany = tany;
}

UNO_Struct::~UNO_Struct() {
}

void
UNO_Struct::set(char *mname, SV *value) {
    UNO_XAny aval;

    if ( ! xinvoke.is() ) {
	croak("UNO: Invalid XInvocation2 ref");
    }

    aval = SVToAny(value);

    ::rtl::OUString membername = ::rtl::OUString::createFromAscii(mname);
    if ( xinvoke->hasProperty(membername) ) {
	xinvoke->setValue( membername, aval );
    } else {
	croak("Member name: \"%s\" does not exists", mname);
    }
}

SV *
UNO_Struct::get(char *mname) {
    UNO_XAny aval;

    if ( ! xinvoke.is() ) {
	croak("UNO: Invalid XInvocation2 ref");
    }

    ::rtl::OUString membername = ::rtl::OUString::createFromAscii(mname);
    if ( xinvoke->hasProperty(membername) ) {
	aval = xinvoke->getValue( membername );
    } else {
	croak("Member name: \"%s\" does not exists", mname);
    }
    return AnyToSV(aval);
}

UNO_Interface *
UNO::createInitialComponentContext(char *iniFile) {
    UNOInstance.localCtx = cppu::defaultBootstrap_InitialComponentContext(
	::rtl::OUString::createFromAscii(iniFile) );
    UNOInstance.prtInitialized = TRUE;
    createServices();

    UNO_XAny tany;
    tany <<= UNOInstance.localCtx;

    ctx = new UNO_Interface(tany);
    return ctx;
}

UNO_Interface *
UNO::createInitialComponentContext() {
    UNOInstance.localCtx = cppu::defaultBootstrap_InitialComponentContext();
    UNOInstance.prtInitialized = TRUE;
    createServices();

    UNO_XAny tany;
    tany <<= UNOInstance.localCtx;

    ctx = new UNO_Interface(tany);
    return ctx;
}

UNO_Struct *
UNO::createIdlStruct(char *name) {
    return new UNO_Struct(name);
}

UNO_Interface::UNO_Interface() {
}

UNO_Interface::UNO_Interface(UNO_XAny thisif) {
    dTHX;
    UNO_SAny args(1);
    UNO_XInterface tif;

    // Check if ref is valid
    UNO_XInterface cif;
    thisif >>= cif;
    if ( ! cif.is() ) {
	croak("UNO: invalid interface ref");
    }

    args[0] <<= thisif;
    try {
        tif = UNOInstance.ssf->createInstanceWithArguments(args);
    } catch ( ::com::sun::star::uno::Exception& e ) {
	UNOCroak(aTHX_ e);
    }        
    if ( ! tif.is() ) {
	croak("UNO: Proxy creation failed");
    }

    xinvoke = UNO_XInvocation2(tif, ::com::sun::star::uno::UNO_QUERY);

    if ( ! xinvoke.is() ) {
	croak("UNO: XInvocation2 failed to be created");
    }

    pany = thisif;
}

SV *
UNO_Interface::invoke(char *method, UNO_SAny args) {
    dTHX;
    I32 i;

    ::rtl::OUString mstr = ::rtl::OUString::createFromAscii(method);
    if ( ! xinvoke.is() ) {
	croak("UNO: Invalid XInvocation2 ref");
    }

    if ( ! xinvoke->hasMethod(mstr) ) {
	croak("UNO: Method: \"%s\" is NOT defined", method);
    }

    UNO_SAny oargs;
    UNO_SShort oidx;
    UNO_XAny ret_val;

    try {
	ret_val = xinvoke->invoke(mstr, args, oidx, oargs);
    } catch ( ::com::sun::star::reflection::InvocationTargetException& e ) {
	UNOCroak(aTHX_ e.TargetException);
    } catch ( ::com::sun::star::lang::WrappedTargetRuntimeException& e ) {
	UNOCroak(aTHX_ e.TargetException);
    } catch ( ::com::sun::star::uno::Exception& e ) {
	UNOCroak(aTHX_ e);
    }

    SV *retval = Nullsv;
    if ( oargs.getLength() > 0 ) {
	AV *av;

	av = newAV();

	// Store return value
	SV *trv = AnyToSV(ret_val);
	av_store(av, 0, trv);

	// Convert output parameters
	av_extend(av, oargs.getLength()+1);
	for ( int i = 0; i < oargs.getLength(); i++ ) {
	    SV *tav = AnyToSV(UNOInstance.typecvt->convertTo(oargs[i], oargs[i].getValueType()));
	    av_store(av, i+1, tav);
	}
	retval = (SV *)av;
    } else {
	// Convert return value
	retval = AnyToSV(ret_val);
    }

    return retval;
}

void
UNO_Any::assignAny(UNO_XAny any) {
	pany <<= any;
}

UNO_XAny
UNO_Any::getAny() {
	return pany;
}

static void
UNOExit(pTHX_ void *pi) {
    // Clean up PerlRT
    ((PerlRT *)pi)->reflection.clear();
    ((PerlRT *)pi)->typecvt.clear();
    ((PerlRT *)pi)->ssf.clear();
    ((PerlRT *)pi)->localCtx.clear();
}

void
Bootstrap(pTHX) {
    dSP;

    UNOInstance.prtInitialized = 0;

    perl_atexit(UNOExit, (void *)&UNOInstance);
}

UNO_SAny
AVToSAny(AV *parr) {
    dTHX;
    UNO_SAny aany;

    if ( av_len(parr) >= 0 ) {
	aany.realloc(av_len(parr) + 1);
	for ( int i = 0; i <= av_len(parr); i++ ) {
	    aany[i] = SVToAny(*av_fetch(parr, i, FALSE));
	}
    }
    return aany;
}

UNO_XAny
HVToStruct(HV *hv) {
    dTHX;
    UNO_XAny a;

    SV *smagic = newSVpv(UNO_STRUCT_NAME_KEY, strlen(UNO_STRUCT_NAME_KEY));
    if ( hv_exists_ent(hv, smagic, 0) ) {
	char *key;
	I32 klen;
	SV *val;

	SV **pname = hv_fetch(hv, UNO_STRUCT_NAME_KEY, strlen(UNO_STRUCT_NAME_KEY), FALSE);
	char *cname = SvPVX(*pname);

	::rtl::OUString sname = ::rtl::OUString::createFromAscii(cname);

	UNO_XMaterialHolder mholder( UNOInstance.ssf, ::com::sun::star::uno::UNO_QUERY );
	if ( mholder.is( ) )
		a = mholder->getMaterial();

	// Iterate through hash
	hv_iterinit(hv);
	while (val = hv_iternextsv(hv, (char **) &key, &klen)) {
	    if ( strcmp(key, UNO_STRUCT_NAME_KEY) ) {
		UNO_XAny tany;

		tany = SVToAny(val);
	    }
	}
    }
    return a;
}

UNO_XAny
SVToAny(SV *svp) {
    dTHX;
    UNO_XAny a;

    SvGETMAGIC(svp);

    if ( !SvOK(svp) )
	return a;

    if ( SvROK(svp) ) {
	switch ( SvTYPE(SvRV(svp)) ) {
	    case SVt_PVAV: {
		AV *parr = (AV *)SvRV(svp);
		UNO_SAny aany = AVToSAny(parr);
		a <<= aany;

		break;
	    }

	    case SVt_PVHV: {
		HV *hv = (HV *)SvRV(svp);
		UNO_XAny aany = HVToStruct(hv);
		a <<= aany;

		break;
	    }

	    case SVt_RV:
	    case SVt_PVMG: {
		long otype;
		IV tmp = SvIV((SV*)SvRV(svp));
		UNO_Any *tptr = INT2PTR(UNO_Any *,tmp);

		UNO_XAny tany = tptr->getAny();

		switch (tany.getValueTypeClass()) {
		    case typelib_TypeClass_STRUCT: {
			UNO_XMaterialHolder mh(tptr->xinvoke, ::com::sun::star::uno::UNO_QUERY);
			if( mh.is() ) {
			    a = mh->getMaterial();
			} else {
			    croak("Error getting Material");
			}
			break;
		    }

		    case typelib_TypeClass_SEQUENCE:
		    case typelib_TypeClass_INTERFACE: {
			a <<= tany;
			break;
		    }

		    case typelib_TypeClass_BOOLEAN:
		    case typelib_TypeClass_LONG:
		    case typelib_TypeClass_HYPER: {
			a = tany;
			break;
		    }

		    default: {
			croak("Unsupported ref: %d", tany.getValueTypeClass());
			break;
		    }
		}

		break;
	    }
	}
    } else if ( SvNOK(svp) ) {
	a <<= (double) SvNVX(svp);
    } else if (SvIOK(svp) ) {
	a <<= (long) SvIVX(svp);
    } else if (SvPOK(svp) ) {
	// Extract String
	char *tstr = SvPVX(svp);
	::rtl::OUString ostr = ::rtl::OUString(tstr, SvCUR(svp), SvUTF8(svp) ? RTL_TEXTENCODING_UTF8 : RTL_TEXTENCODING_ISO_8859_1 );
	a <<= ostr;
    }

    return a;
}

AV *
SAnyToAV(UNO_SAny sa) {
    dTHX;
    AV *av;

    av = newAV();
    av_extend(av, sa.getLength());
    for ( int i = 0; i < sa.getLength(); i++ ) {
	SV *tav = AnyToSV(UNOInstance.typecvt->convertTo(sa[i], sa[i].getValueType()));
	av_store(av, i, tav);
    }
    return av;
}

SV *
AnyToSV(UNO_XAny a) {
    dTHX;
    SV *ret;

    ret = Nullsv;

    switch (a.getValueTypeClass()) {
	case typelib_TypeClass_VOID: {
	    ret = Nullsv;
	    break;
	}

	case typelib_TypeClass_CHAR: {
	    sal_Unicode c = *(sal_Unicode*)a.getValue();
	    ret = newSViv(c);
	    break;
	}

	case typelib_TypeClass_BOOLEAN: {
	    sal_Bool b;
	    a >>= b;
	    ret = b ? &PL_sv_yes : &PL_sv_no;
	    break;
	}

	case typelib_TypeClass_BYTE:
	case typelib_TypeClass_SHORT:
	case typelib_TypeClass_UNSIGNED_SHORT: 
	case typelib_TypeClass_LONG: {
	    long l;
	    a >>= l;
	    ret = newSViv(l);
	    break;
	}

	case typelib_TypeClass_UNSIGNED_LONG: { 
	    unsigned long l;
	    a >>= l;
	    ret = newSVuv(l);
	    break;
	} 

	case typelib_TypeClass_HYPER: {
	    sal_Int64 l;
	    a >>= l;
	    ret = newSViv(l);
	    break;
	}

	case typelib_TypeClass_UNSIGNED_HYPER: {
	    sal_uInt64 l;
	    a >>= l;
	    ret = newSVuv(l);
	    break;
	}

	case typelib_TypeClass_FLOAT: {
	    float f;
	    a >>= f;
	    ret = newSVnv(f);
	    break;
	}

	case typelib_TypeClass_DOUBLE: {
	    double d;
	    a >>= d;
	    ret = newSVnv(d);
	    break;
	}

	case typelib_TypeClass_STRING: {
	    ::rtl::OUString tmp_ostr;
	    a >>= tmp_ostr;

	    ::rtl::OString o = ::rtl::OUStringToOString(tmp_ostr, RTL_TEXTENCODING_UTF8);

	    ret = newSVpvn(o.getStr(), o.getLength());
	    SvUTF8_on(ret);
	    break;
	}

	case typelib_TypeClass_TYPE: {
	    ::com::sun::star::uno::Type t;
	    a >>= t;
	    ::rtl::OString o = ::rtl::OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
	    ret = SvRV(newSVpv(o.getStr(), (com::sun::star::uno::TypeClass)t.getTypeClass()));
	    break;
	}

	case typelib_TypeClass_ANY: {
	    croak("Any2SV: ANY type not supported yet");
	    break;
	}

	case typelib_TypeClass_ENUM: {
	    croak("Any2SV: ENUM type not supported yet");
	    break;
	}

	case typelib_TypeClass_EXCEPTION: {
	    UNO_Struct *tret = new UNO_Struct(a);
	    SV *mret = sv_newmortal();
	    ret = newRV_inc(mret);
	    sv_setref_pv(ret, "OpenOffice::UNO::Exception", (void *)tret);
	    break;
	}

	case typelib_TypeClass_STRUCT: {
	    UNO_Struct *tret = new UNO_Struct(a);
	    SV *mret = sv_newmortal();
	    ret = newRV_inc(mret);
	    sv_setref_pv(ret, "OpenOffice::UNO::Struct", (void *)tret);
	    break;
	}

	case typelib_TypeClass_SEQUENCE: {
	    UNO_SAny sa;
	    UNOInstance.typecvt->convertTo(a, ::getCppuType(&sa)) >>= sa;
	    ret = newRV_noinc((SV *)SAnyToAV(sa));
	    break;
	}

	case typelib_TypeClass_INTERFACE: {
	    UNO_Interface *tret = new UNO_Interface(a);
	    SV *mret = sv_newmortal();
	    ret = newRV_inc(mret);
	    sv_setref_pv(ret, "OpenOffice::UNO::Interface", (void *)tret);
	    break;
	}

	default: {
	    croak("Any2SV: Error Unknown Any type");
	    ret = Nullsv;
	    break;
	}
    }
    return ret;
}

UNO_Boolean::UNO_Boolean() {
    sal_Bool b = sal_False;
    pany = UNO_XAny(&b, getBooleanCppuType());
    bvalue = sal_False;
}

UNO_Boolean::UNO_Boolean(SV *bval) {
    dTHX;
    sal_Bool b = (sal_Bool)SvTRUE(bval);
    pany = UNO_XAny(&b, getBooleanCppuType());
    bvalue = b;
}

UNO_Boolean::~UNO_Boolean() {
}

UNO_Int32::UNO_Int32() {
    sal_Int32 i = 0;
    pany = UNO_XAny(&i, getCppuType(&i));
    ivalue = 0;
}

UNO_Int32::UNO_Int32(SV *ival) {
    dTHX;
    sal_Int32 i = (sal_Int32)SvIV(ival);
    pany = UNO_XAny(&i, getCppuType(&i));
    ivalue = i;
}

UNO_Int32::~UNO_Int32() {
}

UNO_Int64::UNO_Int64() {
    sal_Int64 i = 0;
    pany = UNO_XAny(&i, getCppuType(&i));
    ivalue = 0;
}

UNO_Int64::UNO_Int64(SV *ival) {
    dTHX;
    sal_Int64 i = (sal_Int64)SvIV(ival);
    pany = UNO_XAny(&i, getCppuType(&i));
    ivalue = i;
}

UNO_Int64::~UNO_Int64() {
}

MODULE = OpenOffice::UNO     	PACKAGE = OpenOffice::UNO	PREFIX = UNO_

PROTOTYPES: DISABLE

BOOT:
    Bootstrap(aTHX);

UNO *
UNO::new(...)
CODE:
{
    RETVAL = new UNO();
}
OUTPUT:
    RETVAL

void
UNO::DESTROY(...)
CODE:
{
    delete(THIS);
}

UNO_Interface *
UNO::createInitialComponentContext(...)
CODE:
{
    if ( items == 1 ) {
	RETVAL = THIS->createInitialComponentContext();
    } else if ( items == 2 ) {
	char *iniFile;
	STRLEN len;

	iniFile = SvPV(ST(1), len);
	RETVAL = THIS->createInitialComponentContext(iniFile);
    }
}
OUTPUT:
    RETVAL

UNO_Struct *
UNO::createIdlStruct(...)
CODE:
{
    char *name;
    STRLEN len;

    name = SvPV(ST(1), len);
    UNO_Struct *tret = THIS->createIdlStruct(name);
    RETVAL = tret;
}
OUTPUT:
    RETVAL

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Any	PREFIX = UNO_

UNO_Any *
UNO_Any::new(type, value)
    char *type
    SV *value
CODE:
{
    UNO_Any *any = new UNO_Any(type);
    UNO_XAny from = SVToAny(value);

    ::com::sun::star::uno::Type t = any->getAny().getValueType();
    try {
        any->assignAny(UNOInstance.typecvt->convertTo(from, t));
    } catch(::com::sun::star::uno::Exception& e) {
        UNOCroak(aTHX_ e);
    }

    RETVAL = any;
}
OUTPUT:
    RETVAL

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Interface	PREFIX = UNO_

UNO_Interface *
UNO_Interface::new(...)
CODE:
{
    UNO_Interface *retval;
    
    retval = new UNO_Interface();

    RETVAL = retval;
}
OUTPUT:
    RETVAL

SV *
UNO_Interface::AUTOLOAD(...)
CODE:
{
    CV *method = get_cv("OpenOffice::UNO::Interface::AUTOLOAD", 0);

    I32 i;
    UNO_SAny args;

    if ( items > 1 ) {
	args.realloc(items-1);
	for ( i = 1; i < items; i++ ) {
	    UNO_XAny a = SVToAny(ST(i));
	    args[i-1] <<= a;
	}
    }

    RETVAL = THIS->invoke(SvPVX(method), args);
}
OUTPUT:
    RETVAL

void
UNO_Interface::DESTROY(...)
CODE:
{
    delete(THIS);
}

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Struct	PREFIX = UNO_

UNO_Struct *
UNO_Struct::new(...)
CODE:
{
    UNO_Struct *ret;

    ret = (UNO_Struct *)NULL;
    if ( items == 2 ) {
	char *stype;
	STRLEN len;

	stype = SvPV(ST(1), len);
	ret = new UNO_Struct(stype);
    }
    RETVAL = ret;
}
OUTPUT:
    RETVAL

void
UNO_Struct::DESTROY(...)
CODE:
{
    delete(THIS);
}

SV *
UNO_Struct::AUTOLOAD(...)
CODE:
{
    CV *member = get_cv("OpenOffice::UNO::Struct::AUTOLOAD", 0);
    char *mname;

    mname = SvPVX(member);

    SV *ret;

    ret = Nullsv;
    // Distinguish between "set" and "get" accessor
    if ( items == 2 ) {	// If "set"
	THIS->set(mname, ST(1));
    } else {	// If "get"
	ret = THIS->get(mname);
    }

    RETVAL = ret;
}
OUTPUT:
    RETVAL

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Boolean	PREFIX = UNO_

UNO_Boolean *
UNO_Boolean::new(...)
CODE:
{
    if ( items == 2 ) {
        RETVAL = new UNO_Boolean(ST(1));
    } else {
        RETVAL = new UNO_Boolean();
    }
}
OUTPUT:
    RETVAL

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Int32	PREFIX = UNO_

UNO_Int32 *
UNO_Int32::new(...)
CODE:
{
    if ( items == 2 ) {
        RETVAL = new UNO_Int32(ST(1));
    } else {
        RETVAL = new UNO_Int32();
    }
}
OUTPUT:
    RETVAL

MODULE = OpenOffice::UNO	PACKAGE = OpenOffice::UNO::Int64	PREFIX = UNO_

UNO_Int64 *
UNO_Int64::new(...)
CODE:
{
    if ( items == 2 ) {
        RETVAL = new UNO_Int64(ST(1));
    } else {
        RETVAL = new UNO_Int64();
    }
}
OUTPUT:
    RETVAL