6
#include "kscript_corbafunc.h"
7
#include "kscript_util.h"
8
#include "kscript_struct.h"
9
#include "kscript_proxy.h"
10
#include "kscript_types.h"
12
#include "kscript_parsenode.h"
16
/**********************************
18
* Marshalling and Demarshalling
20
**********************************/
23
* Unpack an Any in a KSValue
25
bool ksUnpack( KSContext& context, KSValue* _arg, CORBA::Any& _any, CORBA::TypeCode_ptr _tc )
34
// TODO: CORBA::Any support
35
/* PyObject* pany = pm_module->newAny();
38
cerr << "ERROR: Could not create a new any" << endl;
42
CORBA::Any* any = new CORBA::Any();
45
PyObject* p_id = Py_BuildValue( "i", id );
46
PyObject_SetAttrString( pany, "_any_id_", p_id );
54
assert( _any.enum_get( i ) );
55
_arg->setValue( QString( _tc->member_name( i ) ) );
58
case CORBA::tk_string:
61
bool res = ( _any >>= CORBA::Any::to_string( text, 0 ) );
63
_arg->setValue( QString( text ) );
69
bool erg = ( _any >>= x );
71
_arg->setValue( (KScript::Long)x );
74
case CORBA::tk_ushort:
77
bool erg = ( _any >>= x );
79
_arg->setValue( (KScript::Long)x );
85
bool erg = ( _any >>= x );
87
_arg->setValue( (KScript::Long)x );
93
bool erg = ( _any >>= x );
95
_arg->setValue( (KScript::Long)x );
101
bool erg = ( _any >>= x );
103
_arg->setValue( (KScript::Double)x );
106
case CORBA::tk_double:
109
bool erg = ( _any >>= x );
111
_arg->setValue( (KScript::Double)x );
114
case CORBA::tk_objref:
117
if ( !( _any >>= CORBA::Any::to_object( x ) ) )
120
if ( CORBA::is_nil( x ) )
126
if ( !x->_is_a( _tc->id() ) )
128
QString tmp( i18n("While unpacking a CORBA datatype, an object of type %1 was expected, but %2 was found") );
129
context.setException( new KSException( "UnpackingError", tmp.arg( _tc->id() ).arg( x->_repoid() ) ) );
133
// We try to instantiate the most specialized interface.
134
// Please mention that C++-Corba does not do that, but since we
135
// are dynamically typed ...
136
KSValue *c = context.interpreter()->repoidImplementation( x->_repoid() );
138
c = context.interpreter()->repoidImplementation( _tc->id() );
140
if ( !c || !c->type() == KSValue::InterfaceType )
142
QString tmp(i18n( "Did not find an interface for the repoid %1. Seems to be an error of the idl compiler.") );
143
context.setException( new KSException( "UnpackingError", tmp.arg( _tc->id() ) ) );
147
KSProxy* proxy = c->interfaceValue()->constructor( (CORBA::Object*)x );
149
_arg->setValue( proxy );
152
case CORBA::tk_TypeCode:
154
CORBA::TypeCode_ptr x;
155
bool erg = ( _any >>= x );
157
_arg->setValue( new KSTypeCode( (CORBA::TypeCode*)x ) );
160
case CORBA::tk_boolean:
163
bool erg = ( _any >>= CORBA::Any::to_boolean( x ) );
165
_arg->setValue( (KScript::Boolean)x );
168
case CORBA::tk_octet:
171
bool erg = ( _any >>= CORBA::Any::to_octet( x ) );
173
_arg->setValue( (KScript::Long)x );
179
bool erg = ( _any >>= CORBA::Any::to_char( x ) );
184
_arg->setValue( QString( buf ) );
187
case CORBA::tk_sequence:
190
assert( _any.seq_get_begin( len ) );
191
CORBA::TypeCode_var ctc = _tc->content_type();
193
QValueList<KSValue::Ptr> lst;
195
for( CORBA::ULong i = 0; i < len; i++ )
197
KSValue::Ptr v = new KSValue;
198
if ( !ksUnpack( context, v, _any, ctc ) )
202
assert( _any.seq_get_end() );
204
_arg->setValue( lst );
207
case CORBA::tk_struct:
209
KSValue *c = context.interpreter()->repoidImplementation( _tc->id() );
211
if ( !c || !c->type() == KSValue::StructClassType )
213
QString tmp( i18n("Did not find a struct for the repoid %1. Seems to be an error of the idl compiler.") );
214
context.setException( new KSException( "UnpackingError", tmp.arg( _tc->id() ) ) );
218
KSStruct::Ptr s = c->structClassValue()->constructor();
220
CORBA::ULong len = _tc->member_count();
221
assert( _any.struct_get_begin() );
222
for( CORBA::ULong i = 0; i < len; i++ )
224
CORBA::TypeCode_var ntc = _tc->member_type( i );
225
KSValue::Ptr m = new KSValue;
226
if ( !ksUnpack( context, m, _any, ntc ) )
228
if ( !s->setMember( context, _tc->member_name( i ), m ) )
231
assert( _any.struct_get_end() );
234
_arg->setValue( &*s );
237
case CORBA::tk_except:
239
KSValue *c = context.interpreter()->repoidImplementation( _tc->id() );
241
if ( !c || !c->type() == KSValue::StructClassType )
243
QString tmp( i18n("Did not find a struct for the repoid %1. Seems to be an error of the idl compiler.") );
244
context.setException( new KSException( "UnpackingError", tmp.arg( _tc->id() ) ) );
248
KSStruct::Ptr s = c->structClassValue()->constructor();
250
CORBA::ULong len = _tc->member_count();
251
CORBA::String_var repoid;
252
assert( _any.except_get_begin( repoid ) );
253
for( CORBA::ULong i = 0; i < len; i++ )
255
CORBA::TypeCode_var ntc = _tc->member_type( i );
256
KSValue::Ptr m = new KSValue;
257
if ( !ksUnpack( context, m, _any, ntc ) )
259
if ( !s->setMember( context, _tc->member_name( i ), m ) )
262
assert( _any.except_get_end() );
265
_arg->setValue( &*s );
268
case CORBA::tk_union:
272
cerr << "Extracting Union " << _tc->id() << endl;
273
CORBA::TypeCode_var dt = _tc->discriminator_type();
274
CORBA::Long defidx = _tc->default_index();
276
assert( _any.union_get_begin() );
278
PyObject* disc = parseResult( _any, dt );
283
cerr << "ERROR: Could not extract discriminator of union " << _tc->id() << endl;
286
for ( idx = 0; idx < _tc->member_count(); idx++ )
288
if ( defidx != -1 && (CORBA::ULong) defidx == idx )
291
CORBA::Any_var lany = _tc->member_label( idx );
292
PyObject* label = parseResult( *lany, dt );
295
cerr << "ERROR: Could not extract label of union " << _tc->id() << endl;
298
if ( PyObject_Compare( label, disc ) == 0 )
311
CORBA::TypeCode_var mtype = _tc->member_type( idx );
312
assert( _any.union_get_selection( idx ) );
313
PyObject* memb = parseResult( _any, mtype );
316
cerr << "ERROR: Could not extract value of union " << _tc->id() << endl;
319
uni = pm_module->newUnion();
321
PyObject_SetAttrString( uni, "d", disc );
322
PyObject_SetAttrString( uni, "v", memb );
324
else if ( defidx == -1 )
326
uni = pm_module->newUnion();
328
PyObject_SetAttrString( uni, "d", Py_None );
329
PyObject_SetAttrString( uni, "v", Py_None );
333
assert( defidx != -1 );
334
CORBA::TypeCode_var deftype = _tc->member_type( (CORBA::ULong) defidx);
335
assert( _any.union_get_selection( defidx ) );
336
uni = pm_module->newUnion();
338
PyObject* memb = parseResult( _any, deftype );
341
cerr << "ERROR: Could not extract value of union " << _tc->id() << " using default discriminator" << endl;
344
PyObject_SetAttrString( uni, "d", Py_None );
345
PyObject_SetAttrString( uni, "v", memb );
348
assert( _any.union_get_end() );
352
case CORBA::tk_alias:
354
const CORBA::TypeCode_var ntc = _tc->content_type();
355
return ksUnpack( context, _arg, _any, ntc );
358
printf( "INTERNAL ERROR: Did not handle tk_XXXX=%i", (int)_tc->kind() );
366
* Pack a KScript value into a Any
368
bool ksPack( KSContext& context, CORBA::Any& _any, KSValue* _arg, CORBA::TypeCode_ptr _tc )
370
switch( _tc->kind() )
376
// TODO: Need any support
377
// _any <<= *(it->second);
382
if ( !KSUtil::checkType( context, _arg, KSValue::StringType ) )
385
const char* value = _arg->stringValue().ascii();
386
for ( CORBA::ULong i = 0; i < _tc->member_count(); i++ )
388
if ( strcmp( value, (char *) _tc->member_name (i) ) == 0 )
390
assert( _any.enum_put( i ) );
395
QString tmp( i18n("The value %1 is not a known enumerator\nPossible values are:\n") );
396
for ( CORBA::ULong i = 0; i < _tc->member_count(); i++ )
398
tmp += _tc->member_name(i);
401
context.setException( new KSException( "UnknownEnumerator", tmp.arg( value ) ) );
404
case CORBA::tk_string:
406
if ( !KSUtil::checkType( context, _arg, KSValue::StringType ) )
408
_any <<= CORBA::Any::from_string( (char *) _arg->stringValue().ascii(), 0 );
411
case CORBA::tk_short:
413
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
415
CORBA::Short x = _arg->intValue();
419
case CORBA::tk_ushort:
421
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
423
CORBA::UShort x = _arg->intValue();
429
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
431
CORBA::Long x = _arg->intValue();
435
case CORBA::tk_longlong:
437
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
439
CORBA::LongLong x = _arg->intValue();
443
case CORBA::tk_ulong:
445
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
447
CORBA::ULong x = _arg->intValue();
451
case CORBA::tk_double:
453
if ( !KSUtil::checkType( context, _arg, KSValue::DoubleType ) )
455
CORBA::Double x = _arg->doubleValue();
459
case CORBA::tk_float:
461
if ( !KSUtil::checkType( context, _arg, KSValue::DoubleType ) )
463
CORBA::Float x = _arg->doubleValue();
467
case CORBA::tk_longdouble:
469
if ( !KSUtil::checkType( context, _arg, KSValue::DoubleType ) )
471
CORBA::LongDouble x = _arg->doubleValue();
475
case CORBA::tk_boolean:
477
if ( !KSUtil::checkType( context, _arg, KSValue::BoolType ) )
479
CORBA::Boolean x = _arg->boolValue();
480
_any <<= CORBA::Any::from_boolean( x );
485
if ( !KSUtil::checkType( context, _arg, KSValue::StringType ) )
487
QString value = _arg->stringValue();
488
if ( value.length() != 1 )
490
KSUtil::castingError( context, "multi-character String", "Character" );
493
CORBA::Char x = *value.ascii();
494
_any <<= CORBA::Any::from_char( x );
497
case CORBA::tk_octet:
499
if ( !KSUtil::checkType( context, _arg, KSValue::IntType ) )
501
CORBA::Octet x = _arg->intValue();
502
_any <<= CORBA::Any::from_octet( x );
505
case CORBA::tk_TypeCode:
507
if ( !KSUtil::checkType( context, _arg, KSValue::TypeCodeType ) )
509
_any <<= (CORBA::TypeCode*)_arg->typeCodeValue()->tc();
512
case CORBA::tk_objref:
514
if ( !KSUtil::checkType( context, _arg, KSValue::ProxyType ) )
516
CORBA::Object_ptr obj = (CORBA::Object*)_arg->proxyValue()->object();
517
// TODO: Handle None here
518
// if ( _arg == Py_None )
520
// _any <<= CORBA::Any::from_object( obj, _tc->name() );
524
if ( !obj->_is_a( _tc->id() ) )
526
KSUtil::castingError( context, obj->_repoid(), _tc->id() );
529
_any <<= CORBA::Any::from_object( obj, _tc->name() );
532
case CORBA::tk_sequence:
534
if ( !KSUtil::checkType( context, _arg, KSValue::ListType ) )
537
const CORBA::TypeCode_var ctc = _tc->content_type();
539
CORBA::ULong len = _arg->listValue().count();
540
assert( _any.seq_put_begin( len ) );
541
QValueList<KSValue::Ptr>::Iterator it = _arg->listValue().begin();
542
for ( CORBA::ULong i = 0; i < len; i++ )
544
if ( !ksPack( context, _any, *it, ctc ) )
547
assert( _any.seq_put_end() );
550
case CORBA::tk_struct:
552
if ( !KSUtil::checkType( context, _arg, KSValue::StructType ) )
555
assert( _any.struct_put_begin() );
556
CORBA::ULong len = _tc->member_count();
557
for( CORBA::ULong i = 0; i < len; i++ )
559
const CORBA::TypeCode_var ntc = _tc->member_type( i );
560
KSValue::Ptr v = _arg->structValue()->member( context, _tc->member_name( i ) );
563
QString tmp( i18n("The struct misses the member %1") );
564
context.setException( new KSException( "MissingMember", tmp.arg( _tc->member_name( i ) ) ) );
567
if ( !ksPack( context, _any, v, ntc ) )
570
assert( _any.struct_put_end() );
573
case CORBA::tk_union:
578
cerr << "Packing Union " << _tc->id() << endl;
580
CORBA::TypeCode_var dt = _tc->discriminator_type();
581
CORBA::Long defidx = _tc->default_index();
582
assert( _any.union_put_begin() );
586
PyObject* disc = PyObject_GetAttrString( _arg, "d" );
587
if ( disc == 0L || disc == Py_None )
589
cerr << "ERROR: Can not pack union " << _tc->id() << " because the descriminator is not set" << endl;
592
for ( idx = 0; idx < _tc->member_count(); idx++ )
594
if ( defidx != -1 && (CORBA::ULong) defidx == idx )
597
CORBA::Any_var lany = _tc->member_label( idx );
598
PyObject* label = parseResult( *lany, dt );
601
cerr << "ERROR: Could not extract label of union " << _tc->id() << endl;
604
if ( PyObject_Compare( label, disc ) == 0 )
613
if ( !parseResult( _any, disc, dt ) )
615
cerr << "ERROR: Could not pack discriminator for union " << _tc->id() << endl;
619
PyObject* value = PyObject_GetAttrString( _arg, "v" );
623
CORBA::TypeCode_var mtype = _tc->member_type( idx );
624
assert( _any.union_put_selection( idx ) );
625
if ( !parseResult( _any, value, mtype ) )
627
cerr << "ERROR: Could not pack value for union " << _tc->id() << endl;
631
else if ( defidx == -1 )
633
// Do not pack any value at all
637
CORBA::TypeCode_var mtype = _tc->member_type( idx );
638
assert( _any.union_put_selection( idx ) );
639
if ( !parseResult( _any, value, mtype ) )
641
cerr << "ERROR: Could not pack value for union " << _tc->id() << endl;
646
assert( _any.union_put_end() );
650
case CORBA::tk_alias:
652
const CORBA::TypeCode_var ntc = _tc->content_type();
653
return ksPack( context, _any, _arg, ntc );
656
* Not handled here ...
657
* tk_array, tk_alias, tk_except,
659
/* if ( _t == CORBA::_tc_wchar )
660
if ( _t == CORBA::_tc_wstring )
661
if ( _t == CORBA::_tc_Principal )
662
if ( _t == CORBA::_tc_Context ) */
668
/**************************************
672
**************************************/
674
KSCorbaFunc::KSCorbaFunc( KSModule* m, KSParseNode* node )
675
: KSFunction( m ), m_node( node )
677
m_name = node->getIdent();
680
bool KSCorbaFunc::init( KSContext& context )
682
// Did we already initialize ?
686
KSContext d( context );
688
// Get the return type
689
ASSERT( m_node->branch1() );
690
if ( !m_node->branch1()->eval( d ) )
692
context.setException( d );
696
KSTypeCode::Ptr tc = KSTypeCode::typeCode( context, d.value() );
700
setReturnTypeCode( tc );
703
d.setValue( new KSValue( this ) );
705
ASSERT( d.value() && d.value()->type() == KSValue::FunctionType );
706
// Get the list of parameters
707
if ( m_node->branch2() )
709
if ( !m_node->branch2()->eval( d ) )
711
context.setException( d );
716
// Get the list of exceptions
717
if ( m_node->branch3() )
719
if ( !m_node->branch3()->eval( d ) )
721
context.setException( d );
726
// Save memory since the code is no longer needed
733
bool KSCorbaFunc::call( KSContext& context )
735
QValueList<KSValue::Ptr>& args = context.value()->listValue();
736
QValueList<KSValue::Ptr>::Iterator it = args.begin();
738
if ( !init( context) )
741
uint params = m_parameters.count();
742
// "params+1" because the object itself is passes as first parameter
743
if ( !KSUtil::checkArgumentsCount( context, params + 1, m_name ) )
747
if ( !KSUtil::checkType( context, *it, KSValue::ProxyType ) )
750
KSProxy* proxy = (*it)->proxyValue();
751
CORBA::Object_ptr obj = (CORBA::Object*)proxy->object();
754
CORBA::Request_var req = obj->_request( m_name );
755
req->result()->value()->type( (CORBA::TypeCode*)m_returnTypeCode->tc() );
759
QValueList<Parameter>::Iterator pit = m_parameters.begin();
760
for( ; pit != m_parameters.end(); ++pit, ++it, ++i )
762
CORBA::Any any( (CORBA::TypeCode*)(*pit).typecode->tc(), (void*)NULL );
763
if ( !ksPack( context, any, *it, (CORBA::TypeCode*)(*pit).typecode->tc() ) )
765
if ( (*pit).mode == T_IN )
766
req->add_in_arg( (*pit).name.ascii() ) = any;
767
else if ( (*pit).mode == T_INOUT )
768
req->add_inout_arg( (*pit).name.ascii() ) = any;
769
else if ( (*pit).mode == T_OUT )
771
req->add_out_arg( (*pit).name.ascii() );
772
req->arguments()->item( i )->value()->type( (CORBA::TypeCode*)(*pit).typecode->tc() );
779
// Check for exceptions
780
if ( req->env()->exception() )
782
CORBA::Exception *_ex = req->env()->exception();
783
CORBA::UnknownUserException *_uuex = CORBA::UnknownUserException::_downcast( _ex );
786
KSValue* s = context.interpreter()->repoidImplementation( _uuex->_except_repoid() );
787
if ( s && s->type() == KSValue::StructClassType )
789
KSTypeCode::Ptr tc = KSTypeCode::typeCode( context, s );
793
KSValue::Ptr v = new KSValue;
794
// Unpack the exception
795
if ( !ksUnpack( context, v, _uuex->exception( (CORBA::TypeCode*)tc->tc() ), (CORBA::TypeCode*)tc->tc() ) )
798
// Emit a custom exception
800
context.setException( new KSException( s, v ) );
805
// Raise a default excpetion
806
QString tmp( i18n("An unexpected CORBA exception occured\n%1") );
807
context.setException( new KSException( "CORBAException", tmp.arg( _ex->_repoid() ), -1 ) );
811
// Unpack out/inout parameters
813
// Go to first parameter
816
pit = m_parameters.begin();
817
for( ; pit != m_parameters.end(); ++pit, ++it, ++i )
819
if ( (*pit).mode == T_INOUT || (*pit).mode == T_OUT )
821
if ( !ksUnpack( context, *it, *req->arguments()->item( i )->value(), (CORBA::TypeCode*)(*pit).typecode->tc() ) )
826
// Unpack the return value
827
KSValue::Ptr v = new KSValue;
828
if ( !ksUnpack( context, v, *req->result()->value(), (CORBA::TypeCode*)m_returnTypeCode->tc() ) )
830
context.setValue( v );
832
printf("YEAH, back from CORBA\n");
837
void KSCorbaFunc::addParameter( ParameterMode m, const QString& name, const KSTypeCode::Ptr &tc )
843
m_parameters.append( p );
846
void KSCorbaFunc::addException( const KSValue::Ptr& exc )
848
m_exceptions.append( exc );
851
void KSCorbaFunc::setReturnTypeCode( const KSTypeCode::Ptr& tc )
853
m_returnTypeCode = tc;