1 // -*- Mode: C++; -*-
2 //                            Package   : omniORBpy
3 // pyMarshal.cc               Created on: 1999/07/05
4 //                            Author    : Duncan Grisby (dpg1)
5 //
6 //    Copyright (C) 2002-2014 Apasphere Ltd
7 //    Copyright (C) 1999 AT&T Laboratories Cambridge
8 //
9 //    This file is part of the omniORBpy library
10 //
11 //    The omniORBpy library is free software; you can redistribute it
12 //    and/or modify it under the terms of the GNU Lesser General
13 //    Public License as published by the Free Software Foundation;
14 //    either version 2.1 of the License, or (at your option) any later
15 //    version.
16 //
17 //    This library is distributed in the hope that it will be useful,
18 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 //    GNU Lesser General Public License for more details.
21 //
22 //    You should have received a copy of the GNU Lesser General Public
23 //    License along with this library. If not, see http://www.gnu.org/licenses/
24 //
25 //
26 // Description:
27 //    Marshalling / unmarshalling of Python objects
28 
29 #include <omnipy.h>
30 #include <pyFixed.h>
31 #include <codeSetUtil.h>
32 
OMNI_USING_NAMESPACE(omni)33 OMNI_USING_NAMESPACE(omni)
34 
35 
36 // Small function to indicate whether a descriptor represents a type
37 // for which we have unrolled sequence marshalling code
38 static inline CORBA::Boolean
39 sequenceOptimisedType(PyObject* desc, CORBA::ULong& tk)
40 {
41   static CORBA::Boolean optmap[] = {
42     0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
43     1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44     0, 0, 0, 1, 1, 1, 0, 0, 0, 0,
45     0, 0, 0, 0
46   };
47 
48 #if (PY_VERSION_HEX < 0x03000000)
49 
50   if (PyInt_Check(desc)) {
51     tk = PyInt_AS_LONG(desc);
52     OMNIORB_ASSERT(tk <= 33);
53     return optmap[tk];
54   }
55 
56 #else
57 
58   if (PyLong_Check(desc)) {
59     tk = PyLong_AsLong(desc);
60     OMNIORB_ASSERT(tk <= 33);
61     return optmap[tk];
62   }
63 
64 #endif
65 
66   return 0;
67 }
68 
69 
70 
71 static void
validateTypeNull(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)72 validateTypeNull(PyObject* d_o, PyObject* a_o,
73 		 CORBA::CompletionStatus compstatus,
74 		 PyObject* track)
75 {
76   if (a_o != Py_None)
77     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
78 		       omniPy::formatString("Expecting None, got %r",
79 					    "O", a_o->ob_type));
80 }
81 
82 static void
validateTypeVoid(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)83 validateTypeVoid(PyObject* d_o, PyObject* a_o,
84 		 CORBA::CompletionStatus compstatus,
85 		 PyObject* track)
86 {
87   if (a_o != Py_None)
88     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
89 		       omniPy::formatString("Expecting None, got %r",
90 					    "O", a_o->ob_type));
91 }
92 
93 static void
validateTypeShort(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)94 validateTypeShort(PyObject* d_o, PyObject* a_o,
95 		  CORBA::CompletionStatus compstatus,
96 		  PyObject* track)
97 {
98   long l = 0;
99 
100 #if (PY_VERSION_HEX < 0x03000000)
101   if (PyInt_Check(a_o)) {
102     l = PyInt_AS_LONG(a_o);
103   }
104   else
105 #endif
106   if (PyLong_Check(a_o)) {
107     l = PyLong_AsLong(a_o);
108     if (l == -1 && PyErr_Occurred()) {
109       PyErr_Clear();
110       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
111 			 omniPy::formatString("%s is out of range for short",
112 					      "O", a_o));
113     }
114   }
115   else {
116     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
117 		       omniPy::formatString("Expecting short, got %r",
118 					    "O", a_o->ob_type));
119   }
120 
121   if (l < -0x8000 || l > 0x7fff) {
122     THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
123 		       omniPy::formatString("%s is out of range for short",
124 					    "O", a_o));
125   }
126 }
127 
128 static void
validateTypeLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)129 validateTypeLong(PyObject* d_o, PyObject* a_o,
130 		 CORBA::CompletionStatus compstatus,
131 		 PyObject* track)
132 {
133   long l = 0;
134 
135 #if (PY_VERSION_HEX < 0x03000000)
136   if (PyInt_Check(a_o)) {
137     l = PyInt_AS_LONG(a_o);
138   }
139   else
140 #endif
141   if (PyLong_Check(a_o)) {
142     l = PyLong_AsLong(a_o);
143     if (l == -1 && PyErr_Occurred()) {
144       PyErr_Clear();
145       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
146 			 omniPy::formatString("%s is out of range for long",
147 					      "O", a_o));
148     }
149   }
150   else {
151     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
152 		       omniPy::formatString("Expecting long, got %r",
153 					    "O", a_o->ob_type));
154   }
155 
156 #if SIZEOF_LONG > 4
157   if (l < -0x80000000L || l > 0x7fffffffL) {
158     THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
159 		       omniPy::formatString("%s is out of range for long",
160 					    "O", a_o));
161   }
162 #endif
163 }
164 
165 static void
validateTypeUShort(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)166 validateTypeUShort(PyObject* d_o, PyObject* a_o,
167 		   CORBA::CompletionStatus compstatus,
168 		   PyObject* track)
169 {
170   long l = 0;
171 
172 #if (PY_VERSION_HEX < 0x03000000)
173   if (PyInt_Check(a_o)) {
174     l = PyInt_AS_LONG(a_o);
175   }
176   else
177 #endif
178   if (PyLong_Check(a_o)) {
179     l = PyLong_AsLong(a_o);
180     if (l == -1 && PyErr_Occurred()) {
181       PyErr_Clear();
182       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
183 			 omniPy::formatString("%s is out of range for "
184 					      "unsigned short",
185 					      "O", a_o));
186     }
187   }
188   else {
189     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
190 		       omniPy::formatString("Expecting unsigned short, got %r",
191 					    "O", a_o->ob_type));
192   }
193 
194   if (l < 0 || l > 0xffff) {
195     THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
196 		       omniPy::formatString("%s is out of range for "
197 					    "unsigned short",
198 					    "O", a_o));
199   }
200 }
201 
202 static void
validateTypeULong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)203 validateTypeULong(PyObject* d_o, PyObject* a_o,
204 		  CORBA::CompletionStatus compstatus,
205 		  PyObject* track)
206 {
207   if (PyLong_Check(a_o)) {
208     unsigned long ul = PyLong_AsUnsignedLong(a_o);
209     if (ul == (unsigned long)-1 && PyErr_Occurred()) {
210       PyErr_Clear();
211       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
212 			 omniPy::formatString("%s is out of range for "
213 					      "unsigned long",
214 					      "O", a_o));
215     }
216 #if SIZEOF_LONG > 4
217     if (ul > 0xffffffffL) {
218       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
219 			 omniPy::formatString("%s is out of range for "
220 					      "unsigned long",
221 					      "O", a_o));
222     }
223 #endif
224   }
225 #if (PY_VERSION_HEX < 0x03000000)
226   else if (PyInt_Check(a_o)) {
227     long l = PyInt_AS_LONG(a_o);
228 #  if SIZEOF_LONG > 4
229     if (l < 0 || l > 0xffffffffL) {
230       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
231 			 omniPy::formatString("%s is out of range for "
232 					      "unsigned long",
233 					      "O", a_o));
234     }
235 #  else
236     if (l < 0) {
237       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
238 			 omniPy::formatString("%s is out of range for "
239 					      "unsigned long",
240 					      "O", a_o));
241     }
242 #  endif
243   }
244 #endif
245   else {
246     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
247 		       omniPy::formatString("Expecting unsigned long, got %r",
248 					    "O", a_o->ob_type));
249   }
250 }
251 
252 static void
validateTypeFloat(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)253 validateTypeFloat(PyObject* d_o, PyObject* a_o,
254 		  CORBA::CompletionStatus compstatus,
255 		  PyObject* track)
256 {
257 #if (PY_VERSION_HEX < 0x03000000)
258   if (PyFloat_Check(a_o) || PyInt_Check(a_o))
259     return;
260 #else
261   if (PyFloat_Check(a_o))
262     return;
263 #endif
264 
265   if (PyLong_Check(a_o)) {
266     double d = PyLong_AsDouble(a_o);
267     if (d == -1.0 && PyErr_Occurred()) {
268       PyErr_Clear();
269       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
270 			 omniPy::formatString("%s is out of range for float",
271 					      "O", a_o));
272     }
273   }
274   else {
275     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
276 		       omniPy::formatString("Expecting float, got %r",
277 					    "O", a_o->ob_type));
278   }
279 }
280 
281 static void
validateTypeDouble(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)282 validateTypeDouble(PyObject* d_o, PyObject* a_o,
283 		   CORBA::CompletionStatus compstatus,
284 		   PyObject* track)
285 {
286 #if (PY_VERSION_HEX < 0x03000000)
287   if (PyFloat_Check(a_o) || PyInt_Check(a_o))
288     return;
289 #else
290   if (PyFloat_Check(a_o))
291     return;
292 #endif
293 
294   if (PyLong_Check(a_o)) {
295     double d = PyLong_AsDouble(a_o);
296     if (d == -1.0 && PyErr_Occurred()) {
297       PyErr_Clear();
298       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
299 			 omniPy::formatString("%s is out of range for double",
300 					      "O", a_o));
301     }
302   }
303   else {
304     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
305 		       omniPy::formatString("Expecting double, got %r",
306 					    "O", a_o->ob_type));
307   }
308 }
309 
310 static void
validateTypeBoolean(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)311 validateTypeBoolean(PyObject* d_o, PyObject* a_o,
312 		    CORBA::CompletionStatus compstatus,
313 		    PyObject* track)
314 {
315   if (PyObject_IsTrue(a_o) == -1) {
316     if (omniORB::trace(1))
317       PyErr_Print();
318     else
319       PyErr_Clear();
320 
321     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
322 		       omniPy::formatString("Expecting bool, got %r",
323 					    "O", a_o->ob_type));
324   }
325 }
326 
327 static void
validateTypeChar(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)328 validateTypeChar(PyObject* d_o, PyObject* a_o,
329 		 CORBA::CompletionStatus compstatus,
330 		 PyObject* track)
331 {
332   if (!String_Check(a_o)) {
333     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
334 		       omniPy::formatString("Expecting string, got %r",
335 					    "O", a_o->ob_type));
336   }
337   if (String_GET_SIZE(a_o) != 1) {
338     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
339 		       omniPy::formatString("Expecting string of length 1, "
340 					    "got %r",
341 					    "O", a_o));
342   }
343 
344 #if (PY_VERSION_HEX >= 0x03030000) // Python 3.3 or later
345   Py_UCS4 uc = PyUnicode_READ_CHAR(a_o, 0);
346   if (uc > 255)
347     OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar, compstatus);
348 
349 #elif (PY_VERSION_HEX >= 0x03000000) // Python 3.0 - 3.2
350   Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
351   if (*us > 255)
352     OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar, compstatus);
353 #endif
354 }
355 
356 static void
validateTypeOctet(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)357 validateTypeOctet(PyObject* d_o, PyObject* a_o,
358 		  CORBA::CompletionStatus compstatus,
359 		  PyObject* track)
360 {
361   long l = 0;
362 
363 #if (PY_VERSION_HEX < 0x03000000)
364   if (PyInt_Check(a_o)) {
365     l = PyInt_AS_LONG(a_o);
366   }
367   else
368 #endif
369   if (PyLong_Check(a_o)) {
370     l = PyLong_AsLong(a_o);
371     if (l == -1 && PyErr_Occurred()) {
372       PyErr_Clear();
373       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
374 			 omniPy::formatString("%s is out of range for octet",
375 					      "O", a_o));
376     }
377   }
378   else {
379     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
380 		       omniPy::formatString("Expecting octet, got %r",
381 					    "O", a_o->ob_type));
382   }
383 
384   if (l < 0 || l > 0xff) {
385     THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
386 		       omniPy::formatString("%s is out of range for octet",
387 					    "O", a_o));
388   }
389 }
390 
391 static void
validateTypeAny(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)392 validateTypeAny(PyObject* d_o, PyObject* a_o,
393 		CORBA::CompletionStatus compstatus,
394 		PyObject* track)
395 {
396   if (!PyObject_IsInstance(a_o, omniPy::pyCORBAAnyClass)) {
397     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
398 		       omniPy::formatString("Expecting Any, got %r",
399 					    "O", a_o->ob_type));
400   }
401 
402   // Validate TypeCode
403   omniPy::PyRefHolder t_o(PyObject_GetAttrString(a_o, (char*)"_t"));
404 
405   if (!t_o.valid()) {
406     PyErr_Clear();
407     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
408 		       String_FromString("Any has no TypeCode _t"));
409   }
410 
411   if (!PyObject_IsInstance(t_o, omniPy::pyCORBATypeCodeClass)) {
412     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
413 		       omniPy::formatString("Expecting TypeCode in Any, got %r",
414 					    "O", a_o->ob_type));
415   }
416 
417   omniPy::PyRefHolder desc(PyObject_GetAttrString(t_o, (char*)"_d"));
418   if (!desc.valid()) {
419     PyErr_Clear();
420     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
421 		       String_FromString("TypeCode in Any has no "
422                                          "descriptor _d"));
423   }
424 
425   // Any's contents
426   t_o = PyObject_GetAttrString(a_o, (char*)"_v");
427   if (!t_o.valid()) {
428     PyErr_Clear();
429     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
430 		       String_FromString("Any has no value _v"));
431   }
432   try {
433     omniPy::validateType(desc, t_o, compstatus, track);
434   }
435   catch (Py_BAD_PARAM& bp) {
436     bp.add(String_FromString("Value inside Any"));
437     throw;
438   }
439 }
440 
441 
442 static void
validateTypeTypeCode(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)443 validateTypeTypeCode(PyObject* d_o, PyObject* a_o,
444 		     CORBA::CompletionStatus compstatus,
445 		     PyObject* track)
446 {
447   if (!PyObject_IsInstance(a_o, omniPy::pyCORBATypeCodeClass)) {
448     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
449 		       omniPy::formatString("Expecting TypeCode, got %r",
450 					    "O", a_o->ob_type));
451   }
452   PyObject* t_o = PyObject_GetAttrString(a_o, (char*)"_d");
453 
454   if (!t_o) {
455     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
456 		       String_FromString("TypeCode in has no descriptor _d"));
457   }
458 
459   Py_DECREF(t_o);
460 }
461 
462 static void
validateTypePrincipal(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)463 validateTypePrincipal(PyObject* d_o, PyObject* a_o,
464 		      CORBA::CompletionStatus compstatus,
465 		      PyObject* track)
466 {
467   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
468 }
469 
470 
471 static void
validateTypeObjref(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)472 validateTypeObjref(PyObject* d_o, PyObject* a_o,
473 		   CORBA::CompletionStatus compstatus,
474 		   PyObject* track)
475 { // repoId, name
476   if (a_o != Py_None) {
477     CORBA::Object_ptr obj = omniPy::getObjRef(a_o);
478     if (!obj) {
479       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
480 			 omniPy::formatString("Expecting object reference, "
481 					      "got %r",
482 					      "O", a_o->ob_type));
483     }
484   }
485 }
486 
487 static void
validateTypeStruct(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)488 validateTypeStruct(PyObject* d_o, PyObject* a_o,
489 		   CORBA::CompletionStatus compstatus,
490 		   PyObject* track)
491 { // class, repoId, struct name, name, descriptor, ...
492 
493   // The descriptor tuple has twice the number of struct members,
494   // plus 4 -- the typecode kind, the Python class, the repoId,
495   // and the struct name
496   int                 i, j;
497   int                 cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
498   PyObject*           name;
499   omniPy::PyRefHolder value;
500 
501   for (i=0,j=4; i < cnt; i++,j++) {
502     name = PyTuple_GET_ITEM(d_o, j++);
503     OMNIORB_ASSERT(String_Check(name));
504 
505     value = PyObject_GetAttr(a_o, name);
506 
507     if (!value.valid()) {
508       PyErr_Clear();
509       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
510 			 omniPy::formatString("Struct %r instance %r "
511 					      "has no %r member",
512 					      "OOO",
513 					      PyTuple_GET_ITEM(d_o, 3),
514 					      a_o->ob_type,
515 					      name));
516     }
517     try {
518       omniPy::validateType(PyTuple_GET_ITEM(d_o, j), value, compstatus, track);
519     }
520     catch (Py_BAD_PARAM& bp) {
521       bp.add(omniPy::formatString("Struct %r member %r", "OO",
522 				  PyTuple_GET_ITEM(d_o, 3), name));
523       throw;
524     }
525   }
526 }
527 
528 static void
validateTypeUnion(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)529 validateTypeUnion(PyObject* d_o, PyObject* a_o,
530 		  CORBA::CompletionStatus compstatus,
531 		  PyObject* track)
532 { // class,
533   // repoId,
534   // name,
535   // discriminant descr,
536   // default used,
537   // ((label value, member name, member descr), ...),
538   // default (label, name, descr) or None,
539   // {label: (label, name, descr), ...}
540 
541   omniPy::PyRefHolder discriminant(PyObject_GetAttrString(a_o, (char*)"_d"));
542   if (!discriminant.valid()) {
543     PyErr_Clear();
544     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
545 		       omniPy::formatString("Expecting union, got %r",
546 					    "O", a_o->ob_type));
547   }
548 
549   omniPy::PyRefHolder value(PyObject_GetAttrString(a_o, (char*)"_v"));
550   if (!value.valid()) {
551     PyErr_Clear();
552     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
553 		       omniPy::formatString("Expecting union, got %r",
554 					    "O", a_o->ob_type));
555   }
556 
557   PyObject* t_o = PyTuple_GET_ITEM(d_o, 4); // Discriminant descriptor
558   try {
559     omniPy::validateType(t_o, discriminant, compstatus, track);
560   }
561   catch (Py_BAD_PARAM& bp) {
562     bp.add(String_FromString("Union discriminant"));
563     throw;
564   }
565 
566   PyObject* cdict = PyTuple_GET_ITEM(d_o, 8);
567   OMNIORB_ASSERT(PyDict_Check(cdict));
568 
569   t_o = PyDict_GetItem(cdict, discriminant);
570 
571   if (!t_o) {
572     // Discriminant not found in case dictionary. Is there a default case?
573     t_o = PyTuple_GET_ITEM(d_o, 7);
574     if (t_o == Py_None)
575       t_o = 0;
576   }
577   if (t_o) {
578     OMNIORB_ASSERT(PyTuple_Check(t_o));
579     try {
580       omniPy::validateType(PyTuple_GET_ITEM(t_o, 2), value, compstatus, track);
581     }
582     catch (Py_BAD_PARAM& bp) {
583       bp.add(omniPy::formatString("Union member %r", "O",
584 				  PyTuple_GET_ITEM(t_o, 1)));
585       throw;
586     }
587   }
588 }
589 
590 
591 static void
validateTypeEnum(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)592 validateTypeEnum(PyObject* d_o, PyObject* a_o,
593 		 CORBA::CompletionStatus compstatus,
594 		 PyObject* track)
595 { // repoId, name, item list
596 
597   omniPy::PyRefHolder ev(PyObject_GetAttrString(a_o, (char*)"_v"));
598 
599   if (!ev.valid()) {
600     PyErr_Clear();
601     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
602 		       omniPy::formatString("Expecting enum %r item, got %r",
603 					    "OO",
604 					    PyTuple_GET_ITEM(d_o, 2),
605 					    a_o->ob_type));
606   }
607 
608   PyObject* t_o = PyTuple_GET_ITEM(d_o, 3);
609 
610   CORBA::ULong e;
611   try {
612     e = omniPy::getULongVal(ev);
613   }
614   catch (Py_BAD_PARAM& bp) {
615     bp.add(omniPy::formatString("Expecting enum %r item, got %r",
616                                 "OO",
617                                 PyTuple_GET_ITEM(d_o, 2),
618                                 a_o));
619     throw;
620   }
621 
622   if (e >= PyTuple_GET_SIZE(t_o)) {
623     THROW_PY_BAD_PARAM(BAD_PARAM_EnumValueOutOfRange, compstatus,
624 		       omniPy::formatString("Expecting enum %r item, got %r",
625 					    "OO",
626 					    PyTuple_GET_ITEM(d_o, 2),
627 					    a_o));
628   }
629 
630   if (PyTuple_GET_ITEM(t_o, e) != a_o) {
631     // EnumItem object is not the one we expected -- are they equivalent?
632     int cmp;
633 
634 #if (PY_VERSION_HEX < 0x03000000)
635 
636     if (PyObject_Cmp(PyTuple_GET_ITEM(t_o, e), a_o, &cmp) == -1)
637       omniPy::handlePythonException();
638 
639     if (cmp != 0) {
640       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
641 			 omniPy::formatString("Expecting enum %r item, "
642 					      "got %r",
643 					      "OO",
644 					      PyTuple_GET_ITEM(d_o, 2),
645 					      a_o));
646     }
647 
648 #else
649     cmp = PyObject_RichCompareBool(PyTuple_GET_ITEM(t_o, e), a_o, Py_EQ);
650     if (cmp == -1)
651       omniPy::handlePythonException();
652 
653     if (cmp != 1) {
654       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
655 			 omniPy::formatString("Expecting enum %r item, "
656 					      "got %r",
657 					      "OO",
658 					      PyTuple_GET_ITEM(d_o, 2),
659 					      a_o));
660     }
661 #endif
662   }
663 }
664 
665 static void
validateTypeString(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)666 validateTypeString(PyObject* d_o, PyObject* a_o,
667 		   CORBA::CompletionStatus compstatus,
668 		   PyObject* track)
669 { // max_length
670 
671   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
672   OMNIORB_ASSERT(Int_Check(t_o));
673 
674   CORBA::ULong max_len = Int_AS_LONG(t_o);
675 
676   if (!String_Check(a_o)) {
677     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
678 		       omniPy::formatString("Expecting string, got %r",
679 					    "O", a_o->ob_type));
680   }
681 
682   CORBA::ULong len;
683   const char*  str = String_AS_STRING_AND_SIZE(a_o, len);
684 
685   if (max_len > 0 && len > max_len)
686     OMNIORB_THROW(MARSHAL, MARSHAL_StringIsTooLong, compstatus);
687 
688   // Annoyingly, we have to scan the string to check there are no
689   // nulls
690   for (CORBA::ULong i=0; i<len; i++) {
691     if (str[i] == '\0') {
692       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
693 			 omniPy::formatString("Embedded null in string "
694 					      "at position %d",
695 					      "i", i));
696     }
697   }
698 }
699 
700 
701 static inline
listGet(PyObject * lst,CORBA::ULong idx)702 PyObject* listGet(PyObject* lst, CORBA::ULong idx)
703 {
704   return PyList_GET_ITEM(lst, idx);
705 }
706 
707 static inline
tupleGet(PyObject * lst,CORBA::ULong idx)708 PyObject* tupleGet(PyObject* lst, CORBA::ULong idx)
709 {
710   return PyTuple_GET_ITEM(lst, idx);
711 }
712 
713 template<class G>
714 static inline void
validateOptSequenceItems(CORBA::ULong len,PyObject * a_o,CORBA::ULong etk,CORBA::CompletionStatus compstatus,const char * seq_arr,G getFn)715 validateOptSequenceItems(CORBA::ULong            len,
716                          PyObject*               a_o,
717                          CORBA::ULong            etk,
718                          CORBA::CompletionStatus compstatus,
719                          const char*             seq_arr,
720                          G                       getFn)
721 {
722   CORBA::ULong  i;
723   PyObject*     t_o;
724   long          long_val   = 0;
725   unsigned long ulong_val  = 0;
726   double        double_val = 0.0;;
727 
728   switch (etk) {
729 
730   case CORBA::tk_short:
731 
732     for (i=0; i<len; i++) {
733       t_o = getFn(a_o, i);
734 
735 #if (PY_VERSION_HEX < 0x03000000)
736       if (PyInt_Check(t_o)) {
737         long_val = PyInt_AS_LONG(t_o);
738       }
739       else
740 #endif
741       if (PyLong_Check(t_o)) {
742         long_val = PyLong_AsLong(t_o);
743         if (long_val == -1 && PyErr_Occurred()) {
744           PyErr_Clear();
745           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
746                              omniPy::formatString("%s item %d: "
747                                                   "%s is out of range for "
748                                                   "short", "siO",
749                                                   seq_arr, i, t_o));
750         }
751       }
752       else {
753         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
754                            omniPy::formatString("%s item %d: "
755                                                 "expecting short, "
756                                                 "got %r", "siO",
757                                                 seq_arr, i, t_o->ob_type));
758       }
759 
760       if (long_val < -0x8000 || long_val > 0x7fff) {
761         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
762                            omniPy::formatString("%s item %d: "
763                                                 "%s is out of range for "
764                                                 "short", "siO",
765                                                 seq_arr, i, t_o));
766       }
767     }
768     return;
769 
770   case CORBA::tk_long:
771 
772     for (i=0; i<len; i++) {
773       t_o = getFn(a_o, i);
774 
775 #if (PY_VERSION_HEX < 0x03000000)
776       if (PyInt_Check(t_o)) {
777         long_val = PyInt_AS_LONG(t_o);
778       }
779       else
780 #endif
781       if (PyLong_Check(t_o)) {
782         long_val = PyLong_AsLong(t_o);
783         if (long_val == -1 && PyErr_Occurred()) {
784           PyErr_Clear();
785           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
786                              omniPy::formatString("%s item %d: "
787                                                   "%s is out of range for "
788                                                   "long", "siO",
789                                                   seq_arr, i, t_o));
790         }
791       }
792       else {
793         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
794                            omniPy::formatString("%s item %d: "
795                                                 "expecting long, "
796                                                 "got %r", "siO",
797                                                 seq_arr, i, t_o->ob_type));
798       }
799 
800 #if SIZEOF_LONG > 4
801       if (long_val < -0x80000000L || long_val > 0x7fffffffL) {
802         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
803                            omniPy::formatString("%s item %d: "
804                                                 "%s is out of range for "
805                                                 "long", "siO",
806                                                 seq_arr, i, t_o));
807       }
808 #endif
809     }
810     return;
811 
812   case CORBA::tk_ushort:
813 
814     for (i=0; i<len; i++) {
815       t_o = getFn(a_o, i);
816 
817 #if (PY_VERSION_HEX < 0x03000000)
818       if (PyInt_Check(t_o)) {
819         long_val = PyInt_AS_LONG(t_o);
820       }
821       else
822 #endif
823       if (PyLong_Check(t_o)) {
824         long_val = PyLong_AsLong(t_o);
825         if (long_val == -1 && PyErr_Occurred()) {
826           PyErr_Clear();
827           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
828                              omniPy::formatString("%s item %d: "
829                                                   "%s is out of range for "
830                                                   "unsigned short", "siO",
831                                                   seq_arr, i, t_o));
832         }
833       }
834       else {
835         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
836                            omniPy::formatString("%s item %d: "
837                                                 "expecting unsigned short, "
838                                                 "got %r","siO",
839                                                 seq_arr, i, t_o->ob_type));
840       }
841 
842       if (long_val < 0 || long_val > 0xffff) {
843         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
844                            omniPy::formatString("%s item %d: "
845                                                 "%s is out of range for "
846                                                 "unsigned short", "siO",
847                                                 seq_arr, i, t_o));
848       }
849     }
850     return;
851 
852   case CORBA::tk_ulong:
853 
854     for (i=0; i<len; i++) {
855       t_o = getFn(a_o, i);
856 
857       if (PyLong_Check(t_o)) {
858         ulong_val = PyLong_AsUnsignedLong(t_o);
859         if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
860           PyErr_Clear();
861           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
862                              omniPy::formatString("%s item %d: "
863                                                   "%s is out of range for "
864                                                   "unsigned long", "siO",
865                                                   seq_arr, i, t_o));
866         }
867 #if SIZEOF_LONG > 4
868         if (ulong_val > 0xffffffffL) {
869           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
870                              omniPy::formatString("%s item %d: "
871                                                   "%s is out of range for "
872                                                   "unsigned long", "siO",
873                                                   seq_arr, i, t_o));
874         }
875 #endif
876       }
877 #if (PY_VERSION_HEX < 0x03000000)
878       else if (PyInt_Check(t_o)) {
879         long_val = PyInt_AS_LONG(t_o);
880 
881 #  if SIZEOF_LONG > 4
882         if (long_val < 0 || long_val > 0xffffffffL)
883 #  else
884           if (long_val < 0)
885 #  endif
886 	    {
887 	      THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
888 				 omniPy::formatString("%s item %d: "
889 						      "%s is out of range for "
890 						      "unsigned long", "siO",
891                                                       seq_arr, i, t_o));
892 	    }
893       }
894 #endif
895       else {
896         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
897                            omniPy::formatString("%s item %d: "
898                                                 "expecting unsigned long, "
899                                                 "got %r", "siO",
900                                                 seq_arr, i, t_o->ob_type));
901       }
902     }
903     return;
904 
905   case CORBA::tk_float:
906   case CORBA::tk_double:
907 
908     for (i=0; i<len; i++) {
909       t_o = getFn(a_o, i);
910       if (PyFloat_Check(t_o)) {
911         // OK
912       }
913 #if (PY_VERSION_HEX < 0x03000000)
914       else if (PyInt_Check(t_o)) {
915         // OK
916       }
917 #endif
918       else if (PyLong_Check(t_o)) {
919         double_val = PyLong_AsDouble(t_o);
920         if (double_val == -1.0 && PyErr_Occurred()) {
921           PyErr_Clear();
922           const char* tname = etk == CORBA::tk_float ? "float" : "double";
923 
924           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
925                              omniPy::formatString("%s item %d: "
926                                                   "%s is out of range "
927                                                   "for %s", "siOs",
928                                                   seq_arr, i, t_o, tname));
929         }
930       }
931       else {
932         const char* tname = etk == CORBA::tk_float ? "float" : "double";
933         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
934                            omniPy::formatString("%s item %d: "
935                                                 "expecting %s, "
936                                                 "got %r", "sisO",
937                                                 seq_arr, i, tname,
938                                                 t_o->ob_type));
939       }
940     }
941     return;
942 
943   case CORBA::tk_boolean:
944     for (i=0; i<len; i++) {
945       t_o = getFn(a_o, i);
946 
947       if (PyObject_IsTrue(t_o) == -1) {
948         if (omniORB::trace(1))
949           PyErr_Print();
950         else
951           PyErr_Clear();
952 
953         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
954                            omniPy::formatString("%s item %d: "
955                                                 "expecting bool, "
956                                                 "got %r", "siO",
957                                                 seq_arr, i, t_o->ob_type));
958       }
959     }
960     return;
961 
962 #ifdef HAS_LongLong
963 
964   case CORBA::tk_longlong:
965 
966     for (i=0; i<len; i++) {
967       t_o = getFn(a_o, i);
968 
969       if (PyLong_Check(t_o)) {
970         CORBA::LongLong ll = PyLong_AsLongLong(t_o);
971         if (ll == -1 && PyErr_Occurred()) {
972           PyErr_Clear();
973           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
974                              omniPy::formatString("%s item %d: "
975                                                   "%s is out of range for "
976                                                   "long long", "siO",
977                                                   seq_arr, i, t_o));
978         }
979       }
980 #if (PY_VERSION_HEX < 0x03000000)
981       else if (!PyInt_Check(t_o)) {
982         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
983                            omniPy::formatString("%s item %d: "
984                                                 "expecting long long, "
985                                                 "got %r", "siO",
986                                                 seq_arr, i, t_o->ob_type));
987       }
988 #endif
989     }
990     return;
991 
992   case CORBA::tk_ulonglong:
993 
994     for (i=0; i<len; i++) {
995       t_o = getFn(a_o, i);
996 
997       if (PyLong_Check(t_o)) {
998         CORBA::ULongLong ull = PyLong_AsUnsignedLongLong(t_o);
999         if (ull == (CORBA::ULongLong)-1 && PyErr_Occurred()) {
1000           PyErr_Clear();
1001           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1002                              omniPy::formatString("%s item %d: "
1003                                                   "%s is out of range for "
1004                                                   "unsigned long long", "siO",
1005                                                   seq_arr, i, t_o));
1006         }
1007       }
1008 #if (PY_VERSION_HEX < 0x03000000)
1009       else if (PyInt_Check(t_o)) {
1010         long l = PyInt_AS_LONG(t_o);
1011         if (l < 0) {
1012           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1013                              omniPy::formatString("%s item %d: "
1014                                                   "%s is out of range for "
1015                                                   "unsigned long long", "siO",
1016                                                   seq_arr, i, t_o));
1017         }
1018       }
1019 #endif
1020       else {
1021         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1022                            omniPy::formatString("%s item %d: "
1023                                                 "expecting unsigned "
1024                                                 "long long, got %r", "siO",
1025                                                 seq_arr, i, t_o->ob_type));
1026       }
1027     }
1028     return;
1029 #else // No long long
1030   case 23:
1031     OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1032 
1033   case 24:
1034     OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1035 #endif
1036   default:
1037     OMNIORB_ASSERT(0);
1038   }
1039 }
1040 
1041 
1042 static void
validateTypeSequence(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1043 validateTypeSequence(PyObject* d_o, PyObject* a_o,
1044 		     CORBA::CompletionStatus compstatus,
1045 		     PyObject* track)
1046 { // element_desc, max_length
1047   PyObject*    t_o      = PyTuple_GET_ITEM(d_o, 2);
1048   OMNIORB_ASSERT(Int_Check(t_o));
1049 
1050   CORBA::ULong max_len  = Int_AS_LONG(t_o);
1051   PyObject*    elm_desc = PyTuple_GET_ITEM(d_o, 1);
1052 
1053   CORBA::ULong len, i;
1054   CORBA::ULong etk;
1055 
1056   if (sequenceOptimisedType(elm_desc, etk)) {
1057 
1058     if (etk == CORBA::tk_octet) {
1059       // Mapping says sequence<octet> uses a string. For Python 3 we
1060       // use a bytes.
1061       if (!RawString_Check(a_o)) {
1062 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1063 			   omniPy::formatString("Expecting bytes, got %r",
1064 						"O", a_o->ob_type));
1065       }
1066       len = RawString_GET_SIZE(a_o);
1067       if (max_len > 0 && len > max_len)
1068 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1069       return;
1070     }
1071     else if (etk == CORBA::tk_char) {
1072       // Mapping says sequence<char> uses a string
1073       if (!String_Check(a_o)) {
1074 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1075 			   omniPy::formatString("Expecting string, got %r",
1076 						"O", a_o->ob_type));
1077       }
1078       len = String_GET_SIZE(a_o);
1079       if (max_len > 0 && len > max_len)
1080 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1081 
1082 #if (PY_VERSION_HEX >= 0x03030000) // Python 3.3 or later
1083       int   kind = PyUnicode_KIND(a_o);
1084       void* data = PyUnicode_DATA(a_o);
1085 
1086       for (i=0; i != len; ++i) {
1087         Py_UCS4 uc = PyUnicode_READ(kind, data, i);
1088         if (uc > 255)
1089           OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar,
1090                         compstatus);
1091       }
1092 
1093 #elif (PY_VERSION_HEX >= 0x03000000) // Python 3.0 - 3.2
1094       Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
1095       for (i=0; i != len; ++i) {
1096         if (us[i] > 255)
1097           OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar,
1098                         compstatus);
1099       }
1100 #endif
1101       return;
1102     }
1103     else if (PyList_Check(a_o)) {
1104       CORBA::ULong len = PyList_GET_SIZE(a_o);
1105       if (max_len > 0 && len > max_len)
1106         OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1107 
1108       validateOptSequenceItems(len, a_o, etk, compstatus, "Sequence", listGet);
1109     }
1110     else if (PyTuple_Check(a_o)) {
1111       CORBA::ULong len = PyTuple_GET_SIZE(a_o);
1112       if (max_len > 0 && len > max_len)
1113         OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1114 
1115       validateOptSequenceItems(len, a_o, etk, compstatus, "Sequence", tupleGet);
1116     }
1117     else {
1118       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1119 			 omniPy::formatString("Expecting sequence, got %r",
1120 					      "O", a_o->ob_type));
1121     }
1122   }
1123   else { // Complex type
1124     if (PyList_Check(a_o)) {
1125       len = PyList_GET_SIZE(a_o);
1126       if (max_len > 0 && len > max_len)
1127 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1128 
1129       for (i=0; i < len; i++) {
1130 	try {
1131 	  omniPy::validateType(elm_desc, PyList_GET_ITEM(a_o, i),
1132 			       compstatus, track);
1133 	}
1134 	catch (Py_BAD_PARAM& bp) {
1135 	  bp.add(omniPy::formatString("Sequence item %d", "i", i));
1136 	  throw;
1137 	}
1138       }
1139     }
1140     else if (PyTuple_Check(a_o)) {
1141       len = PyTuple_GET_SIZE(a_o);
1142       if (max_len > 0 && len > max_len)
1143 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
1144 
1145       for (i=0; i < len; i++) {
1146 	try {
1147 	  omniPy::validateType(elm_desc, PyTuple_GET_ITEM(a_o, i),
1148 			       compstatus, track);
1149 	}
1150 	catch (Py_BAD_PARAM& bp) {
1151 	  bp.add(omniPy::formatString("Sequence item %d", "i", i));
1152 	  throw;
1153 	}
1154       }
1155     }
1156     else {
1157       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1158 			 omniPy::formatString("Expecting sequence, got %r",
1159 					      "O", a_o->ob_type));
1160     }
1161   }
1162 }
1163 
1164 static void
validateTypeArray(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1165 validateTypeArray(PyObject* d_o, PyObject* a_o,
1166 		  CORBA::CompletionStatus compstatus,
1167 		  PyObject* track)
1168 { // element_desc, length
1169 
1170   PyObject*    t_o      = PyTuple_GET_ITEM(d_o, 2);
1171   OMNIORB_ASSERT(Int_Check(t_o));
1172 
1173   CORBA::ULong arr_len  = Int_AS_LONG(t_o);
1174   PyObject*    elm_desc = PyTuple_GET_ITEM(d_o, 1);
1175 
1176   CORBA::ULong len, i;
1177   CORBA::ULong etk;
1178 
1179   if (sequenceOptimisedType(elm_desc, etk)) {
1180 
1181     if (etk == CORBA::tk_octet) {
1182       // Mapping says array of octet uses a string. For Python 3 we
1183       // use a bytes.
1184       if (!RawString_Check(a_o)) {
1185 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1186 			   omniPy::formatString("Expecting bytes, got %r",
1187 						"O", a_o->ob_type));
1188       }
1189       len = RawString_GET_SIZE(a_o);
1190       if (len != arr_len) {
1191 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1192 			   omniPy::formatString("Expecting bytes length %d, "
1193 						"got %d",
1194 						"ii", arr_len, len));
1195       }
1196       return;
1197     }
1198     else if (etk == CORBA::tk_char) {
1199       // Mapping says array of char uses a string
1200       if (!String_Check(a_o)) {
1201 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1202 			   omniPy::formatString("Expecting string, got %r",
1203 						"O", a_o->ob_type));
1204       }
1205       len = String_GET_SIZE(a_o);
1206       if (len != arr_len) {
1207 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1208 			   omniPy::formatString("Expecting string length %d, "
1209 						"got %d",
1210 						"ii", arr_len, len));
1211       }
1212 
1213 #if (PY_VERSION_HEX >= 0x03030000) // Python 3.3 or later
1214       int   kind = PyUnicode_KIND(a_o);
1215       void* data = PyUnicode_DATA(a_o);
1216 
1217       for (i=0; i != len; ++i) {
1218         Py_UCS4 uc = PyUnicode_READ(kind, data, i);
1219         if (uc > 255)
1220           OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar,
1221                         compstatus);
1222       }
1223 
1224 #elif (PY_VERSION_HEX >= 0x03000000) // Python 3.0 - 3.2
1225       Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
1226       for (i=0; i != len; ++i) {
1227         if (us[i] > 255)
1228           OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar,
1229                         compstatus);
1230       }
1231 #endif
1232       return;
1233     }
1234     else if (PyList_Check(a_o)) {
1235       len = PyList_GET_SIZE(a_o);
1236       if (len != arr_len) {
1237 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1238 			   omniPy::formatString("Expecting array length %d, "
1239 						"got %d",
1240 						"ii", arr_len, len));
1241       }
1242       validateOptSequenceItems(len, a_o, etk, compstatus, "Array", listGet);
1243     }
1244     else if (PyTuple_Check(a_o)) {
1245       len = PyTuple_GET_SIZE(a_o);
1246       if (len != arr_len) {
1247 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1248 			   omniPy::formatString("Expecting array length %d, "
1249 						"got %d",
1250 						"ii", arr_len, len));
1251       }
1252       validateOptSequenceItems(len, a_o, etk, compstatus, "Array", tupleGet);
1253     }
1254     else {
1255       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1256 			 omniPy::formatString("Expecting array, got %r",
1257 					      "O", a_o->ob_type));
1258     }
1259   }
1260   else { // Complex type
1261     if (PyList_Check(a_o)) {
1262       len = PyList_GET_SIZE(a_o);
1263       if (len != arr_len) {
1264 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1265 			   omniPy::formatString("Expecting array length %d, "
1266 						"got %d",
1267 						"ii", arr_len, len));
1268       }
1269 
1270       for (i=0; i < len; i++) {
1271 	try {
1272 	  omniPy::validateType(elm_desc, PyList_GET_ITEM(a_o, i),
1273 			       compstatus, track);
1274 	}
1275 	catch (Py_BAD_PARAM& bp) {
1276 	  bp.add(omniPy::formatString("Array item %d", "i", i));
1277 	  throw;
1278 	}
1279       }
1280     }
1281     else if (PyTuple_Check(a_o)) {
1282       len = PyTuple_GET_SIZE(a_o);
1283       if (len != arr_len) {
1284 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1285 			   omniPy::formatString("Expecting array length %d, "
1286 						"got %d",
1287 						"ii", arr_len, len));
1288       }
1289 
1290       for (i=0; i < len; i++) {
1291 	try {
1292 	  omniPy::validateType(elm_desc, PyTuple_GET_ITEM(a_o, i),
1293 			       compstatus, track);
1294 	}
1295 	catch (Py_BAD_PARAM& bp) {
1296 	  bp.add(omniPy::formatString("Array item %d", "i", i));
1297 	  throw;
1298 	}
1299       }
1300     }
1301     else {
1302       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1303 			 omniPy::formatString("Expecting array, got %r",
1304 					      "O", a_o->ob_type));
1305     }
1306   }
1307 }
1308 
1309 static void
validateTypeAlias(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1310 validateTypeAlias(PyObject* d_o, PyObject* a_o,
1311 		  CORBA::CompletionStatus compstatus,
1312 		  PyObject* track)
1313 { // repoId, name, descr
1314 
1315   omniPy::validateType(PyTuple_GET_ITEM(d_o, 3), a_o, compstatus, track);
1316 }
1317 
1318 static void
validateTypeExcept(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1319 validateTypeExcept(PyObject* d_o, PyObject* a_o,
1320 		   CORBA::CompletionStatus compstatus,
1321 		   PyObject* track)
1322 { // class, repoId, exc name, name, descriptor, ...
1323 
1324   // As with structs, the descriptor tuple has twice the number of
1325   // members plus 4.
1326   int cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
1327 
1328   PyObject* name;
1329   PyObject* value;
1330 
1331   int i, j;
1332   for (i=0,j=4; i < cnt; i++,j++) {
1333     name = PyTuple_GET_ITEM(d_o, j++);
1334     OMNIORB_ASSERT(String_Check(name));
1335 
1336     value = PyObject_GetAttr(a_o, name);
1337 
1338     if (!value) {
1339       PyErr_Clear();
1340       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1341 			 omniPy::formatString("Exception %r instance %r "
1342 					      "has no %r member",
1343 					      "OOO",
1344 					      PyTuple_GET_ITEM(d_o, 3),
1345 					      a_o->ob_type,
1346 					      name));
1347     }
1348     omniPy::PyRefHolder h(value);
1349     try {
1350       omniPy::validateType(PyTuple_GET_ITEM(d_o, j), value, compstatus, track);
1351     }
1352     catch (Py_BAD_PARAM& bp) {
1353       bp.add(omniPy::formatString("Exception %r member %r", "OO",
1354 				  PyTuple_GET_ITEM(d_o, 3), name));
1355       throw;
1356     }
1357   }
1358 }
1359 
1360 static void
validateTypeLongLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1361 validateTypeLongLong(PyObject* d_o, PyObject* a_o,
1362 		     CORBA::CompletionStatus compstatus,
1363 		     PyObject* track)
1364 {
1365 #ifdef HAS_LongLong
1366   if (PyLong_Check(a_o)) {
1367     CORBA::LongLong ll = PyLong_AsLongLong(a_o);
1368     if (ll == -1 && PyErr_Occurred()) {
1369       PyErr_Clear();
1370       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1371 			 omniPy::formatString("%s is out of range for "
1372 					      "long long",
1373 					      "O", a_o));
1374     }
1375   }
1376 #  if (PY_VERSION_HEX < 0x03000000)
1377   else if (PyInt_Check(a_o)) {
1378     // OK
1379   }
1380 #  endif
1381   else {
1382     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1383 		       omniPy::formatString("Expecting long long, got %r",
1384 					    "O", a_o->ob_type));
1385   }
1386 
1387 #else
1388   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1389 #endif
1390 }
1391 
1392 static void
validateTypeULongLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1393 validateTypeULongLong(PyObject* d_o, PyObject* a_o,
1394 		      CORBA::CompletionStatus compstatus,
1395 		      PyObject* track)
1396 {
1397 #ifdef HAS_LongLong
1398   if (PyLong_Check(a_o)) {
1399     CORBA::ULongLong ull = PyLong_AsUnsignedLongLong(a_o);
1400     if (ull == (CORBA::ULongLong)-1 && PyErr_Occurred()) {
1401       PyErr_Clear();
1402       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1403 			 omniPy::formatString("%s is out of range for "
1404 					      "unsigned long long",
1405 					      "O", a_o));
1406     }
1407   }
1408 #  if (PY_VERSION_HEX < 0x03000000)
1409   else if (PyInt_Check(a_o)) {
1410     long l = PyInt_AS_LONG(a_o);
1411     if (l < 0) {
1412       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
1413 			 omniPy::formatString("%s is out of range for "
1414 					      "unsigned long long",
1415 					      "O", a_o));
1416     }
1417   }
1418 #  endif
1419   else {
1420     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1421 		       omniPy::formatString("Expecting long long, got %r",
1422 					    "O", a_o->ob_type));
1423   }
1424 #else
1425   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1426 #endif
1427 }
1428 
1429 static void
validateTypeLongDouble(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1430 validateTypeLongDouble(PyObject* d_o, PyObject* a_o,
1431 		       CORBA::CompletionStatus compstatus,
1432 		       PyObject* track)
1433 {
1434   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1435 }
1436 
1437 static void
validateTypeWChar(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1438 validateTypeWChar(PyObject* d_o, PyObject* a_o,
1439 		  CORBA::CompletionStatus compstatus,
1440 		  PyObject* track)
1441 {
1442   if (!PyUnicode_Check(a_o)) {
1443     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1444 		       omniPy::formatString("Expecting unicode, got %r",
1445 					    "O", a_o->ob_type));
1446   }
1447   if (Unicode_GET_SIZE(a_o) != 1) {
1448     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1449 		       omniPy::formatString("Expecting unicode of length 1, "
1450 					    "got %r",
1451 					    "O", a_o));
1452   }
1453 #if (PY_VERSION_HEX >= 0x03030000) // New Unicode API
1454   Py_UCS4 uc = PyUnicode_READ_CHAR(a_o, 0);
1455   if (uc > 0xffff)
1456     OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_CannotMapChar, compstatus);
1457 #endif
1458 }
1459 
1460 static void
validateTypeWString(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1461 validateTypeWString(PyObject* d_o, PyObject* a_o,
1462 		    CORBA::CompletionStatus compstatus,
1463 		    PyObject* track)
1464 { // max_length
1465   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
1466   OMNIORB_ASSERT(Int_Check(t_o));
1467 
1468   CORBA::ULong max_len = Int_AS_LONG(t_o);
1469 
1470   if (!PyUnicode_Check(a_o)) {
1471     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1472 		       omniPy::formatString("Expecting unicode, got %r",
1473 					    "O", a_o->ob_type));
1474   }
1475 
1476 #if (PY_VERSION_HEX < 0x03030000) // Earlier than Python 3.3
1477 
1478   CORBA::ULong len = PyUnicode_GET_SIZE(a_o);
1479 
1480   if (max_len > 0 && len > max_len)
1481     OMNIORB_THROW(MARSHAL, MARSHAL_WStringIsTooLong, compstatus);
1482 
1483   // Check for nulls
1484   Py_UNICODE* str = PyUnicode_AS_UNICODE(a_o);
1485   for (CORBA::ULong i=0; i<len; i++) {
1486     if (str[i] == 0) {
1487       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
1488 			 omniPy::formatString("Embedded null in unicode "
1489 					      "at position %d", "i", i));
1490     }
1491   }
1492 
1493 #else // New Unicode API
1494 
1495   CORBA::ULong len = PyUnicode_GET_LENGTH(a_o);
1496 
1497   if (max_len > 0 && len > max_len)
1498     OMNIORB_THROW(MARSHAL, MARSHAL_WStringIsTooLong, compstatus);
1499 
1500   // Check for nulls
1501   int   kind = PyUnicode_KIND(a_o);
1502   void* data = PyUnicode_DATA(a_o);
1503 
1504   for (CORBA::ULong i=0; i<len; i++) {
1505     if (PyUnicode_READ(kind, data, i) == 0) {
1506       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
1507 			 omniPy::formatString("Embedded null in unicode "
1508 					      "at position %d", "i", i));
1509     }
1510   }
1511 #endif
1512 }
1513 
1514 static void
validateTypeFixed(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1515 validateTypeFixed(PyObject* d_o, PyObject* a_o,
1516 		  CORBA::CompletionStatus compstatus,
1517 		  PyObject* track)
1518 { // digits, scale
1519   if (!omnipyFixed_Check(a_o)) {
1520     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
1521 		       omniPy::formatString("Expecting fixed, got %r",
1522 					    "O", a_o->ob_type));
1523   }
1524 
1525   PyObject* t_o;
1526 
1527   t_o = PyTuple_GET_ITEM(d_o, 1); int dlimit = Int_AS_LONG(t_o);
1528   t_o = PyTuple_GET_ITEM(d_o, 2); int slimit = Int_AS_LONG(t_o);
1529 
1530   int digits = ((omnipyFixedObject*)a_o)->ob_fixed->fixed_digits();
1531   int scale  = ((omnipyFixedObject*)a_o)->ob_fixed->fixed_scale();
1532 
1533   if (scale > slimit) {
1534     digits -= (scale - slimit);
1535     scale   = slimit;
1536   }
1537   if (digits > dlimit)
1538     OMNIORB_THROW(DATA_CONVERSION, DATA_CONVERSION_RangeError, compstatus);
1539 }
1540 
1541 // validateTypeValue and validateTypeValueBox are in pyValueType.cc
1542 
1543 static void
validateTypeNative(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1544 validateTypeNative(PyObject* d_o, PyObject* a_o,
1545 		   CORBA::CompletionStatus compstatus,
1546 		   PyObject* track)
1547 {
1548   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
1549 }
1550 
1551 // validateTypeAbstractInterface is in pyAbstractIntf.cc
1552 
1553 static void
validateTypeLocalInterface(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1554 validateTypeLocalInterface(PyObject* d_o, PyObject* a_o,
1555 			   CORBA::CompletionStatus compstatus,
1556 			   PyObject* track)
1557 {
1558   OMNIORB_THROW(MARSHAL, MARSHAL_LocalObject, compstatus);
1559 }
1560 
1561 void
1562 omniPy::
validateTypeIndirect(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus,PyObject * track)1563 validateTypeIndirect(PyObject* d_o, PyObject* a_o,
1564 		     CORBA::CompletionStatus compstatus,
1565 		     PyObject* track)
1566 {
1567   PyObject* l = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyList_Check(l));
1568   PyObject* d = PyList_GET_ITEM(l, 0);
1569 
1570   if (String_Check(d)) {
1571     // Indirection to a repoId -- find the corresponding descriptor
1572     d = PyDict_GetItem(pyomniORBtypeMap, d);
1573     if (!d) OMNIORB_THROW(BAD_PARAM,
1574 			  BAD_PARAM_IncompletePythonType,
1575 			  compstatus);
1576     Py_INCREF(d);
1577     PyList_SetItem(l, 0, d);
1578   }
1579   validateType(d, a_o, compstatus, track);
1580 }
1581 
1582 
1583 const omniPy::ValidateTypeFn omniPy::validateTypeFns[] = {
1584   validateTypeNull,
1585   validateTypeVoid,
1586   validateTypeShort,
1587   validateTypeLong,
1588   validateTypeUShort,
1589   validateTypeULong,
1590   validateTypeFloat,
1591   validateTypeDouble,
1592   validateTypeBoolean,
1593   validateTypeChar,
1594   validateTypeOctet,
1595   validateTypeAny,
1596   validateTypeTypeCode,
1597   validateTypePrincipal,
1598   validateTypeObjref,
1599   validateTypeStruct,
1600   validateTypeUnion,
1601   validateTypeEnum,
1602   validateTypeString,
1603   validateTypeSequence,
1604   validateTypeArray,
1605   validateTypeAlias,
1606   validateTypeExcept,
1607   validateTypeLongLong,
1608   validateTypeULongLong,
1609   validateTypeLongDouble,
1610   validateTypeWChar,
1611   validateTypeWString,
1612   validateTypeFixed,
1613   omniPy::validateTypeValue,
1614   omniPy::validateTypeValueBox,
1615   validateTypeNative,
1616   omniPy::validateTypeAbstractInterface,
1617   validateTypeLocalInterface
1618 };
1619 
1620 
1621 static void
marshalPyObjectNull(cdrStream & stream,PyObject * d_o,PyObject * a_o)1622 marshalPyObjectNull(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1623 {
1624 }
1625 
1626 static void
marshalPyObjectVoid(cdrStream & stream,PyObject * d_o,PyObject * a_o)1627 marshalPyObjectVoid(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1628 {
1629 }
1630 
1631 static void
marshalPyObjectShort(cdrStream & stream,PyObject * d_o,PyObject * a_o)1632 marshalPyObjectShort(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1633 {
1634   CORBA::Short s;
1635 
1636 #if (PY_VERSION_HEX < 0x03000000)
1637   if (PyInt_Check(a_o))
1638     s = PyInt_AS_LONG(a_o);
1639   else
1640 #endif
1641     s = PyLong_AsLong(a_o);
1642 
1643   s >>= stream;
1644 }
1645 
1646 static void
marshalPyObjectLong(cdrStream & stream,PyObject * d_o,PyObject * a_o)1647 marshalPyObjectLong(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1648 {
1649   CORBA::Long l;
1650 
1651 #if (PY_VERSION_HEX < 0x03000000)
1652   if (PyInt_Check(a_o))
1653     l = PyInt_AS_LONG(a_o);
1654   else
1655 #endif
1656     l = PyLong_AsLong(a_o);
1657 
1658   l >>= stream;
1659 }
1660 
1661 static void
marshalPyObjectUShort(cdrStream & stream,PyObject * d_o,PyObject * a_o)1662 marshalPyObjectUShort(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1663 {
1664   CORBA::UShort us;
1665 
1666 #if (PY_VERSION_HEX < 0x03000000)
1667   if (PyInt_Check(a_o))
1668     us = PyInt_AS_LONG(a_o);
1669   else
1670 #endif
1671     us = PyLong_AsLong(a_o);
1672 
1673   us >>= stream;
1674 }
1675 
1676 static void
marshalPyObjectULong(cdrStream & stream,PyObject * d_o,PyObject * a_o)1677 marshalPyObjectULong(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1678 {
1679   CORBA::ULong ul;
1680 
1681 #if (PY_VERSION_HEX < 0x03000000)
1682   if (PyLong_Check(a_o))
1683     ul = PyLong_AsUnsignedLong(a_o);
1684   else // It's an int
1685     ul = PyInt_AS_LONG(a_o);
1686 #else
1687   ul = PyLong_AsUnsignedLong(a_o);
1688 #endif
1689 
1690   ul >>= stream;
1691 }
1692 
1693 static void
marshalPyObjectFloat(cdrStream & stream,PyObject * d_o,PyObject * a_o)1694 marshalPyObjectFloat(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1695 {
1696   CORBA::Float f;
1697 
1698   if (PyFloat_Check(a_o))
1699     f = (CORBA::Float)PyFloat_AS_DOUBLE(a_o);
1700 
1701 #if (PY_VERSION_HEX < 0x03000000)
1702   else if (PyInt_Check(a_o))
1703     f = (CORBA::Float)PyInt_AS_LONG(a_o);
1704 #endif
1705 
1706   else
1707     f = (CORBA::Float)PyLong_AsDouble(a_o);
1708 
1709   f >>= stream;
1710 }
1711 
1712 static void
marshalPyObjectDouble(cdrStream & stream,PyObject * d_o,PyObject * a_o)1713 marshalPyObjectDouble(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1714 {
1715   CORBA::Double d = 0; // Initialised to stop egcs complaining
1716 
1717   if (PyFloat_Check(a_o))
1718     d = (CORBA::Double)PyFloat_AS_DOUBLE(a_o);
1719 
1720 #if (PY_VERSION_HEX < 0x03000000)
1721   else if (PyInt_Check(a_o))
1722     d = (CORBA::Double)PyInt_AS_LONG(a_o);
1723 #endif
1724 
1725   else
1726     d = (CORBA::Double)PyLong_AsDouble(a_o);
1727 
1728   d >>= stream;
1729 }
1730 
1731 static void
marshalPyObjectBoolean(cdrStream & stream,PyObject * d_o,PyObject * a_o)1732 marshalPyObjectBoolean(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1733 {
1734   CORBA::Boolean b = PyObject_IsTrue(a_o);
1735   stream.marshalBoolean(b);
1736 }
1737 
1738 static void
marshalPyObjectChar(cdrStream & stream,PyObject * d_o,PyObject * a_o)1739 marshalPyObjectChar(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1740 {
1741 #if (PY_VERSION_HEX < 0x03000000)
1742   char* str = PyString_AS_STRING(a_o);
1743   stream.marshalChar(str[0]);
1744 
1745 #elif (PY_VERSION_HEX < 0x03030000)
1746   Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
1747   stream.marshalChar(*us);
1748 
1749 #else
1750   Py_UCS4 uc = PyUnicode_READ_CHAR(a_o, 0);
1751   stream.marshalChar(uc);
1752 
1753 #endif
1754 }
1755 
1756 static void
marshalPyObjectOctet(cdrStream & stream,PyObject * d_o,PyObject * a_o)1757 marshalPyObjectOctet(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1758 {
1759   CORBA::Octet o;
1760 
1761 #if (PY_VERSION_HEX < 0x03000000)
1762   if (PyInt_Check(a_o))
1763     o = PyInt_AS_LONG(a_o);
1764   else
1765 #endif
1766     o = PyLong_AsLong(a_o);
1767 
1768   stream.marshalOctet(o);
1769 }
1770 
1771 static void
marshalPyObjectAny(cdrStream & stream,PyObject * d_o,PyObject * a_o)1772 marshalPyObjectAny(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1773 {
1774   // TypeCode
1775   omniPy::PyRefHolder t_o (PyObject_GetAttrString(a_o, (char*)"_t"));
1776   omniPy::PyRefHolder desc(PyObject_GetAttrString(t_o, (char*)"_d"));
1777 
1778   omniPy::marshalTypeCode(stream, desc);
1779 
1780   // Any's contents
1781   t_o = PyObject_GetAttrString(a_o, (char*)"_v");
1782   omniPy::marshalPyObject(stream, desc, t_o);
1783 }
1784 
1785 static void
marshalPyObjectTypeCode(cdrStream & stream,PyObject * d_o,PyObject * a_o)1786 marshalPyObjectTypeCode(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1787 {
1788   omniPy::PyRefHolder t_o(PyObject_GetAttrString(a_o, (char*)"_d"));
1789   omniPy::marshalTypeCode(stream, t_o);
1790 }
1791 
1792 static void
marshalPyObjectPrincipal(cdrStream & stream,PyObject * d_o,PyObject * a_o)1793 marshalPyObjectPrincipal(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1794 {
1795   OMNIORB_ASSERT(0);
1796 }
1797 
1798 static void
marshalPyObjectObjref(cdrStream & stream,PyObject * d_o,PyObject * a_o)1799 marshalPyObjectObjref(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1800 { // repoId, name
1801 
1802   CORBA::Object_ptr obj;
1803 
1804   if (a_o == Py_None)
1805     obj = CORBA::Object::_nil();
1806   else
1807     obj = omniPy::getObjRef(a_o);
1808 
1809   CORBA::Object::_marshalObjRef(obj, stream);
1810 }
1811 
1812 static void
marshalPyObjectStruct(cdrStream & stream,PyObject * d_o,PyObject * a_o)1813 marshalPyObjectStruct(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1814 { // class, repoId, struct name, {name, descriptor}
1815 
1816   int                 i, j;
1817   int                 cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
1818   PyObject*           name;
1819   omniPy::PyRefHolder value;
1820 
1821   for (i=0,j=4; i < cnt; i++,j++) {
1822     name  = PyTuple_GET_ITEM(d_o, j++);
1823     value = PyObject_GetAttr(a_o, name);
1824     omniPy::marshalPyObject(stream, PyTuple_GET_ITEM(d_o, j), value);
1825   }
1826 }
1827 
1828 static void
marshalPyObjectUnion(cdrStream & stream,PyObject * d_o,PyObject * a_o)1829 marshalPyObjectUnion(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1830 { // class,
1831   // repoId,
1832   // name,
1833   // discriminant descr,
1834   // default used,
1835   // ((label value, member name, member descr), ...),
1836   // default (label, name, descr) or None,
1837   // {label: (label, name, descr), ...}
1838 
1839   omniPy::PyRefHolder discriminant(PyObject_GetAttrString(a_o, (char*)"_d"));
1840   omniPy::PyRefHolder value(PyObject_GetAttrString(a_o, (char*)"_v"));
1841 
1842   PyObject* t_o          = PyTuple_GET_ITEM(d_o, 4); // Discriminant descriptor
1843   PyObject* cdict        = PyTuple_GET_ITEM(d_o, 8);
1844 
1845   omniPy::marshalPyObject(stream, t_o, discriminant);
1846 
1847   t_o = PyDict_GetItem(cdict, discriminant);
1848   if (t_o) {
1849     // Discriminant found in case dictionary
1850     omniPy::marshalPyObject(stream, PyTuple_GET_ITEM(t_o, 2), value);
1851   }
1852   else {
1853     // Is there a default case?
1854     t_o = PyTuple_GET_ITEM(d_o, 7);
1855     if (t_o != Py_None) {
1856       omniPy::marshalPyObject(stream, PyTuple_GET_ITEM(t_o, 2), value);
1857     }
1858   }
1859 }
1860 
1861 static void
marshalPyObjectEnum(cdrStream & stream,PyObject * d_o,PyObject * a_o)1862 marshalPyObjectEnum(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1863 { // repoId, name, item list
1864 
1865   omniPy::PyRefHolder ev(PyObject_GetAttrString(a_o, (char*)"_v"));
1866   CORBA::ULong e = omniPy::getULongVal(ev);
1867   e >>= stream;
1868 }
1869 
1870 static void
marshalPyObjectString(cdrStream & stream,PyObject * d_o,PyObject * a_o)1871 marshalPyObjectString(cdrStream& stream, PyObject* d_o, PyObject* a_o)
1872 { // max_length
1873 
1874 #if (PY_VERSION_HEX < 0x03000000)
1875   orbParameters::nativeCharCodeSet->marshalString(stream, stream.TCS_C(), 0,
1876 						  PyString_GET_SIZE(a_o),
1877 						  PyString_AS_STRING(a_o));
1878 #else
1879   CORBA::ULong size;
1880   const char*  str = String_AS_STRING_AND_SIZE(a_o, size);
1881 
1882   omniPy::ncs_c_utf_8->marshalString(stream, stream.TCS_C(), 0, size, str);
1883 #endif
1884 }
1885 
1886 
1887 template<class G>
1888 inline void
marshalOptSequenceItems(cdrStream & stream,CORBA::ULong len,PyObject * a_o,CORBA::ULong etk,G getFn)1889 marshalOptSequenceItems(cdrStream&   stream,
1890                         CORBA::ULong len,
1891                         PyObject*    a_o,
1892                         CORBA::ULong etk,
1893                         G            getFn)
1894 {
1895   CORBA::ULong  i;
1896   PyObject*     t_o;
1897   long          long_val;
1898   unsigned long ulong_val;
1899   double        double_val;
1900 
1901   switch (etk) {
1902 
1903   case CORBA::tk_short:
1904     {
1905       CORBA::Short e;
1906       for (i=0; i < len; i++) {
1907         t_o = getFn(a_o, i);
1908 
1909 #if (PY_VERSION_HEX < 0x03000000)
1910         if (PyInt_Check(t_o))
1911           e = PyInt_AS_LONG(t_o);
1912         else
1913 #endif
1914           e = PyLong_AsLong(t_o);
1915 
1916         e >>= stream;
1917       }
1918     }
1919     break;
1920 
1921   case CORBA::tk_long:
1922     {
1923       CORBA::Long e;
1924       for (i=0; i < len; i++) {
1925         t_o = getFn(a_o, i);
1926 
1927 #if (PY_VERSION_HEX < 0x03000000)
1928         if (PyInt_Check(t_o))
1929           e = PyInt_AS_LONG(t_o);
1930         else
1931 #endif
1932           e = PyLong_AsLong(t_o);
1933 
1934         e >>= stream;
1935       }
1936     }
1937     break;
1938 
1939   case CORBA::tk_ushort:
1940     {
1941       CORBA::UShort e;
1942       for (i=0; i < len; i++) {
1943         t_o = getFn(a_o, i);
1944 
1945 #if (PY_VERSION_HEX < 0x03000000)
1946         if (PyInt_Check(t_o))
1947           e = PyInt_AS_LONG(t_o);
1948         else
1949 #endif
1950           e = PyLong_AsLong(t_o);
1951 
1952         e >>= stream;
1953       }
1954     }
1955     break;
1956 
1957   case CORBA::tk_ulong:
1958     {
1959       CORBA::ULong e;
1960       for (i=0; i < len; i++) {
1961         t_o = getFn(a_o, i);
1962 
1963 #if (PY_VERSION_HEX < 0x03000000)
1964         if (PyLong_Check(t_o))
1965 #endif
1966           e = PyLong_AsUnsignedLong(t_o);
1967 
1968 #if (PY_VERSION_HEX < 0x03000000)
1969         else
1970           e = PyInt_AS_LONG(t_o);
1971 #endif
1972         e >>= stream;
1973       }
1974     }
1975     break;
1976 
1977   case CORBA::tk_float:
1978     {
1979       CORBA::Float e;
1980       for (i=0; i < len; i++) {
1981         t_o = getFn(a_o, i);
1982 
1983         if (PyFloat_Check(t_o))
1984           e = PyFloat_AS_DOUBLE(t_o);
1985 
1986 #if (PY_VERSION_HEX < 0x03000000)
1987         else if (PyInt_Check(t_o))
1988           e = PyInt_AS_LONG(t_o);
1989 #endif
1990         else
1991           e = PyLong_AsDouble(t_o);
1992 
1993         e >>= stream;
1994       }
1995     }
1996     break;
1997 
1998   case CORBA::tk_double:
1999     {
2000       CORBA::Double e;
2001       for (i=0; i < len; i++) {
2002         t_o = getFn(a_o, i);
2003 
2004         if (PyFloat_Check(t_o))
2005           e = PyFloat_AS_DOUBLE(t_o);
2006 
2007 #if (PY_VERSION_HEX < 0x03000000)
2008         else if (PyInt_Check(t_o))
2009           e = PyInt_AS_LONG(t_o);
2010 #endif
2011         else
2012           e = PyLong_AsDouble(t_o);
2013 
2014         e >>= stream;
2015       }
2016     }
2017     break;
2018 
2019   case CORBA::tk_boolean:
2020     {
2021       CORBA::Boolean e;
2022       for (i=0; i < len; i++) {
2023         t_o = getFn(a_o, i);
2024 
2025         stream.marshalBoolean(PyObject_IsTrue(t_o));
2026       }
2027     }
2028     break;
2029 
2030 #ifdef HAS_LongLong
2031 
2032   case CORBA::tk_longlong:
2033     {
2034       CORBA::LongLong e;
2035       for (i=0; i < len; i++) {
2036         t_o = getFn(a_o, i);
2037 
2038 #if (PY_VERSION_HEX < 0x03000000)
2039         if (PyLong_Check(t_o))
2040 #endif
2041           e = PyLong_AsLongLong(t_o);
2042 
2043 #if (PY_VERSION_HEX < 0x03000000)
2044         else
2045           e = PyInt_AS_LONG(t_o);
2046 #endif
2047         e >>= stream;
2048       }
2049     }
2050     break;
2051 
2052   case CORBA::tk_ulonglong:
2053     {
2054       CORBA::ULongLong e;
2055       for (i=0; i < len; i++) {
2056         t_o = getFn(a_o, i);
2057 
2058 #if (PY_VERSION_HEX < 0x03000000)
2059         if (PyLong_Check(t_o))
2060 #endif
2061           e = PyLong_AsLongLong(t_o);
2062 
2063 #if (PY_VERSION_HEX < 0x03000000)
2064         else
2065           e = PyInt_AS_LONG(t_o);
2066 #endif
2067         e >>= stream;
2068       }
2069     }
2070     break;
2071 #endif
2072   default:
2073     OMNIORB_ASSERT(0);
2074   }
2075 
2076 }
2077 
2078 
2079 static void
marshalPyObjectSequence(cdrStream & stream,PyObject * d_o,PyObject * a_o)2080 marshalPyObjectSequence(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2081 { // element_desc, max_length
2082 
2083   PyObject* elm_desc = PyTuple_GET_ITEM(d_o, 1);
2084   PyObject* t_o;
2085 
2086   CORBA::ULong i, len;
2087   CORBA::ULong etk;
2088 
2089   if (sequenceOptimisedType(elm_desc, etk)) {
2090     if (etk == CORBA::tk_octet) {
2091       len = RawString_GET_SIZE(a_o);
2092       len >>= stream;
2093       CORBA::Octet *l = (CORBA::Octet*)RawString_AS_STRING(a_o);
2094       stream.put_octet_array((const CORBA::Octet*)l, len);
2095     }
2096     else if (etk == CORBA::tk_char) {
2097       len = String_GET_SIZE(a_o);
2098       len >>= stream;
2099 
2100 #if (PY_VERSION_HEX < 0x03000000)
2101       CORBA::Char *l = (CORBA::Char*)PyString_AS_STRING(a_o);
2102       for (i=0; i != len; ++i)
2103 	stream.marshalChar(l[i]);
2104 
2105 #elif (PY_VERSION_HEX >= 0x03030000) // Python 3.3 or later
2106       int   kind = PyUnicode_KIND(a_o);
2107       void* data = PyUnicode_DATA(a_o);
2108 
2109       for (i=0; i != len; ++i) {
2110         Py_UCS4 uc = PyUnicode_READ(kind, data, i);
2111         stream.marshalChar((char)uc);
2112       }
2113 
2114 #elif (PY_VERSION_HEX >= 0x03000000) // Python 3.0 - 3.2
2115       Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
2116       for (i=0; i != len; ++i) {
2117         stream.marshalChar((char)us[i]);
2118       }
2119 #endif
2120     }
2121     else if (PyList_Check(a_o)) {
2122       len = PyList_GET_SIZE(a_o);
2123       len >>= stream;
2124 
2125       marshalOptSequenceItems(stream, len, a_o, etk, listGet);
2126     }
2127     else {
2128       OMNIORB_ASSERT(PyTuple_Check(a_o));
2129       len = PyTuple_GET_SIZE(a_o);
2130       len >>= stream;
2131 
2132       marshalOptSequenceItems(stream, len, a_o, etk, tupleGet);
2133     }
2134   }
2135   else if (PyList_Check(a_o)) {
2136     len = PyList_GET_SIZE(a_o);
2137     len >>= stream;
2138     for (i=0; i < len; i++)
2139       omniPy::marshalPyObject(stream, elm_desc, PyList_GET_ITEM(a_o, i));
2140   }
2141   else {
2142     len = PyTuple_GET_SIZE(a_o);
2143     len >>= stream;
2144     for (i=0; i < len; i++)
2145       omniPy::marshalPyObject(stream, elm_desc, PyTuple_GET_ITEM(a_o, i));
2146   }
2147 }
2148 
2149 
2150 static void
marshalPyObjectArray(cdrStream & stream,PyObject * d_o,PyObject * a_o)2151 marshalPyObjectArray(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2152 { // element_desc, length
2153 
2154   PyObject* elm_desc = PyTuple_GET_ITEM(d_o, 1);
2155   PyObject* t_o;
2156 
2157   CORBA::ULong i, len;
2158   CORBA::ULong etk;
2159 
2160   if (sequenceOptimisedType(elm_desc, etk)) {
2161     if (etk == CORBA::tk_octet) {
2162       len = RawString_GET_SIZE(a_o);
2163       CORBA::Octet *l = (CORBA::Octet*)RawString_AS_STRING(a_o);
2164       stream.put_octet_array(l, len);
2165     }
2166     else if (etk == CORBA::tk_char) {
2167       len = String_GET_SIZE(a_o);
2168 
2169 #if (PY_VERSION_HEX < 0x03000000)
2170       CORBA::Char *l = (CORBA::Char*)PyString_AS_STRING(a_o);
2171       for (i=0; i<len; i++)
2172 	stream.marshalChar(l[i]);
2173 
2174 #elif (PY_VERSION_HEX >= 0x03030000) // Python 3.3 or later
2175       int   kind = PyUnicode_KIND(a_o);
2176       void* data = PyUnicode_DATA(a_o);
2177 
2178       for (i=0; i != len; ++i) {
2179         Py_UCS4 uc = PyUnicode_READ(kind, data, i);
2180         stream.marshalChar((char)uc);
2181       }
2182 
2183 #elif (PY_VERSION_HEX >= 0x03000000) // Python 3.0 - 3.2
2184       Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
2185       for (i=0; i != len; ++i) {
2186         stream.marshalChar((char)us[i]);
2187       }
2188 #endif
2189     }
2190     else if (PyList_Check(a_o)) {
2191       len = PyList_GET_SIZE(a_o);
2192       marshalOptSequenceItems(stream, len, a_o, etk, listGet);
2193     }
2194     else {
2195       OMNIORB_ASSERT(PyTuple_Check(a_o));
2196       len = PyTuple_GET_SIZE(a_o);
2197       marshalOptSequenceItems(stream, len, a_o, etk, tupleGet);
2198     }
2199   }
2200   else if (PyList_Check(a_o)) {
2201     len = PyList_GET_SIZE(a_o);
2202     for (i=0; i < len; i++)
2203       omniPy::marshalPyObject(stream, elm_desc, PyList_GET_ITEM(a_o, i));
2204   }
2205   else {
2206     len = PyTuple_GET_SIZE(a_o);
2207     for (i=0; i < len; i++)
2208       omniPy::marshalPyObject(stream, elm_desc, PyTuple_GET_ITEM(a_o, i));
2209   }
2210 }
2211 
2212 static void
marshalPyObjectAlias(cdrStream & stream,PyObject * d_o,PyObject * a_o)2213 marshalPyObjectAlias(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2214 { // repoId, name, descr
2215 
2216   omniPy::marshalPyObject(stream, PyTuple_GET_ITEM(d_o, 3), a_o);
2217 }
2218 
2219 static void
marshalPyObjectExcept(cdrStream & stream,PyObject * d_o,PyObject * a_o)2220 marshalPyObjectExcept(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2221 { // class, repoId, exc name, name, descriptor, ...
2222 
2223   PyObject*    t_o  = PyTuple_GET_ITEM(d_o, 2);
2224 
2225   CORBA::ULong slen;
2226   const char*  str = String_AS_STRING_AND_SIZE(t_o, slen);
2227   ++slen;
2228 
2229   slen >>= stream;
2230   stream.put_octet_array((const CORBA::Octet*)str, slen);
2231 
2232   int cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
2233 
2234   PyObject* name;
2235   PyObject* value;
2236 
2237   int i, j;
2238   for (i=0,j=4; i < cnt; i++) {
2239     name  = PyTuple_GET_ITEM(d_o, j++);
2240     value = PyObject_GetAttr(a_o, name);
2241     Py_DECREF(value);
2242     omniPy::marshalPyObject(stream, PyTuple_GET_ITEM(d_o, j++), value);
2243   }
2244 }
2245 
2246 static void
marshalPyObjectLongLong(cdrStream & stream,PyObject * d_o,PyObject * a_o)2247 marshalPyObjectLongLong(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2248 {
2249 #ifdef HAS_LongLong
2250   CORBA::LongLong ll;
2251 
2252 #if (PY_VERSION_HEX < 0x03000000)
2253   if (PyLong_Check(a_o))
2254 #endif
2255     ll = PyLong_AsLongLong(a_o);
2256 
2257 #if (PY_VERSION_HEX < 0x03000000)
2258   else // It's an int
2259     ll = PyInt_AS_LONG(a_o);
2260 #endif
2261 
2262   ll >>= stream;
2263 #else
2264   OMNIORB_ASSERT(0);
2265 #endif
2266 }
2267 
2268 static void
marshalPyObjectULongLong(cdrStream & stream,PyObject * d_o,PyObject * a_o)2269 marshalPyObjectULongLong(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2270 {
2271 #ifdef HAS_LongLong
2272   CORBA::ULongLong ull;
2273 
2274 #if (PY_VERSION_HEX < 0x03000000)
2275   if (PyLong_Check(a_o))
2276 #endif
2277     ull = PyLong_AsUnsignedLongLong(a_o);
2278 
2279 #if (PY_VERSION_HEX < 0x03000000)
2280   else // It's an int
2281     ull = PyInt_AS_LONG(a_o);
2282 #endif
2283 
2284   ull >>= stream;
2285 #else
2286   OMNIORB_ASSERT(0);
2287 #endif
2288 }
2289 
2290 static void
marshalPyObjectLongDouble(cdrStream & stream,PyObject * d_o,PyObject * a_o)2291 marshalPyObjectLongDouble(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2292 {
2293   OMNIORB_ASSERT(0);
2294 }
2295 
2296 static void
marshalPyObjectWChar(cdrStream & stream,PyObject * d_o,PyObject * a_o)2297 marshalPyObjectWChar(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2298 {
2299   OMNIORB_CHECK_TCS_W_FOR_MARSHAL(stream.TCS_W(), stream);
2300 
2301 #if (PY_VERSION_HEX < 0x03030000) // Old Unicode API
2302   Py_UNICODE* str = PyUnicode_AS_UNICODE(a_o);
2303   stream.TCS_W()->marshalWChar(stream, str[0]);
2304 #else
2305   Py_UCS4 uc = PyUnicode_READ_CHAR(a_o, 0);
2306   stream.TCS_W()->marshalWChar(stream, uc);
2307 #endif
2308 }
2309 
2310 static void
marshalPyObjectWString(cdrStream & stream,PyObject * d_o,PyObject * a_o)2311 marshalPyObjectWString(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2312 {
2313   OMNIORB_CHECK_TCS_W_FOR_MARSHAL(stream.TCS_W(), stream);
2314 
2315 #if defined(Py_UNICODE_WIDE) || (PY_VERSION_HEX >= 0x03030000)
2316   omniPy::PyRefHolder ustr(PyUnicode_AsUTF16String(a_o));
2317   if (!ustr.valid()) {
2318     // Now we're in trouble...
2319     if (omniORB::trace(1)) {
2320       PyErr_Print();
2321     }
2322     PyErr_Clear();
2323     OMNIORB_THROW(UNKNOWN, UNKNOWN_PythonException,
2324 		  (CORBA::CompletionStatus)stream.completion());
2325   }
2326   OMNIORB_ASSERT(RawString_Check(ustr));
2327 
2328   char*        str = RawString_AS_STRING(ustr) + 2; // Skip BOM
2329   CORBA::ULong len = (RawString_GET_SIZE(ustr) - 2) / 2;
2330 
2331 #else
2332   Py_UNICODE*  str = PyUnicode_AS_UNICODE(a_o);
2333   CORBA::ULong len = PyUnicode_GET_SIZE(a_o);
2334 
2335 #endif
2336   stream.TCS_W()->marshalWString(stream, 0, len,
2337 				 (const omniCodeSet::UniChar*)str);
2338 }
2339 
2340 static void
marshalPyObjectFixed(cdrStream & stream,PyObject * d_o,PyObject * a_o)2341 marshalPyObjectFixed(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2342 { // digits, scale
2343   PyObject* t_o;
2344 
2345   t_o = PyTuple_GET_ITEM(d_o, 1); int dlimit = Int_AS_LONG(t_o);
2346   t_o = PyTuple_GET_ITEM(d_o, 2); int slimit = Int_AS_LONG(t_o);
2347 
2348   CORBA::Fixed f(*((omnipyFixedObject*)a_o)->ob_fixed);
2349   f.PR_setLimits(dlimit, slimit);
2350   f >>= stream;
2351 }
2352 
2353 // marshalPyObjectValue and marshalPyObjectValueBox are in pyValueType.cc
2354 
2355 static void
marshalPyObjectNative(cdrStream & stream,PyObject * d_o,PyObject * a_o)2356 marshalPyObjectNative(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2357 {
2358   OMNIORB_ASSERT(0);
2359 }
2360 
2361 // marshalPyObjectAbstractInterface is in pyAbstractIntf.cc
2362 
2363 static void
marshalPyObjectLocalInterface(cdrStream & stream,PyObject * d_o,PyObject * a_o)2364 marshalPyObjectLocalInterface(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2365 {
2366   OMNIORB_ASSERT(0);
2367 }
2368 
2369 void
2370 omniPy::
marshalPyObjectIndirect(cdrStream & stream,PyObject * d_o,PyObject * a_o)2371 marshalPyObjectIndirect(cdrStream& stream, PyObject* d_o, PyObject* a_o)
2372 {
2373   PyObject* l = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyList_Check(l));
2374   PyObject* d = PyList_GET_ITEM(l, 0);
2375 
2376   OMNIORB_ASSERT(!String_Check(d));
2377   marshalPyObject(stream, d, a_o);
2378 }
2379 
2380 
2381 const omniPy::MarshalPyObjectFn omniPy::marshalPyObjectFns[] = {
2382   marshalPyObjectNull,
2383   marshalPyObjectVoid,
2384   marshalPyObjectShort,
2385   marshalPyObjectLong,
2386   marshalPyObjectUShort,
2387   marshalPyObjectULong,
2388   marshalPyObjectFloat,
2389   marshalPyObjectDouble,
2390   marshalPyObjectBoolean,
2391   marshalPyObjectChar,
2392   marshalPyObjectOctet,
2393   marshalPyObjectAny,
2394   marshalPyObjectTypeCode,
2395   marshalPyObjectPrincipal,
2396   marshalPyObjectObjref,
2397   marshalPyObjectStruct,
2398   marshalPyObjectUnion,
2399   marshalPyObjectEnum,
2400   marshalPyObjectString,
2401   marshalPyObjectSequence,
2402   marshalPyObjectArray,
2403   marshalPyObjectAlias,
2404   marshalPyObjectExcept,
2405   marshalPyObjectLongLong,
2406   marshalPyObjectULongLong,
2407   marshalPyObjectLongDouble,
2408   marshalPyObjectWChar,
2409   marshalPyObjectWString,
2410   marshalPyObjectFixed,
2411   omniPy::marshalPyObjectValue,
2412   omniPy::marshalPyObjectValueBox,
2413   marshalPyObjectNative,
2414   omniPy::marshalPyObjectAbstractInterface,
2415   marshalPyObjectLocalInterface
2416 };
2417 
2418 
2419 
2420 static PyObject*
unmarshalPyObjectNull(cdrStream & stream,PyObject * d_o)2421 unmarshalPyObjectNull(cdrStream& stream, PyObject* d_o)
2422 {
2423   Py_INCREF(Py_None);
2424   return Py_None;
2425 }
2426 
2427 static PyObject*
unmarshalPyObjectVoid(cdrStream & stream,PyObject * d_o)2428 unmarshalPyObjectVoid(cdrStream& stream, PyObject* d_o)
2429 {
2430   Py_INCREF(Py_None);
2431   return Py_None;
2432 }
2433 
2434 static PyObject*
unmarshalPyObjectShort(cdrStream & stream,PyObject * d_o)2435 unmarshalPyObjectShort(cdrStream& stream, PyObject* d_o)
2436 {
2437   CORBA::Short s;
2438   s <<= stream;
2439   return Int_FromLong(s);
2440 }
2441 
2442 static PyObject*
unmarshalPyObjectLong(cdrStream & stream,PyObject * d_o)2443 unmarshalPyObjectLong(cdrStream& stream, PyObject* d_o)
2444 {
2445   CORBA::Long l;
2446   l <<= stream;
2447   return Int_FromLong(l);
2448 }
2449 
2450 static PyObject*
unmarshalPyObjectUShort(cdrStream & stream,PyObject * d_o)2451 unmarshalPyObjectUShort(cdrStream& stream, PyObject* d_o)
2452 {
2453   CORBA::UShort us;
2454   us <<= stream;
2455   return Int_FromLong(us);
2456 }
2457 
2458 static PyObject*
unmarshalPyObjectULong(cdrStream & stream,PyObject * d_o)2459 unmarshalPyObjectULong(cdrStream& stream, PyObject* d_o)
2460 {
2461   CORBA::ULong ul;
2462   ul <<= stream;
2463   return PyLong_FromUnsignedLong(ul);
2464 }
2465 
2466 static PyObject*
unmarshalPyObjectFloat(cdrStream & stream,PyObject * d_o)2467 unmarshalPyObjectFloat(cdrStream& stream, PyObject* d_o)
2468 {
2469   CORBA::Float f;
2470   f <<= stream;
2471   return PyFloat_FromDouble((double)f);
2472 }
2473 
2474 static PyObject*
unmarshalPyObjectDouble(cdrStream & stream,PyObject * d_o)2475 unmarshalPyObjectDouble(cdrStream& stream, PyObject* d_o)
2476 {
2477   CORBA::Double d;
2478   d <<= stream;
2479   return PyFloat_FromDouble(d);
2480 }
2481 
2482 static PyObject*
unmarshalPyObjectBoolean(cdrStream & stream,PyObject * d_o)2483 unmarshalPyObjectBoolean(cdrStream& stream, PyObject* d_o)
2484 {
2485   CORBA::Boolean b = stream.unmarshalBoolean();
2486   return PyBool_FromLong(b);
2487 }
2488 
2489 static PyObject*
unmarshalPyObjectChar(cdrStream & stream,PyObject * d_o)2490 unmarshalPyObjectChar(cdrStream& stream, PyObject* d_o)
2491 {
2492 #if (PY_VERSION_HEX < 0x03000000)
2493   CORBA::Char c = stream.unmarshalChar();
2494   return PyString_FromStringAndSize((const char*)&c, 1);
2495 
2496 #elif (PY_VERSION_HEX < 0x03030000)
2497   Py_UNICODE uc = stream.unmarshalChar();
2498   return PyUnicode_FromUnicode(&uc, 1);
2499 
2500 #else
2501   Py_UCS4   uc  = stream.unmarshalChar();
2502   PyObject* r_o = PyUnicode_New(1, uc);
2503 
2504   PyUnicode_WriteChar(r_o, 0, uc);
2505   return r_o;
2506 
2507 #endif
2508 }
2509 
2510 static PyObject*
unmarshalPyObjectOctet(cdrStream & stream,PyObject * d_o)2511 unmarshalPyObjectOctet(cdrStream& stream, PyObject* d_o)
2512 {
2513   CORBA::Octet o = stream.unmarshalOctet();
2514   return Int_FromLong(o);
2515 }
2516 
2517 static PyObject*
unmarshalPyObjectAny(cdrStream & stream,PyObject * d_o)2518 unmarshalPyObjectAny(cdrStream& stream, PyObject* d_o)
2519 {
2520   // TypeCode
2521   PyObject* desc = omniPy::unmarshalTypeCode(stream);
2522   omniPy::PyRefHolder argtuple(PyTuple_New(1));
2523 
2524   PyTuple_SET_ITEM(argtuple, 0, desc);
2525 
2526   omniPy::PyRefHolder tcobj(PyObject_CallObject(omniPy::pyCreateTypeCode,
2527                                                 argtuple));
2528 
2529   if (!tcobj.valid()) {
2530     // Return exception to caller
2531     return 0;
2532   }
2533 
2534   PyObject* value = omniPy::unmarshalPyObject(stream, desc);
2535 
2536   argtuple = PyTuple_New(2);
2537   PyTuple_SET_ITEM(argtuple, 0, tcobj.retn());
2538   PyTuple_SET_ITEM(argtuple, 1, value);
2539 
2540   return PyObject_CallObject(omniPy::pyCORBAAnyClass, argtuple);
2541 }
2542 
2543 static PyObject*
unmarshalPyObjectTypeCode(cdrStream & stream,PyObject * d_o)2544 unmarshalPyObjectTypeCode(cdrStream& stream, PyObject* d_o)
2545 {
2546   PyObject* t_o      = omniPy::unmarshalTypeCode(stream);
2547   PyObject* argtuple = PyTuple_New(1);
2548   PyTuple_SET_ITEM(argtuple, 0, t_o);
2549   PyObject* r_o      = PyObject_CallObject(omniPy::pyCreateTypeCode, argtuple);
2550   Py_DECREF(argtuple);
2551   return r_o;
2552 }
2553 
2554 static PyObject*
unmarshalPyObjectPrincipal(cdrStream & stream,PyObject * d_o)2555 unmarshalPyObjectPrincipal(cdrStream& stream, PyObject* d_o)
2556 {
2557   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2558 		(CORBA::CompletionStatus)stream.completion());
2559   return 0;
2560 }
2561 
2562 static PyObject*
unmarshalPyObjectObjref(cdrStream & stream,PyObject * d_o)2563 unmarshalPyObjectObjref(cdrStream& stream, PyObject* d_o)
2564 { // repoId, name
2565 
2566   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
2567 
2568   const char* targetRepoId;
2569 
2570   if (t_o == Py_None) {
2571     targetRepoId = 0;
2572   }
2573   else {
2574     OMNIORB_ASSERT(String_Check(t_o));
2575     targetRepoId = String_AS_STRING(t_o);
2576     if (targetRepoId[0] == '\0') { // Empty string => CORBA.Object
2577       targetRepoId = CORBA::Object::_PD_repoId;
2578     }
2579   }
2580   CORBA::Object_ptr obj = omniPy::UnMarshalObjRef(targetRepoId, stream);
2581   return omniPy::createPyCorbaObjRef(targetRepoId, obj);
2582 }
2583 
2584 static PyObject*
unmarshalPyObjectStruct(cdrStream & stream,PyObject * d_o)2585 unmarshalPyObjectStruct(cdrStream& stream, PyObject* d_o)
2586 { // class, repoId, struct name, name, descriptor, ...
2587 
2588   PyObject* strclass = PyTuple_GET_ITEM(d_o, 1);
2589   int       cnt      = (PyTuple_GET_SIZE(d_o) - 4) / 2;
2590 
2591   omniPy::PyRefHolder strtuple(PyTuple_New(cnt));
2592 
2593   int i, j;
2594   for (i=0, j=5; i < cnt; i++, j+=2) {
2595     PyTuple_SET_ITEM(strtuple, i,
2596 		     omniPy::unmarshalPyObject(stream,
2597 					       PyTuple_GET_ITEM(d_o, j)));
2598   }
2599   return PyObject_CallObject(strclass, strtuple);
2600 }
2601 
2602 static PyObject*
unmarshalPyObjectUnion(cdrStream & stream,PyObject * d_o)2603 unmarshalPyObjectUnion(cdrStream& stream, PyObject* d_o)
2604 { // class,
2605   // repoId,
2606   // name,
2607   // discriminant descr,
2608   // default used,
2609   // ((label value, member name, member descr), ...),
2610   // default (label, name, descr) or None,
2611   // {label: (label, name, descr), ...}
2612 
2613   PyObject* unclass = PyTuple_GET_ITEM(d_o, 1);
2614   PyObject* t_o     = PyTuple_GET_ITEM(d_o, 4);
2615   PyObject* cdict   = PyTuple_GET_ITEM(d_o, 8);
2616 
2617   omniPy::PyRefHolder discriminant(omniPy::unmarshalPyObject(stream, t_o));
2618   PyObject* value;
2619 
2620   t_o = PyDict_GetItem(cdict, discriminant);
2621   if (t_o) {
2622     // Discriminant found in case dictionary
2623     OMNIORB_ASSERT(PyTuple_Check(t_o));
2624     value = omniPy::unmarshalPyObject(stream, PyTuple_GET_ITEM(t_o, 2));
2625   }
2626   else {
2627     // Is there a default case?
2628     t_o = PyTuple_GET_ITEM(d_o, 7);
2629     if (t_o != Py_None) {
2630       OMNIORB_ASSERT(PyTuple_Check(t_o));
2631       value = omniPy::unmarshalPyObject(stream, PyTuple_GET_ITEM(t_o, 2));
2632     }
2633     else {
2634       Py_INCREF(Py_None);
2635       value = Py_None;
2636     }
2637   }
2638   omniPy::PyRefHolder untuple(PyTuple_New(2));
2639   PyTuple_SET_ITEM(untuple, 0, discriminant.retn());
2640   PyTuple_SET_ITEM(untuple, 1, value);
2641 
2642   return PyObject_CallObject(unclass, untuple);
2643 }
2644 
2645 static PyObject*
unmarshalPyObjectEnum(cdrStream & stream,PyObject * d_o)2646 unmarshalPyObjectEnum(cdrStream& stream, PyObject* d_o)
2647 { // repoId, name, item list
2648 
2649   PyObject* t_o = PyTuple_GET_ITEM(d_o, 3);
2650 
2651   OMNIORB_ASSERT(PyTuple_Check(t_o));
2652 
2653   CORBA::ULong e;
2654   e <<= stream;
2655 
2656   if (e >= (CORBA::ULong)PyTuple_GET_SIZE(t_o))
2657     OMNIORB_THROW(MARSHAL, MARSHAL_InvalidEnumValue,
2658 		  (CORBA::CompletionStatus)stream.completion());
2659 
2660   PyObject* ev = PyTuple_GET_ITEM(t_o, e);
2661   Py_INCREF(ev);
2662   return ev;
2663 }
2664 
2665 static PyObject*
unmarshalPyObjectString(cdrStream & stream,PyObject * d_o)2666 unmarshalPyObjectString(cdrStream& stream, PyObject* d_o)
2667 { // max_length
2668 
2669   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
2670 
2671   OMNIORB_ASSERT(Int_Check(t_o));
2672 
2673   CORBA::ULong max_len = Int_AS_LONG(t_o);
2674   CORBA::ULong len;
2675   char*        s;
2676 
2677 #if (PY_VERSION_HEX < 0x03000000)
2678   len = orbParameters::nativeCharCodeSet->unmarshalString(stream,
2679                                                           stream.TCS_C(),
2680                                                           max_len, s);
2681 #else
2682   len = omniPy::ncs_c_utf_8->unmarshalString(stream, stream.TCS_C(),
2683                                              max_len, s);
2684 #endif
2685 
2686   PyObject* r_o = String_FromStringAndSize(s, len);
2687   _CORBA_String_helper::dealloc(s);
2688   return r_o;
2689 }
2690 
2691 
2692 static PyObject*
unmarshalPyObjectSeqArray(cdrStream & stream,PyObject * d_o,CORBA::ULong len)2693 unmarshalPyObjectSeqArray(cdrStream& stream, PyObject* d_o, CORBA::ULong len)
2694 {
2695   omniPy::PyRefHolder r_o;
2696 
2697   PyObject* elm_desc = PyTuple_GET_ITEM(d_o, 1);
2698 
2699   // If the sequence length field is greater than the number of
2700   // octets left in the message, the sequence length is invalid.
2701   if (!stream.checkInputOverrun(1, len)) {
2702 
2703     if (Int_Check(elm_desc) && Int_AS_LONG(elm_desc) <= 1) {
2704       // Sequence is a bizarre sequence of void or null, meaning that
2705       // the data takes up no space!  The overrun is therefore not an
2706       // error.
2707     }
2708     else {
2709       OMNIORB_THROW(MARSHAL, MARSHAL_PassEndOfMessage,
2710                     (CORBA::CompletionStatus)stream.completion());
2711     }
2712   }
2713 
2714   CORBA::ULong i;
2715   CORBA::ULong etk;
2716 
2717   if (sequenceOptimisedType(elm_desc, etk)) {
2718     if (etk == CORBA::tk_octet) {
2719       r_o = RawString_FromStringAndSize(0, len);
2720       CORBA::Octet* c = (CORBA::Octet*)RawString_AS_STRING(r_o);
2721       stream.get_octet_array(c, len);
2722       return r_o.retn();
2723     }
2724     else if (etk == CORBA::tk_char) {
2725 
2726 #if (PY_VERSION_HEX < 0x03000000)
2727       r_o = PyString_FromStringAndSize(0, len);
2728       CORBA::Char* c = (CORBA::Char*)PyString_AS_STRING(r_o);
2729 
2730       for (i=0; i<len; i++)
2731         c[i] = stream.unmarshalChar();
2732 
2733 #elif (PY_VERSION_HEX < 0x03030000)
2734       r_o = PyUnicode_FromUnicode(0, len);
2735       Py_UNICODE* uc = PyUnicode_AS_UNICODE(r_o);
2736 
2737       for (i=0; i<len; i++)
2738         uc[i] = stream.unmarshalChar();
2739 
2740 #else
2741       r_o = PyUnicode_New(len, 255);
2742 
2743       int   kind = PyUnicode_KIND(r_o);
2744       void* data = PyUnicode_DATA(r_o);
2745 
2746       for (i=0; i<len; i++)
2747         PyUnicode_WRITE(kind, data, i, stream.unmarshalChar());
2748 #endif
2749 
2750       return r_o.retn();
2751     }
2752     else {
2753       r_o = PyList_New(len);
2754 
2755       switch(etk) {
2756       case CORBA::tk_short:
2757 	{
2758 	  CORBA::Short e;
2759 	  for (i=0; i < len; i++) {
2760 	    e <<= stream;
2761 	    PyList_SET_ITEM(r_o, i, Int_FromLong(e));
2762 	  }
2763 	}
2764 	return r_o.retn();
2765 
2766       case CORBA::tk_long:
2767 	{
2768 	  CORBA::Long e;
2769 	  for (i=0; i < len; i++) {
2770 	    e <<= stream;
2771 	    PyList_SET_ITEM(r_o, i, Int_FromLong(e));
2772 	  }
2773 	}
2774 	return r_o.retn();
2775 
2776       case CORBA::tk_ushort:
2777 	{
2778 	  CORBA::UShort e;
2779 	  for (i=0; i < len; i++) {
2780 	    e <<= stream;
2781 	    PyList_SET_ITEM(r_o, i, Int_FromLong(e));
2782 	  }
2783 	}
2784 	return r_o.retn();
2785 
2786       case CORBA::tk_ulong:
2787 	{
2788 	  CORBA::ULong e;
2789 	  for (i=0; i < len; i++) {
2790 	    e <<= stream;
2791 	    PyList_SET_ITEM(r_o, i, PyLong_FromUnsignedLong(e));
2792 	  }
2793 	}
2794 	return r_o.retn();
2795 
2796       case CORBA::tk_float:
2797 	{
2798 	  CORBA::Float e;
2799 	  for (i=0; i < len; i++) {
2800 	    e <<= stream;
2801 	    PyList_SET_ITEM(r_o, i, PyFloat_FromDouble(e));
2802 	  }
2803 	}
2804 	return r_o.retn();
2805 
2806       case CORBA::tk_double:
2807 	{
2808 	  CORBA::Double e;
2809 	  for (i=0; i < len; i++) {
2810 	    e <<= stream;
2811 	    PyList_SET_ITEM(r_o, i, PyFloat_FromDouble(e));
2812 	  }
2813 	}
2814 	return r_o.retn();
2815 
2816       case CORBA::tk_boolean:
2817 	{
2818 	  CORBA::Boolean e;
2819 	  for (i=0; i < len; i++) {
2820 	    e = stream.unmarshalBoolean();
2821 	    PyList_SET_ITEM(r_o, i, PyBool_FromLong(e));
2822 	  }
2823 	}
2824 	return r_o.retn();
2825 
2826 #ifdef HAS_LongLong
2827 
2828       case CORBA::tk_longlong:
2829 	{
2830 	  CORBA::LongLong e;
2831 	  for (i=0; i < len; i++) {
2832 	    e <<= stream;
2833 	    PyList_SET_ITEM(r_o, i, PyLong_FromLongLong(e));
2834 	  }
2835 	}
2836 	return r_o.retn();
2837 
2838       case CORBA::tk_ulonglong:
2839 	{
2840 	  CORBA::ULongLong e;
2841 	  for (i=0; i < len; i++) {
2842 	    e <<= stream;
2843 	    PyList_SET_ITEM(r_o, i, PyLong_FromUnsignedLongLong(e));
2844 	  }
2845 	}
2846 	return r_o.retn();
2847 #else
2848       case 23:
2849 	OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2850 		      (CORBA::CompletionStatus)stream.completion());
2851 	return 0;
2852 
2853       case 24:
2854 	OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2855 		      (CORBA::CompletionStatus)stream.completion());
2856 	return 0;
2857 #endif
2858       default:
2859 	OMNIORB_ASSERT(0);
2860 	return 0;
2861       }
2862     }
2863   }
2864   else {
2865     r_o = PyList_New(len);
2866 
2867     for (i=0; i < len; i++)
2868       PyList_SET_ITEM(r_o, i, omniPy::unmarshalPyObject(stream, elm_desc));
2869 
2870     return r_o.retn();
2871   }
2872 }
2873 
2874 
2875 static PyObject*
unmarshalPyObjectSequence(cdrStream & stream,PyObject * d_o)2876 unmarshalPyObjectSequence(cdrStream& stream, PyObject* d_o)
2877 { // element_desc, max_length
2878 
2879   PyObject* t_o = PyTuple_GET_ITEM(d_o, 2);
2880   OMNIORB_ASSERT(Int_Check(t_o));
2881 
2882   CORBA::ULong max_len = Int_AS_LONG(t_o);
2883   CORBA::ULong len;
2884   len <<= stream;
2885 
2886   if (max_len > 0 && len > max_len)
2887     OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong,
2888 		  (CORBA::CompletionStatus)stream.completion());
2889 
2890   return unmarshalPyObjectSeqArray(stream, d_o, len);
2891 }
2892 
2893 
2894 static PyObject*
unmarshalPyObjectArray(cdrStream & stream,PyObject * d_o)2895 unmarshalPyObjectArray(cdrStream& stream, PyObject* d_o)
2896 { // element_desc, length
2897 
2898   PyObject* t_o = PyTuple_GET_ITEM(d_o, 2);
2899   OMNIORB_ASSERT(Int_Check(t_o));
2900 
2901   CORBA::ULong len      = Int_AS_LONG(t_o);
2902   PyObject*    elm_desc = PyTuple_GET_ITEM(d_o, 1);
2903 
2904   return unmarshalPyObjectSeqArray(stream, d_o, len);
2905 }
2906 
2907 
2908 static PyObject*
unmarshalPyObjectAlias(cdrStream & stream,PyObject * d_o)2909 unmarshalPyObjectAlias(cdrStream& stream, PyObject* d_o)
2910 { // repoId, name, descr
2911 
2912   return omniPy::unmarshalPyObject(stream, PyTuple_GET_ITEM(d_o, 3));
2913 }
2914 
2915 static PyObject*
unmarshalPyObjectExcept(cdrStream & stream,PyObject * d_o)2916 unmarshalPyObjectExcept(cdrStream& stream, PyObject* d_o)
2917 { // class, repoId, exc name, name, descriptor, ...
2918 
2919   // Throw away the repoId. By the time we get here, we already
2920   // know it.
2921   // *** Should maybe check to see if it's what we're expecting
2922   CORBA::ULong len; len <<= stream;
2923   stream.skipInput(len);
2924 
2925   PyObject* strclass = PyTuple_GET_ITEM(d_o, 1);
2926   int       cnt      = (PyTuple_GET_SIZE(d_o) - 4) / 2;
2927 
2928   omniPy::PyRefHolder strtuple(PyTuple_New(cnt));
2929 
2930   int i, j;
2931   for (i=0, j=5; i < cnt; i++, j+=2) {
2932     PyTuple_SET_ITEM(strtuple, i,
2933 		     omniPy::unmarshalPyObject(stream,
2934 					       PyTuple_GET_ITEM(d_o, j)));
2935   }
2936   return PyObject_CallObject(strclass, strtuple);
2937 }
2938 
2939 static PyObject*
unmarshalPyObjectLongLong(cdrStream & stream,PyObject * d_o)2940 unmarshalPyObjectLongLong(cdrStream& stream, PyObject* d_o)
2941 {
2942 #ifdef HAS_LongLong
2943   CORBA::LongLong ll;
2944   ll <<= stream;
2945   return PyLong_FromLongLong(ll);
2946 #else
2947   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2948 		(CORBA::CompletionStatus)stream.completion());
2949   return 0;
2950 #endif
2951 }
2952 
2953 static PyObject*
unmarshalPyObjectULongLong(cdrStream & stream,PyObject * d_o)2954 unmarshalPyObjectULongLong(cdrStream& stream, PyObject* d_o)
2955 {
2956 #ifdef HAS_LongLong
2957   CORBA::ULongLong ull;
2958   ull <<= stream;
2959   return PyLong_FromUnsignedLongLong(ull);
2960 #else
2961   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2962 		(CORBA::CompletionStatus)stream.completion());
2963   return 0;
2964 #endif
2965 }
2966 
2967 static PyObject*
unmarshalPyObjectLongDouble(cdrStream & stream,PyObject * d_o)2968 unmarshalPyObjectLongDouble(cdrStream& stream, PyObject* d_o)
2969 {
2970   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
2971 		(CORBA::CompletionStatus)stream.completion());
2972   return 0;
2973 }
2974 
2975 static PyObject*
unmarshalPyObjectWChar(cdrStream & stream,PyObject * d_o)2976 unmarshalPyObjectWChar(cdrStream& stream, PyObject* d_o)
2977 {
2978   OMNIORB_CHECK_TCS_W_FOR_UNMARSHAL(stream.TCS_W(), stream);
2979 
2980   Py_UNICODE  c   = stream.TCS_W()->unmarshalWChar(stream);
2981   PyObject*   r_o = PyUnicode_FromUnicode(0, 1);
2982   Py_UNICODE* str = PyUnicode_AS_UNICODE(r_o);
2983   str[0]          = c;
2984   str[1]          = 0;
2985   return r_o;
2986 }
2987 
2988 static PyObject*
unmarshalPyObjectWString(cdrStream & stream,PyObject * d_o)2989 unmarshalPyObjectWString(cdrStream& stream, PyObject* d_o)
2990 { // max_length
2991 
2992   OMNIORB_CHECK_TCS_W_FOR_UNMARSHAL(stream.TCS_W(), stream);
2993 
2994   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
2995 
2996   OMNIORB_ASSERT(Int_Check(t_o));
2997 
2998   CORBA::ULong max_len = Int_AS_LONG(t_o);
2999 
3000   omniCodeSet::UniChar* us;
3001   CORBA::ULong len = stream.TCS_W()->unmarshalWString(stream, max_len, us);
3002 
3003 #if defined(Py_UNICODE_WIDE) || (PY_VERSION_HEX >= 0x03030000)
3004 
3005 #  if _OMNIORB_HOST_BYTE_ORDER_ == 0
3006   int byteorder = 1;  // Big endian
3007 #  else
3008   int byteorder = -1; // Little endian
3009 #  endif
3010   PyObject* r_o = PyUnicode_DecodeUTF16((const char*)us, len*2, 0, &byteorder);
3011 
3012 #else
3013   PyObject* r_o = PyUnicode_FromUnicode((Py_UNICODE*)us, len);
3014 #endif
3015 
3016   omniCodeSetUtil::freeU(us);
3017   return r_o;
3018 }
3019 
3020 static PyObject*
unmarshalPyObjectFixed(cdrStream & stream,PyObject * d_o)3021 unmarshalPyObjectFixed(cdrStream& stream, PyObject* d_o)
3022 { // digits, scale
3023   PyObject* t_o;
3024 
3025   t_o = PyTuple_GET_ITEM(d_o, 1); int dlimit = Int_AS_LONG(t_o);
3026   t_o = PyTuple_GET_ITEM(d_o, 2); int slimit = Int_AS_LONG(t_o);
3027 
3028   CORBA::Fixed f;
3029   f.PR_setLimits(dlimit, slimit);
3030 
3031   f <<= stream;
3032 
3033   return omniPy::newFixedObject(f);
3034 }
3035 
3036 // unmarshalPyObjectValue is in pyValueType.cc. It does both values
3037 // and valueboxes.
3038 
3039 static PyObject*
unmarshalPyObjectNative(cdrStream & stream,PyObject * d_o)3040 unmarshalPyObjectNative(cdrStream& stream, PyObject* d_o)
3041 {
3042   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported,
3043 		(CORBA::CompletionStatus)stream.completion());
3044   return 0;
3045 }
3046 
3047 // unmarshalPyObjectAbstractInterface is in pyAbstractIntf.cc
3048 
3049 static PyObject*
unmarshalPyObjectLocalInterface(cdrStream & stream,PyObject * d_o)3050 unmarshalPyObjectLocalInterface(cdrStream& stream, PyObject* d_o)
3051 {
3052   OMNIORB_THROW(MARSHAL, MARSHAL_LocalObject,
3053 		(CORBA::CompletionStatus)stream.completion());
3054   return 0;
3055 }
3056 
3057 PyObject*
3058 omniPy::
unmarshalPyObjectIndirect(cdrStream & stream,PyObject * d_o)3059 unmarshalPyObjectIndirect(cdrStream& stream, PyObject* d_o)
3060 {
3061   PyObject* l = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyList_Check(l));
3062   PyObject* d = PyList_GET_ITEM(l, 0);
3063 
3064   if (String_Check(d)) {
3065     // Indirection to a repoId -- find the corresponding descriptor
3066     d = PyDict_GetItem(pyomniORBtypeMap, d);
3067     if (!d)
3068       OMNIORB_THROW(BAD_PARAM, BAD_PARAM_IncompletePythonType,
3069 		    (CORBA::CompletionStatus)stream.completion());
3070     Py_INCREF(d);
3071     PyList_SetItem(l, 0, d);
3072   }
3073   return unmarshalPyObject(stream, d);
3074 }
3075 
3076 
3077 const omniPy::UnmarshalPyObjectFn omniPy::unmarshalPyObjectFns[] = {
3078   unmarshalPyObjectNull,
3079   unmarshalPyObjectVoid,
3080   unmarshalPyObjectShort,
3081   unmarshalPyObjectLong,
3082   unmarshalPyObjectUShort,
3083   unmarshalPyObjectULong,
3084   unmarshalPyObjectFloat,
3085   unmarshalPyObjectDouble,
3086   unmarshalPyObjectBoolean,
3087   unmarshalPyObjectChar,
3088   unmarshalPyObjectOctet,
3089   unmarshalPyObjectAny,
3090   unmarshalPyObjectTypeCode,
3091   unmarshalPyObjectPrincipal,
3092   unmarshalPyObjectObjref,
3093   unmarshalPyObjectStruct,
3094   unmarshalPyObjectUnion,
3095   unmarshalPyObjectEnum,
3096   unmarshalPyObjectString,
3097   unmarshalPyObjectSequence,
3098   unmarshalPyObjectArray,
3099   unmarshalPyObjectAlias,
3100   unmarshalPyObjectExcept,
3101   unmarshalPyObjectLongLong,
3102   unmarshalPyObjectULongLong,
3103   unmarshalPyObjectLongDouble,
3104   unmarshalPyObjectWChar,
3105   unmarshalPyObjectWString,
3106   unmarshalPyObjectFixed,
3107   omniPy::unmarshalPyObjectValue,
3108   omniPy::unmarshalPyObjectValue, // Same function as value
3109   unmarshalPyObjectNative,
3110   omniPy::unmarshalPyObjectAbstractInterface,
3111   unmarshalPyObjectLocalInterface
3112 };
3113 
3114 
3115 
3116 static PyObject*
copyArgumentNull(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3117 copyArgumentNull(PyObject* d_o, PyObject* a_o,
3118 		 CORBA::CompletionStatus compstatus)
3119 {
3120   if (a_o != Py_None)
3121     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3122 		       omniPy::formatString("Expecting None, got %r",
3123 					    "O", a_o->ob_type));
3124 
3125   Py_INCREF(Py_None);
3126   return Py_None;
3127 }
3128 
3129 static PyObject*
copyArgumentVoid(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3130 copyArgumentVoid(PyObject* d_o, PyObject* a_o,
3131 		 CORBA::CompletionStatus compstatus)
3132 {
3133   if (a_o != Py_None)
3134     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3135 		       omniPy::formatString("Expecting None, got %r",
3136 					    "O", a_o->ob_type));
3137 
3138   Py_INCREF(Py_None);
3139   return Py_None;
3140 }
3141 
3142 static PyObject*
copyArgumentShort(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3143 copyArgumentShort(PyObject* d_o, PyObject* a_o,
3144 		  CORBA::CompletionStatus compstatus)
3145 {
3146   long l;
3147 
3148 #if (PY_VERSION_HEX < 0x03000000)
3149   if (PyInt_Check(a_o)) {
3150     l = PyInt_AS_LONG(a_o);
3151     if (l < -0x8000 || l > 0x7fff) {
3152       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3153 			 omniPy::formatString("%s is out of range for short",
3154 					      "O", a_o));
3155     }
3156     Py_INCREF(a_o); return a_o;
3157   }
3158   else
3159 #endif
3160   if (PyLong_Check(a_o)) {
3161     l = PyLong_AsLong(a_o);
3162     if (l == -1 && PyErr_Occurred()) {
3163       PyErr_Clear();
3164       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3165 			 omniPy::formatString("%s is out of range for short",
3166 					      "O", a_o));
3167     }
3168     else if (l < -0x8000 || l > 0x7fff) {
3169       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3170 			 omniPy::formatString("%s is out of range for short",
3171 					      "O", a_o));
3172     }
3173 #if (PY_VERSION_HEX < 0x03000000)
3174     return PyInt_FromLong(l);
3175 #else
3176     Py_INCREF(a_o); return a_o;
3177 #endif
3178   }
3179   else {
3180     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3181 		       omniPy::formatString("Expecting short, got %r",
3182 					    "O", a_o->ob_type));
3183   }
3184   return 0;
3185 }
3186 
3187 static PyObject*
copyArgumentLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3188 copyArgumentLong(PyObject* d_o, PyObject* a_o,
3189 		 CORBA::CompletionStatus compstatus)
3190 {
3191 #if (PY_VERSION_HEX < 0x03000000)
3192   if (PyInt_Check(a_o)) {
3193 #  if SIZEOF_LONG > 4
3194     long l = PyInt_AS_LONG(a_o);
3195     if (l < -0x80000000L || l > 0x7fffffffL) {
3196       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3197 			 omniPy::formatString("%s is out of range for long",
3198 					      "O", a_o));
3199     }
3200 #  endif
3201     Py_INCREF(a_o); return a_o;
3202   }
3203   else
3204 #endif
3205   if (PyLong_Check(a_o)) {
3206     long l = PyLong_AsLong(a_o);
3207     if (l == -1 && PyErr_Occurred()) {
3208       PyErr_Clear();
3209       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3210 			 omniPy::formatString("%s is out of range for long",
3211 					      "O", a_o));
3212     }
3213 #if SIZEOF_LONG > 4
3214     if (l < -0x80000000L || l > 0x7fffffffL) {
3215       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3216 			 omniPy::formatString("%s is out of range for long",
3217 					      "O", a_o));
3218     }
3219 #endif
3220 
3221 #if (PY_VERSION_HEX < 0x03000000)
3222     return PyInt_FromLong(l);
3223 #else
3224     Py_INCREF(a_o); return a_o;
3225 #endif
3226   }
3227   else {
3228     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3229 		       omniPy::formatString("Expecting long, got %r",
3230 					    "O", a_o->ob_type));
3231   }
3232   return 0;
3233 }
3234 
3235 static PyObject*
copyArgumentUShort(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3236 copyArgumentUShort(PyObject* d_o, PyObject* a_o,
3237 		   CORBA::CompletionStatus compstatus)
3238 {
3239 #if (PY_VERSION_HEX < 0x03000000)
3240   if (PyInt_Check(a_o)) {
3241     long l = PyInt_AS_LONG(a_o);
3242     if (l < 0 || l > 0xffff) {
3243       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3244 			 omniPy::formatString("%s is out of range for "
3245 					      "unsigned short",
3246 					      "O", a_o));
3247     }
3248     Py_INCREF(a_o); return a_o;
3249   }
3250   else
3251 #endif
3252   if (PyLong_Check(a_o)) {
3253     long l = PyLong_AsLong(a_o);
3254     if (l == -1 && PyErr_Occurred()) {
3255       PyErr_Clear();
3256       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3257 			 omniPy::formatString("%s is out of range for "
3258 					      "unsigned short",
3259 					      "O", a_o));
3260     }
3261     else if (l < 0 || l > 0xffff) {
3262       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3263 			 omniPy::formatString("%s is out of range for "
3264 					      "unsigned short",
3265 					      "O", a_o));
3266     }
3267 #if (PY_VERSION_HEX < 0x03000000)
3268     return PyInt_FromLong(l);
3269 #else
3270     Py_INCREF(a_o); return a_o;
3271 #endif
3272   }
3273   else {
3274     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3275 		       omniPy::formatString("Expecting unsigned short, got %r",
3276 					    "O", a_o->ob_type));
3277   }
3278   return 0;
3279 }
3280 
3281 static PyObject*
copyArgumentULong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3282 copyArgumentULong(PyObject* d_o, PyObject* a_o,
3283 		  CORBA::CompletionStatus compstatus)
3284 {
3285   if (PyLong_Check(a_o)) {
3286     unsigned long ul = PyLong_AsUnsignedLong(a_o);
3287     if (ul == (unsigned long)-1 && PyErr_Occurred()) {
3288       PyErr_Clear();
3289       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3290 			 omniPy::formatString("%s is out of range for "
3291 					      "unsigned long",
3292 					      "O", a_o));
3293     }
3294 #if SIZEOF_LONG > 4
3295     if (ul > 0xffffffffL) {
3296       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3297 			 omniPy::formatString("%s is out of range for "
3298 					      "unsigned long",
3299 					      "O", a_o));
3300     }
3301 #endif
3302     Py_INCREF(a_o); return a_o;
3303   }
3304 #if (PY_VERSION_HEX < 0x03000000)
3305   else if (PyInt_Check(a_o)) {
3306     long l = PyInt_AS_LONG(a_o);
3307 #  if SIZEOF_LONG > 4
3308     if (l < 0 || l > 0xffffffffL) {
3309       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3310 			 omniPy::formatString("%s is out of range for "
3311 					      "unsigned long",
3312 					      "O", a_o));
3313     }
3314 #  else
3315     if (l < 0) {
3316       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3317 			 omniPy::formatString("%s is out of range for "
3318 					      "unsigned long",
3319 					      "O", a_o));
3320     }
3321 #  endif
3322     return PyLong_FromLong(l);
3323   }
3324 #endif
3325   else {
3326     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3327 		       omniPy::formatString("Expecting unsigned long, got %r",
3328 					    "O", a_o->ob_type));
3329   }
3330   return 0;
3331 }
3332 
3333 static PyObject*
copyArgumentFloat(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3334 copyArgumentFloat(PyObject* d_o, PyObject* a_o,
3335 		  CORBA::CompletionStatus compstatus)
3336 {
3337   // *** This accepts values that are too big to fit in a float. It
3338   // *** should complain.
3339 
3340   if (PyFloat_Check(a_o)) {
3341     Py_INCREF(a_o); return a_o;
3342   }
3343 #if (PY_VERSION_HEX < 0x03000000)
3344   else if (PyInt_Check(a_o)) {
3345     return PyFloat_FromDouble((double)(PyInt_AS_LONG(a_o)));
3346   }
3347 #endif
3348   else if (PyLong_Check(a_o)) {
3349     double d;
3350     d = PyLong_AsDouble(a_o);
3351     if (d == -1.0 && PyErr_Occurred()) {
3352       PyErr_Clear();
3353       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3354 			 omniPy::formatString("%s is out of range for float",
3355 					      "O", a_o));
3356     }
3357     return PyFloat_FromDouble(d);
3358   }
3359   else {
3360     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3361 		       omniPy::formatString("Expecting float, got %r",
3362 					    "O", a_o->ob_type));
3363   }
3364   return 0;
3365 }
3366 
3367 static PyObject*
copyArgumentDouble(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3368 copyArgumentDouble(PyObject* d_o, PyObject* a_o,
3369 		   CORBA::CompletionStatus compstatus)
3370 {
3371   if (PyFloat_Check(a_o)) {
3372     Py_INCREF(a_o); return a_o;
3373   }
3374 #if (PY_VERSION_HEX < 0x03000000)
3375   else if (PyInt_Check(a_o)) {
3376     return PyFloat_FromDouble((double)(PyInt_AS_LONG(a_o)));
3377   }
3378 #endif
3379   else if (PyLong_Check(a_o)) {
3380     double d;
3381     d = PyLong_AsDouble(a_o);
3382     if (d == -1.0 && PyErr_Occurred()) {
3383       PyErr_Clear();
3384       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3385 			 omniPy::formatString("%s is out of range for double",
3386 					      "O", a_o));
3387     }
3388     return PyFloat_FromDouble(d);
3389   }
3390   else {
3391     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3392 		       omniPy::formatString("Expecting double, got %r",
3393 					    "O", a_o->ob_type));
3394   }
3395   return 0;
3396 }
3397 
3398 static PyObject*
copyArgumentBoolean(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3399 copyArgumentBoolean(PyObject* d_o, PyObject* a_o,
3400 		    CORBA::CompletionStatus compstatus)
3401 {
3402   if (PyBool_Check(a_o)) {
3403     Py_INCREF(a_o);
3404     return a_o;
3405   }
3406 
3407   int i = PyObject_IsTrue(a_o);
3408 
3409   if (i == -1) {
3410     if (omniORB::trace(1))
3411       PyErr_Print();
3412     else
3413       PyErr_Clear();
3414 
3415     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3416 		       omniPy::formatString("Expecting bool, got %r",
3417 					    "O", a_o->ob_type));
3418   }
3419 
3420   PyObject* r_o = i ? Py_True : Py_False;
3421   Py_INCREF(r_o);
3422   return r_o;
3423 }
3424 
3425 static PyObject*
copyArgumentChar(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3426 copyArgumentChar(PyObject* d_o, PyObject* a_o,
3427 		 CORBA::CompletionStatus compstatus)
3428 {
3429   if (!String_Check(a_o)) {
3430     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3431 		       omniPy::formatString("Expecting string, got %r",
3432 					    "O", a_o->ob_type));
3433   }
3434   if (String_GET_SIZE(a_o) != 1) {
3435     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3436 		       omniPy::formatString("Expecting string of length 1, "
3437 					    "got %r",
3438 					    "O", a_o));
3439   }
3440   Py_INCREF(a_o); return a_o;
3441 }
3442 
3443 static PyObject*
copyArgumentOctet(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3444 copyArgumentOctet(PyObject* d_o, PyObject* a_o,
3445 		  CORBA::CompletionStatus compstatus)
3446 {
3447 #if (PY_VERSION_HEX < 0x03000000)
3448   if (PyInt_Check(a_o)) {
3449     long l = PyInt_AS_LONG(a_o);
3450     if (l < 0 || l > 0xff) {
3451       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3452 			 omniPy::formatString("%s is out of range for octet",
3453 					      "O", a_o));
3454     }
3455     Py_INCREF(a_o); return a_o;
3456   }
3457   else
3458 #endif
3459   if (PyLong_Check(a_o)) {
3460     long l = PyLong_AsLong(a_o);
3461     if (l == -1 && PyErr_Occurred()) {
3462       PyErr_Clear();
3463       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3464 			 omniPy::formatString("%s is out of range for octet",
3465 					      "O", a_o));
3466     }
3467     if (l < 0 || l > 0xff) {
3468       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3469 			 omniPy::formatString("%s is out of range for octet",
3470 					      "O", a_o));
3471     }
3472 #if (PY_VERSION_HEX < 0x03000000)
3473     return PyInt_FromLong(l);
3474 #else
3475     Py_INCREF(a_o); return a_o;
3476 #endif
3477   }
3478   else {
3479     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3480 		       omniPy::formatString("Expecting octet, got %r",
3481 					    "O", a_o->ob_type));
3482   }
3483   return 0;
3484 }
3485 
3486 static PyObject*
copyArgumentAny(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3487 copyArgumentAny(PyObject* d_o, PyObject* a_o,
3488 		CORBA::CompletionStatus compstatus)
3489 {
3490   if (!PyObject_IsInstance(a_o, omniPy::pyCORBAAnyClass)) {
3491     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3492 		       omniPy::formatString("Expecting Any, got %r",
3493 					    "O", a_o->ob_type));
3494   }
3495 
3496   // TypeCode
3497   omniPy::PyRefHolder tc(PyObject_GetAttrString(a_o, (char*)"_t"));
3498 
3499   if (!tc.valid()) {
3500     PyErr_Clear();
3501     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3502 		       String_FromString("Any has no TypeCode _t"));
3503   }
3504 
3505   if (!PyObject_IsInstance(tc, omniPy::pyCORBATypeCodeClass)) {
3506     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3507 		       omniPy::formatString("Expecting TypeCode in Any, got %r",
3508 					    "O", a_o->ob_type));
3509   }
3510 
3511   omniPy::PyRefHolder desc(PyObject_GetAttrString(tc, (char*)"_d"));
3512   if (!desc.valid()) {
3513     PyErr_Clear();
3514     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3515 		       String_FromString("TypeCode in Any has no "
3516                                          "descriptor _d"));
3517   }
3518 
3519   // Any's contents
3520   omniPy::PyRefHolder val(PyObject_GetAttrString(a_o, (char*)"_v"));
3521   if (!val.valid()) {
3522     PyErr_Clear();
3523     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3524 		       String_FromString("Any has no value _v"));
3525   }
3526 
3527   // Copy contents
3528   PyObject* cval;
3529 
3530   try {
3531     cval = omniPy::copyArgument(desc, val, compstatus);
3532   }
3533   catch (Py_BAD_PARAM& bp) {
3534     bp.add(String_FromString("Value inside Any"));
3535     throw;
3536   }
3537 
3538   // Construct new Any
3539   omniPy::PyRefHolder argtuple(PyTuple_New(2));
3540   Py_INCREF(tc);
3541   PyTuple_SET_ITEM(argtuple, 0, tc);
3542   PyTuple_SET_ITEM(argtuple, 1, cval);
3543 
3544   return PyObject_CallObject(omniPy::pyCORBAAnyClass, argtuple);
3545 }
3546 
3547 static PyObject*
copyArgumentTypeCode(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3548 copyArgumentTypeCode(PyObject* d_o, PyObject* a_o,
3549 		     CORBA::CompletionStatus compstatus)
3550 {
3551   if (!PyObject_IsInstance(a_o, omniPy::pyCORBATypeCodeClass)) {
3552     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3553 		       omniPy::formatString("Expecting TypeCode, got %r",
3554 					    "O", a_o->ob_type));
3555   }
3556   PyObject* desc = PyObject_GetAttrString(a_o, (char*)"_d");
3557 
3558   if (!desc) {
3559     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3560 		       String_FromString("TypeCode in has no descriptor _d"));
3561   }
3562   Py_DECREF(desc);
3563   Py_INCREF(a_o); return a_o;
3564 }
3565 
3566 static PyObject*
copyArgumentPrincipal(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3567 copyArgumentPrincipal(PyObject* d_o, PyObject* a_o,
3568 		      CORBA::CompletionStatus compstatus)
3569 {
3570   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
3571   return 0;
3572 }
3573 
3574 static PyObject*
copyArgumentObjref(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3575 copyArgumentObjref(PyObject* d_o, PyObject* a_o,
3576 		   CORBA::CompletionStatus compstatus)
3577 { // repoId, name
3578 
3579   return omniPy::copyObjRefArgument(PyTuple_GET_ITEM(d_o, 1),
3580 				    a_o, compstatus);
3581 }
3582 
3583 static PyObject*
copyArgumentStruct(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3584 copyArgumentStruct(PyObject* d_o, PyObject* a_o,
3585 		   CORBA::CompletionStatus compstatus)
3586 { // class, repoId, struct name, name, descriptor, ...
3587 
3588   // The descriptor tuple has twice the number of struct members,
3589   // plus 4 -- the typecode kind, the Python class, the repoId,
3590   // and the struct name
3591   int cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
3592 
3593   PyObject* t_o;
3594   PyObject* name;
3595   omniPy::PyRefHolder value;
3596   omniPy::PyRefHolder argtuple(PyTuple_New(cnt));
3597 
3598   int i, j;
3599 
3600   for (i=0,j=4; i < cnt; i++,j++) {
3601     name  = PyTuple_GET_ITEM(d_o, j++); OMNIORB_ASSERT(String_Check(name));
3602     value = PyObject_GetAttr(a_o, name);
3603 
3604     if (value.valid()) {
3605       try {
3606 	t_o = omniPy::copyArgument(PyTuple_GET_ITEM(d_o, j),
3607 				   value, compstatus);
3608       }
3609       catch (Py_BAD_PARAM& bp) {
3610 	bp.add(omniPy::formatString("Struct %r member %r", "OO",
3611 				    PyTuple_GET_ITEM(d_o, 3), name));
3612 	throw;
3613       }
3614       PyTuple_SET_ITEM(argtuple, i, t_o);
3615     }
3616     else {
3617       PyErr_Clear();
3618       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3619 			 omniPy::formatString("Struct %r instance %r "
3620 					      "has no %r member",
3621 					      "OOO",
3622 					      PyTuple_GET_ITEM(d_o, 3),
3623 					      a_o->ob_type,
3624 					      name));
3625     }
3626   }
3627   return PyObject_CallObject(PyTuple_GET_ITEM(d_o, 1), argtuple);
3628 }
3629 
3630 static PyObject*
copyArgumentUnion(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3631 copyArgumentUnion(PyObject* d_o, PyObject* a_o,
3632 		  CORBA::CompletionStatus compstatus)
3633 { // class,
3634   // repoId,
3635   // name,
3636   // discriminant descr,
3637   // default used,
3638   // ((label value, member name, member descr), ...),
3639   // default (label, name, descr) or None,
3640   // {label: (label, name, descr), ...}
3641 
3642   omniPy::PyRefHolder discr(PyObject_GetAttrString(a_o, (char*)"_d"));
3643   if (!discr.valid()) {
3644     PyErr_Clear();
3645     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3646 		       omniPy::formatString("Expecting union, got %r",
3647 					    "O", a_o->ob_type));
3648   }
3649 
3650   omniPy::PyRefHolder value(PyObject_GetAttrString(a_o, (char*)"_v"));
3651   if (!value.valid()) {
3652     PyErr_Clear();
3653     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3654 		       omniPy::formatString("Expecting union, got %r",
3655 					    "O", a_o->ob_type));
3656   }
3657 
3658   PyObject* t_o = PyTuple_GET_ITEM(d_o, 4);
3659   PyObject* cdiscr;
3660 
3661   try {
3662     cdiscr = omniPy::copyArgument(t_o, discr, compstatus);
3663   }
3664   catch (Py_BAD_PARAM& bp) {
3665     bp.add(String_FromString("Union discriminant"));
3666     throw;
3667   }
3668 
3669   omniPy::PyRefHolder cdiscr_holder(cdiscr);
3670 
3671   PyObject* cvalue = 0;
3672   PyObject* cdict  = PyTuple_GET_ITEM(d_o, 8);
3673   t_o              = PyDict_GetItem(cdict, discr);
3674   if (t_o) {
3675     // Discriminant found in case dictionary
3676     OMNIORB_ASSERT(PyTuple_Check(t_o));
3677     cvalue = omniPy::copyArgument(PyTuple_GET_ITEM(t_o, 2), value, compstatus);
3678   }
3679   else {
3680     // Is there a default case?
3681     t_o = PyTuple_GET_ITEM(d_o, 7);
3682     if (t_o == Py_None) {
3683       // No default
3684       Py_INCREF(Py_None);
3685       cvalue = Py_None;
3686     }
3687     else {
3688       OMNIORB_ASSERT(PyTuple_Check(t_o));
3689       try {
3690 	cvalue = omniPy::copyArgument(PyTuple_GET_ITEM(t_o, 2),
3691 				      value, compstatus);
3692       }
3693       catch (Py_BAD_PARAM& bp) {
3694 	bp.add(omniPy::formatString("Union member %r", "O",
3695 				    PyTuple_GET_ITEM(t_o, 1)));
3696 	throw;
3697       }
3698     }
3699   }
3700   t_o = PyTuple_New(2);
3701   PyTuple_SET_ITEM(t_o, 0, cdiscr_holder.retn());
3702   PyTuple_SET_ITEM(t_o, 1, cvalue);
3703   PyObject* r_o = PyObject_CallObject(PyTuple_GET_ITEM(d_o, 1), t_o);
3704   Py_DECREF(t_o);
3705   return r_o;
3706 }
3707 
3708 
3709 static PyObject*
copyArgumentEnum(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3710 copyArgumentEnum(PyObject* d_o, PyObject* a_o,
3711 		 CORBA::CompletionStatus compstatus)
3712 { // repoId, name, item list
3713 
3714   omniPy::PyRefHolder ev(PyObject_GetAttrString(a_o, (char*)"_v"));
3715 
3716   if (!(ev.valid() && Int_Check(ev))) {
3717     PyErr_Clear();
3718     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3719 		       omniPy::formatString("Expecting enum %r item, got %r",
3720 					    "OO",
3721 					    PyTuple_GET_ITEM(d_o, 2),
3722 					    a_o->ob_type));
3723   }
3724 
3725   PyObject* t_o = PyTuple_GET_ITEM(d_o, 3);
3726   long      e   = Int_AS_LONG(ev);
3727 
3728   if (e >= PyTuple_GET_SIZE(t_o)) {
3729     THROW_PY_BAD_PARAM(BAD_PARAM_EnumValueOutOfRange, compstatus,
3730 		       omniPy::formatString("Expecting enum %r item, got %r",
3731 					    "OO",
3732 					    PyTuple_GET_ITEM(d_o, 2),
3733 					    a_o));
3734   }
3735   if (PyTuple_GET_ITEM(t_o, e) != a_o) {
3736     // EnumItem object is not the one we expected -- are they equivalent?
3737     int cmp;
3738 
3739 #if (PY_VERSION_HEX < 0x03000000)
3740 
3741     if (PyObject_Cmp(PyTuple_GET_ITEM(t_o, e), a_o, &cmp) == -1)
3742       omniPy::handlePythonException();
3743 
3744     if (cmp != 0) {
3745       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3746 			 omniPy::formatString("Expecting enum %r item, "
3747 					      "got %r",
3748 					      "OO",
3749 					      PyTuple_GET_ITEM(d_o, 2),
3750 					      a_o));
3751     }
3752 
3753 #else
3754     cmp = PyObject_RichCompareBool(PyTuple_GET_ITEM(t_o, e), a_o, Py_EQ);
3755     if (cmp == -1)
3756       omniPy::handlePythonException();
3757 
3758     if (cmp != 1) {
3759       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3760 			 omniPy::formatString("Expecting enum %r item, "
3761 					      "got %r",
3762 					      "OO",
3763 					      PyTuple_GET_ITEM(d_o, 2),
3764 					      a_o));
3765     }
3766 #endif
3767     a_o = PyTuple_GET_ITEM(t_o, e);
3768   }
3769   Py_INCREF(a_o); return a_o;
3770 }
3771 
3772 
3773 static PyObject*
copyArgumentString(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)3774 copyArgumentString(PyObject* d_o, PyObject* a_o,
3775 		   CORBA::CompletionStatus compstatus)
3776 { // max_length
3777 
3778   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
3779   OMNIORB_ASSERT(Int_Check(t_o));
3780 
3781   CORBA::ULong max_len = Int_AS_LONG(t_o);
3782 
3783   if (!String_Check(a_o)) {
3784     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3785 		       omniPy::formatString("Expecting string, got %r",
3786 					    "O", a_o->ob_type));
3787   }
3788 
3789   CORBA::ULong len = String_GET_SIZE(a_o);
3790 
3791   if (max_len > 0 && len > max_len)
3792     OMNIORB_THROW(MARSHAL, MARSHAL_StringIsTooLong, compstatus);
3793 
3794   // Annoyingly, we have to scan the string to check there are no
3795   // nulls
3796 
3797 #if (PY_VERSION_HEX < 0x03000000)
3798 
3799   char* str = PyString_AS_STRING(a_o);
3800   for (CORBA::ULong i=0; i != len; ++i) {
3801     if (str[i] == '\0') {
3802       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
3803 			 omniPy::formatString("Embedded null in string "
3804 					      "at position %d",
3805 					      "i", i));
3806     }
3807   }
3808 
3809 #elif (PY_VERSION_HEX < 0x03030000)
3810 
3811   Py_UNICODE* us = PyUnicode_AS_UNICODE(a_o);
3812   for (CORBA::ULong i=0; i != len; ++i) {
3813     if (us[i] == 0) {
3814       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
3815 			 omniPy::formatString("Embedded null in string "
3816 					      "at position %d",
3817 					      "i", i));
3818     }
3819   }
3820 
3821 #else
3822 
3823   int   kind = PyUnicode_KIND(a_o);
3824   void* data = PyUnicode_DATA(a_o);
3825 
3826   for (CORBA::ULong i=0; i != len; ++i) {
3827     Py_UCS4 uc = PyUnicode_READ(kind, data, i);
3828     if (uc == 0) {
3829       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
3830 			 omniPy::formatString("Embedded null in string "
3831 					      "at position %d",
3832 					      "i", i));
3833     }
3834   }
3835 #endif
3836 
3837   // After all that, we don't actually have to copy the string,
3838   // since they're immutable
3839   Py_INCREF(a_o);
3840   return a_o;
3841 }
3842 
3843 
3844 template<class G>
3845 inline PyObject*
copyOptSequenceItems(CORBA::ULong len,PyObject * a_o,CORBA::ULong etk,CORBA::CompletionStatus compstatus,const char * seq_arr,G getFn)3846 copyOptSequenceItems(CORBA::ULong            len,
3847                      PyObject*               a_o,
3848                      CORBA::ULong            etk,
3849                      CORBA::CompletionStatus compstatus,
3850                      const char*             seq_arr,
3851                      G                       getFn)
3852 {
3853   omniPy::PyRefHolder r_o(PyList_New(len));
3854 
3855   PyObject*        t_o;
3856   CORBA::ULong     i;
3857 
3858   long             long_val;
3859   unsigned long    ulong_val;
3860   double           double_val;
3861 #ifdef HAS_LongLong
3862   CORBA::LongLong  llong_val;
3863   CORBA::ULongLong ullong_val;
3864 #endif
3865 
3866   switch (etk) {
3867 
3868   case CORBA::tk_short:
3869 
3870     for (i=0; i<len; i++) {
3871       t_o = getFn(a_o, i);
3872 
3873 #if (PY_VERSION_HEX < 0x03000000)
3874       if (PyInt_Check(t_o)) {
3875         long_val = PyInt_AS_LONG(t_o);
3876         if (long_val >= -0x8000 && long_val <= 0x7fff) {
3877           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
3878         }
3879         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3880                            omniPy::formatString("%s item %d: "
3881                                                 "%s is out of range for "
3882                                                 "short", "siO",
3883                                                 seq_arr, i, t_o));
3884       }
3885       else
3886 #endif
3887       if (PyLong_Check(t_o)) {
3888         long_val = PyLong_AsLong(t_o);
3889         if (long_val == -1 && PyErr_Occurred()) {
3890           PyErr_Clear();
3891           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3892                              omniPy::formatString("%s item %d: "
3893                                                   "%s is out of range for "
3894                                                   "short", "siO",
3895                                                   seq_arr, i, t_o));
3896         }
3897         if (long_val >= -0x8000 && long_val <= 0x7fff) {
3898 #if (PY_VERSION_HEX < 0x03000000)
3899           PyList_SET_ITEM(r_o, i, PyInt_FromLong(long_val)); continue;
3900 #else
3901           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
3902 #endif
3903         }
3904         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3905                            omniPy::formatString("%s item %d: "
3906                                                 "%s is out of range for "
3907                                                 "short", "siO",
3908                                                 seq_arr, i, t_o));
3909       }
3910       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3911                          omniPy::formatString("%s item %d: "
3912                                               "expecting short, "
3913                                               "got %r", "siO",
3914                                               seq_arr, i, t_o->ob_type));
3915     }
3916     break;
3917 
3918   case CORBA::tk_long:
3919 
3920     for (i=0; i<len; i++) {
3921       t_o = getFn(a_o, i);
3922 
3923 #if (PY_VERSION_HEX < 0x03000000)
3924       if (PyInt_Check(t_o)) {
3925 #  if SIZEOF_LONG > 4
3926         long_val = PyInt_AS_LONG(t_o);
3927         if (long_val >= -0x80000000L && long_val <= 0x7fffffffL) {
3928 #  endif
3929           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
3930 #  if SIZEOF_LONG > 4
3931         }
3932         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3933                            omniPy::formatString("%s item %d: "
3934                                                 "%s is out of range for "
3935                                                 "long", "siO",
3936                                                 seq_arr, i, t_o));
3937 #  endif
3938       }
3939       else
3940 #endif
3941       if (PyLong_Check(t_o)) {
3942         long_val = PyLong_AsLong(t_o);
3943         if (long_val == -1 && PyErr_Occurred()) {
3944           PyErr_Clear();
3945           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3946                              omniPy::formatString("%s item %d: "
3947                                                   "%s is out of range for "
3948                                                   "long", "siO",
3949                                                   seq_arr, i, t_o));
3950         }
3951 #if SIZEOF_LONG > 4
3952         if (long_val >= -0x80000000L && long_val <= 0x7fffffffL) {
3953 #endif
3954 #if (PY_VERSION_HEX < 0x03000000)
3955           PyList_SET_ITEM(r_o, i, PyInt_FromLong(long_val)); continue;
3956 #else
3957           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
3958 #endif
3959 #if SIZEOF_LONG > 4
3960         }
3961         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3962                            omniPy::formatString("%s item %d: "
3963                                                 "%s is out of range for "
3964                                                 "long", "siO",
3965                                                 seq_arr, i, t_o));
3966 #endif
3967       }
3968       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
3969                          omniPy::formatString("%s item %d: "
3970                                               "expecting long, "
3971                                               "got %r", "siO",
3972                                               seq_arr, i, t_o->ob_type));
3973     }
3974     break;
3975 
3976   case CORBA::tk_ushort:
3977 
3978     for (i=0; i<len; i++) {
3979       t_o = getFn(a_o, i);
3980 
3981 #if (PY_VERSION_HEX < 0x03000000)
3982       if (PyInt_Check(t_o)) {
3983         long_val = PyInt_AS_LONG(t_o);
3984         if (long_val >= 0 && long_val <= 0xffff) {
3985           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
3986         }
3987         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
3988                            omniPy::formatString("%s item %d: "
3989                                                 "%s is out of range for "
3990                                                 "unsigned short", "siO",
3991                                                 seq_arr, i, t_o));
3992       }
3993       else
3994 #endif
3995       if (PyLong_Check(t_o)) {
3996         long_val = PyLong_AsLong(t_o);
3997         if (long_val == -1 && PyErr_Occurred()) {
3998           PyErr_Clear();
3999           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4000                              omniPy::formatString("%s item %d: "
4001                                                   "%s is out of range for "
4002                                                   "unsigned short", "siO",
4003                                                   seq_arr, i, t_o));
4004         }
4005         if (long_val >= 0 && long_val <= 0xffff) {
4006 #if (PY_VERSION_HEX < 0x03000000)
4007           PyList_SET_ITEM(r_o, i, PyInt_FromLong(long_val)); continue;
4008 #else
4009           Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
4010 #endif
4011         }
4012         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4013                            omniPy::formatString("%s item %d: "
4014                                                 "%s is out of range for "
4015                                                 "unsigned short", "siO",
4016                                                 seq_arr, i, t_o));
4017       }
4018       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4019                          omniPy::formatString("%s item %d: "
4020                                               "expecting unsigned short, "
4021                                               "got %r", "siO",
4022                                               seq_arr, i, t_o->ob_type));
4023     }
4024     break;
4025 
4026   case CORBA::tk_ulong:
4027 
4028     for (i=0; i<len; i++) {
4029       t_o = getFn(a_o, i);
4030 
4031       if (PyLong_Check(t_o)) {
4032         ulong_val = PyLong_AsUnsignedLong(t_o);
4033         if (ulong_val == (unsigned long)-1 && PyErr_Occurred()) {
4034           PyErr_Clear();
4035           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4036                              omniPy::formatString("%s item %d: "
4037                                                   "%s is out of range for "
4038                                                   "unsigned long", "siO",
4039                                                   seq_arr, i, t_o));
4040         }
4041 #if SIZEOF_LONG > 4
4042         if (ulong_val > 0xffffffffL) {
4043           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4044                              omniPy::formatString("%s item %d: "
4045                                                   "%s is out of range for "
4046                                                   "unsigned long", "siO",
4047                                                   seq_arr, i, t_o));
4048         }
4049 #endif
4050         Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
4051       }
4052 #if (PY_VERSION_HEX < 0x03000000)
4053       else if (PyInt_Check(t_o)) {
4054         long_val = PyInt_AS_LONG(t_o);
4055 #  if SIZEOF_LONG > 4
4056         if (long_val >= 0 && long_val <= 0xffffffffL) {
4057           PyList_SET_ITEM(r_o, i, PyLong_FromLong(long_val));
4058           continue;
4059         }
4060 #  else
4061         if (long_val >= 0) {
4062           PyList_SET_ITEM(r_o, i, PyLong_FromLong(long_val));
4063           continue;
4064         }
4065 #  endif
4066         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4067                            omniPy::formatString("%s item %d: "
4068                                                 "%s is out of range for "
4069                                                 "unsigned long", "siO",
4070                                                 seq_arr, i, t_o));
4071       }
4072 #endif
4073       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4074                          omniPy::formatString("%s item %d: "
4075                                               "expecting unsigned long, "
4076                                               "got %r", "siO",
4077                                               seq_arr, i, t_o->ob_type));
4078     }
4079     break;
4080 
4081   case CORBA::tk_float:
4082   case CORBA::tk_double:
4083 
4084     for (i=0; i<len; i++) {
4085       t_o = getFn(a_o, i);
4086 
4087       if (PyFloat_Check(t_o)) {
4088         Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o);
4089       }
4090 #if (PY_VERSION_HEX < 0x03000000)
4091       else if (PyInt_Check(t_o)) {
4092         PyList_SET_ITEM(r_o, i,
4093                         PyFloat_FromDouble((double)PyInt_AS_LONG(t_o)));
4094       }
4095 #endif
4096       else if (PyLong_Check(t_o)) {
4097         double_val = PyLong_AsDouble(t_o);
4098         if (double_val == -1.0 && PyErr_Occurred()) {
4099           PyErr_Clear();
4100           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4101                              omniPy::formatString("%s item %d: "
4102                                                   "%s is out of range for "
4103                                                   "double", "siO",
4104                                                   seq_arr, i, t_o));
4105         }
4106         PyList_SET_ITEM(r_o, i, PyFloat_FromDouble(double_val));
4107       }
4108       else {
4109         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4110                            omniPy::formatString("%s item %d: "
4111                                                 "expecting double, "
4112                                                 "got %r", "siO",
4113                                                 seq_arr, i, t_o->ob_type));
4114       }
4115     }
4116     break;
4117 
4118   case CORBA::tk_boolean:
4119 
4120     for (i=0; i<len; i++) {
4121       t_o = getFn(a_o, i);
4122 
4123       int b = PyObject_IsTrue(t_o);
4124       if (b == -1) {
4125         if (omniORB::trace(1))
4126           PyErr_Print();
4127         else
4128           PyErr_Clear();
4129 
4130         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4131                            omniPy::formatString("%s item %d: "
4132                                                 "expecting bool, "
4133                                                 "got %r", "siO",
4134                                                 seq_arr, i, t_o->ob_type));
4135       }
4136       t_o = b ? Py_True : Py_False;
4137       Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o);
4138     }
4139     break;
4140 
4141 #ifdef HAS_LongLong
4142 
4143   case CORBA::tk_longlong:
4144 
4145     for (i=0; i<len; i++) {
4146       t_o = getFn(a_o, i);
4147 
4148       if (PyLong_Check(t_o)) {
4149         llong_val = PyLong_AsLongLong(t_o);
4150         if (llong_val == -1 && PyErr_Occurred()) {
4151           PyErr_Clear();
4152           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4153                              omniPy::formatString("%s item %d: "
4154                                                   "%s is out of range for "
4155                                                   "long long", "siO",
4156                                                   seq_arr, i, t_o));
4157         }
4158         Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
4159       }
4160 #if (PY_VERSION_HEX < 0x03000000)
4161       else if (PyInt_Check(t_o)) {
4162         long_val = PyInt_AS_LONG(t_o);
4163         PyList_SET_ITEM(r_o, i, PyLong_FromLong(long_val));
4164       }
4165 #endif
4166       else {
4167         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4168                            omniPy::formatString("%s item %d: "
4169                                                 "expecting long long, "
4170                                                 "got %r", "siO",
4171                                                 seq_arr, i, t_o->ob_type));
4172       }
4173     }
4174     break;
4175 
4176   case CORBA::tk_ulonglong:
4177 
4178     for (i=0; i<len; i++) {
4179       t_o = getFn(a_o, i);
4180 
4181       if (PyLong_Check(t_o)) {
4182         ullong_val = PyLong_AsUnsignedLongLong(t_o);
4183         if (ullong_val == (CORBA::ULongLong)-1 && PyErr_Occurred()) {
4184           PyErr_Clear();
4185           THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4186                              omniPy::formatString("%s item %d: "
4187                                                   "%s is out of range for "
4188                                                   "unsigned long long", "siO",
4189                                                   seq_arr, i, t_o));
4190         }
4191         Py_INCREF(t_o); PyList_SET_ITEM(r_o, i, t_o); continue;
4192       }
4193 #if (PY_VERSION_HEX < 0x03000000)
4194       else if (PyInt_Check(t_o)) {
4195         long_val = PyInt_AS_LONG(t_o);
4196         if (long_val >= 0) {
4197           PyList_SET_ITEM(r_o, i, PyLong_FromLong(long_val));
4198           continue;
4199         }
4200         THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4201                            omniPy::formatString("%s item %d: "
4202                                                 "%s is out of range for "
4203                                                 "unsigned long long", "siO",
4204                                                 seq_arr, i, t_o));
4205       }
4206 #endif
4207       else {
4208         THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4209                            omniPy::formatString("%s item %d: "
4210                                                 "expecting unsigned "
4211                                                 "long long, got %r", "siO",
4212                                                 seq_arr, i, t_o->ob_type));
4213       }
4214     }
4215     break;
4216 #else
4217   case 23:
4218   case 24:
4219     {
4220       OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
4221     }
4222 #endif
4223   default:
4224     OMNIORB_ASSERT(0);
4225   }
4226   return r_o.retn();
4227 }
4228 
4229 
4230 static PyObject*
copyArgumentSequence(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4231 copyArgumentSequence(PyObject* d_o, PyObject* a_o,
4232 		     CORBA::CompletionStatus compstatus)
4233 { // element_desc, max_length
4234 
4235   PyObject*    t_o      = PyTuple_GET_ITEM(d_o, 2);
4236   OMNIORB_ASSERT(Int_Check(t_o));
4237   CORBA::ULong max_len  = Int_AS_LONG(t_o);
4238   PyObject*    elm_desc = PyTuple_GET_ITEM(d_o, 1);
4239 
4240   CORBA::ULong len, i;
4241   CORBA::ULong etk;
4242 
4243   if (sequenceOptimisedType(elm_desc, etk)) { // Simple type
4244 
4245     if (etk == CORBA::tk_octet) {
4246       // Mapping says octet and char use a string
4247       if (!RawString_Check(a_o)) {
4248 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4249 			   omniPy::formatString("Expecting bytes, got %r",
4250 						"O", a_o->ob_type));
4251       }
4252       len = RawString_GET_SIZE(a_o);
4253       if (max_len > 0 && len > max_len)
4254 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4255 
4256       Py_INCREF(a_o);
4257       return a_o;
4258     }
4259     else if (etk == CORBA::tk_char) {
4260       // Mapping says octet and char use a string
4261       if (!String_Check(a_o)) {
4262 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4263 			   omniPy::formatString("Expecting string, got %r",
4264 						"O", a_o->ob_type));
4265       }
4266       len = String_GET_SIZE(a_o);
4267       if (max_len > 0 && len > max_len)
4268 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4269 
4270       Py_INCREF(a_o);
4271       return a_o;
4272     }
4273     else if (PyList_Check(a_o)) {
4274       len = PyList_GET_SIZE(a_o);
4275       if (max_len > 0 && len > max_len)
4276 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4277 
4278       return copyOptSequenceItems(len, a_o, etk, compstatus,
4279                                   "Sequence", listGet);
4280     }
4281     else if (PyTuple_Check(a_o)) {
4282       len = PyTuple_GET_SIZE(a_o);
4283       if (max_len > 0 && len > max_len)
4284 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4285 
4286       return copyOptSequenceItems(len, a_o, etk, compstatus,
4287                                   "Sequence", tupleGet);
4288     }
4289     else {
4290       // Not a list or a tuple
4291       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4292 			 omniPy::formatString("Expecting sequence, got %r",
4293 					      "O", a_o->ob_type));
4294     }
4295   }
4296   else {
4297     // Complex type
4298 
4299     if (PyList_Check(a_o)) {
4300       len = PyList_GET_SIZE(a_o);
4301       if (max_len > 0 && len > max_len)
4302 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4303 
4304       omniPy::PyRefHolder r_o(PyList_New(len));
4305 
4306       for (i=0; i < len; i++) {
4307 	try {
4308 	  t_o = omniPy::copyArgument(elm_desc, PyList_GET_ITEM(a_o, i),
4309 				     compstatus);
4310 	}
4311 	catch (Py_BAD_PARAM& bp) {
4312 	  bp.add(omniPy::formatString("Sequence item %d", "i", i));
4313 	  throw;
4314 	}
4315 	PyList_SET_ITEM(r_o, i, t_o);
4316       }
4317       return r_o.retn();
4318     }
4319     else if (PyTuple_Check(a_o)) {
4320       len = PyTuple_GET_SIZE(a_o);
4321       if (max_len > 0 && len > max_len)
4322 	OMNIORB_THROW(MARSHAL, MARSHAL_SequenceIsTooLong, compstatus);
4323 
4324       omniPy::PyRefHolder r_o(PyList_New(len));
4325 
4326       for (i=0; i < len; i++) {
4327 	try {
4328 	  t_o = omniPy::copyArgument(elm_desc, PyTuple_GET_ITEM(a_o, i),
4329 				     compstatus);
4330 	}
4331 	catch (Py_BAD_PARAM& bp) {
4332 	  bp.add(omniPy::formatString("Sequence item %d", "i", i));
4333 	  throw;
4334 	}
4335 	PyList_SET_ITEM(r_o, i, t_o);
4336       }
4337       return r_o.retn();
4338     }
4339     else {
4340       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4341 			 omniPy::formatString("Expecting sequence, got %r",
4342 					      "O", a_o->ob_type));
4343     }
4344   }
4345   return 0;
4346 }
4347 
4348 static PyObject*
copyArgumentArray(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4349 copyArgumentArray(PyObject* d_o, PyObject* a_o,
4350 		  CORBA::CompletionStatus compstatus)
4351 { // element_desc, length
4352 
4353   PyObject*    t_o      = PyTuple_GET_ITEM(d_o, 2);
4354   OMNIORB_ASSERT(Int_Check(t_o));
4355   CORBA::ULong arr_len  = Int_AS_LONG(t_o);
4356   PyObject*    elm_desc = PyTuple_GET_ITEM(d_o, 1);
4357 
4358   CORBA::ULong len, i;
4359   CORBA::ULong etk;
4360 
4361   if (sequenceOptimisedType(elm_desc, etk)) { // Simple type
4362 
4363     if (etk == CORBA::tk_octet) {
4364       // Mapping says octet and char use a string
4365       if (!RawString_Check(a_o)) {
4366 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4367 			   omniPy::formatString("Expecting bytes, got %r",
4368 						"O", a_o->ob_type));
4369       }
4370 
4371       len = RawString_GET_SIZE(a_o);
4372       if (len != arr_len) {
4373 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4374 			   omniPy::formatString("Expecting bytes length %d, "
4375 						"got %d",
4376 						"ii", arr_len, len));
4377       }
4378       Py_INCREF(a_o);
4379       return a_o;
4380     }
4381     else if (etk == CORBA::tk_char) {
4382       // Mapping says octet and char use a string
4383       if (!String_Check(a_o)) {
4384 	THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4385 			   omniPy::formatString("Expecting string, got %r",
4386 						"O", a_o->ob_type));
4387       }
4388 
4389       len = String_GET_SIZE(a_o);
4390       if (len != arr_len) {
4391 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4392 			   omniPy::formatString("Expecting string length %d, "
4393 						"got %d",
4394 						"ii", arr_len, len));
4395       }
4396       Py_INCREF(a_o);
4397       return a_o;
4398     }
4399     else if (PyList_Check(a_o)) {
4400       len = PyList_GET_SIZE(a_o);
4401       if (len != arr_len)
4402 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4403 			   omniPy::formatString("Expecting array length %d, "
4404 						"got %d",
4405 						"ii", arr_len, len));
4406 
4407 
4408       return copyOptSequenceItems(len, a_o, etk, compstatus,
4409                                   "Array", listGet);
4410     }
4411     else if (PyTuple_Check(a_o)) {
4412       len = PyTuple_GET_SIZE(a_o);
4413       if (len != arr_len)
4414 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4415 			   omniPy::formatString("Expecting array length %d, "
4416 						"got %d",
4417 						"ii", arr_len, len));
4418 
4419       return copyOptSequenceItems(len, a_o, etk, compstatus,
4420                                   "Array", tupleGet);
4421 
4422     }
4423     else {
4424       // Not a list or a tuple
4425       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4426 			 omniPy::formatString("Expecting array, got %r",
4427 					      "O", a_o->ob_type));
4428     }
4429   }
4430   else {
4431     // Complex type
4432 
4433     if (PyList_Check(a_o)) {
4434       len = PyList_GET_SIZE(a_o);
4435       if (len != arr_len) {
4436 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4437 			   omniPy::formatString("Expecting array length %d, "
4438 						"got %d",
4439 						"ii", arr_len, len));
4440       }
4441 
4442       omniPy::PyRefHolder r_o(PyList_New(len));
4443 
4444       for (i=0; i < len; i++) {
4445 	try {
4446 	  t_o = omniPy::copyArgument(elm_desc, PyList_GET_ITEM(a_o, i),
4447 				     compstatus);
4448 	}
4449 	catch (Py_BAD_PARAM& bp) {
4450 	  bp.add(omniPy::formatString("Array item %d", "i", i));
4451 	  throw;
4452 	}
4453 	PyList_SET_ITEM(r_o, i, t_o);
4454       }
4455       return r_o.retn();
4456     }
4457     else if (PyTuple_Check(a_o)) {
4458       len = PyTuple_GET_SIZE(a_o);
4459       if (len != arr_len) {
4460 	THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4461 			   omniPy::formatString("Expecting array length %d, "
4462 						"got %d",
4463 						"ii", arr_len, len));
4464       }
4465 
4466       omniPy::PyRefHolder r_o(PyList_New(len));
4467 
4468       for (i=0; i < len; i++) {
4469 	try {
4470 	  t_o = omniPy::copyArgument(elm_desc, PyTuple_GET_ITEM(a_o, i),
4471 				     compstatus);
4472 	}
4473 	catch (Py_BAD_PARAM& bp) {
4474 	  bp.add(omniPy::formatString("Array item %d", "i", i));
4475 	  throw;
4476 	}
4477 	PyList_SET_ITEM(r_o, i, t_o);
4478       }
4479       return r_o.retn();
4480     }
4481     else {
4482       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4483 			 omniPy::formatString("Expecting array, got %r",
4484 					      "O", a_o->ob_type));
4485     }
4486   }
4487   return 0;
4488 }
4489 
4490 static PyObject*
copyArgumentAlias(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4491 copyArgumentAlias(PyObject* d_o, PyObject* a_o,
4492 		  CORBA::CompletionStatus compstatus)
4493 { // repoId, name, descr
4494 
4495   return omniPy::copyArgument(PyTuple_GET_ITEM(d_o, 3), a_o, compstatus);
4496 }
4497 
4498 static PyObject*
copyArgumentExcept(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4499 copyArgumentExcept(PyObject* d_o, PyObject* a_o,
4500 		   CORBA::CompletionStatus compstatus)
4501 { // class, repoId, exc name, name, descriptor, ...
4502 
4503   // As with structs, the descriptor tuple has twice the number of
4504   // members plus 4.
4505   int cnt = (PyTuple_GET_SIZE(d_o) - 4) / 2;
4506 
4507   PyObject* t_o;
4508   PyObject* name;
4509   omniPy::PyRefHolder value;
4510   omniPy::PyRefHolder argtuple(PyTuple_New(cnt));
4511 
4512   int i, j;
4513 
4514   for (i=0,j=4; i < cnt; i++,j++) {
4515     name = PyTuple_GET_ITEM(d_o, j++); OMNIORB_ASSERT(String_Check(name));
4516     value = PyObject_GetAttr(a_o, name);
4517 
4518     if (value.valid()) {
4519       try {
4520 	t_o = omniPy::copyArgument(PyTuple_GET_ITEM(d_o, j),
4521 				   value, compstatus);
4522       }
4523       catch (Py_BAD_PARAM& bp) {
4524 	bp.add(omniPy::formatString("Exception %r member %r", "OO",
4525 				    PyTuple_GET_ITEM(d_o, 3), name));
4526 	throw;
4527       }
4528       PyTuple_SET_ITEM(argtuple, i, t_o);
4529     }
4530     else {
4531       PyErr_Clear();
4532       THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4533 			 omniPy::formatString("Exception %r instance %r "
4534 					      "has no %r member",
4535 					      "OOO",
4536 					      PyTuple_GET_ITEM(d_o, 3),
4537 					      a_o->ob_type,
4538 					      name));
4539     }
4540   }
4541   return PyObject_CallObject(PyTuple_GET_ITEM(d_o, 1), argtuple);
4542 }
4543 
4544 
4545 static PyObject*
copyArgumentLongLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4546 copyArgumentLongLong(PyObject* d_o, PyObject* a_o,
4547 		     CORBA::CompletionStatus compstatus)
4548 {
4549 #ifdef HAS_LongLong
4550   if (PyLong_Check(a_o)) {
4551     CORBA::LongLong ll = PyLong_AsLongLong(a_o);
4552     if (ll == -1 && PyErr_Occurred()) {
4553       PyErr_Clear();
4554       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4555 			 omniPy::formatString("%s is out of range for "
4556 					      "long long",
4557 					      "O", a_o));
4558     }
4559     Py_INCREF(a_o); return a_o;
4560   }
4561 #if (PY_VERSION_HEX < 0x03000000)
4562   else if (PyInt_Check(a_o)) {
4563     long l = PyInt_AS_LONG(a_o);
4564     return PyLong_FromLong(l);
4565   }
4566 #endif
4567   else {
4568     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4569 		       omniPy::formatString("Expecting long long, got %r",
4570 					    "O", a_o->ob_type));
4571   }
4572 #else
4573   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
4574 #endif
4575   return 0;
4576 }
4577 
4578 
4579 static PyObject*
copyArgumentULongLong(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4580 copyArgumentULongLong(PyObject* d_o, PyObject* a_o,
4581 		      CORBA::CompletionStatus compstatus)
4582 {
4583 #ifdef HAS_LongLong
4584   if (PyLong_Check(a_o)) {
4585     CORBA::ULongLong ll = PyLong_AsUnsignedLongLong(a_o);
4586     if (ll == (CORBA::ULongLong)-1 && PyErr_Occurred()) {
4587       PyErr_Clear();
4588       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4589 			 omniPy::formatString("%s is out of range for "
4590 					      "unsigned long long",
4591 					      "O", a_o));
4592     }
4593     Py_INCREF(a_o); return a_o;
4594   }
4595 #if (PY_VERSION_HEX < 0x03000000)
4596   else if (PyInt_Check(a_o)) {
4597     long l = PyInt_AS_LONG(a_o);
4598     if (l < 0) {
4599       THROW_PY_BAD_PARAM(BAD_PARAM_PythonValueOutOfRange, compstatus,
4600 			 omniPy::formatString("%s is out of range for "
4601 					      "unsigned long long",
4602 					      "O", a_o));
4603     }
4604     return PyLong_FromLong(l);
4605   }
4606 #endif
4607   else {
4608     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4609 		       omniPy::formatString("Expecting long long, got %r",
4610 					    "O", a_o->ob_type));
4611   }
4612 #else
4613   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
4614 #endif
4615   return 0;
4616 }
4617 
4618 static PyObject*
copyArgumentLongDouble(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4619 copyArgumentLongDouble(PyObject* d_o, PyObject* a_o,
4620 		       CORBA::CompletionStatus compstatus)
4621 {
4622   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
4623   return 0;
4624 }
4625 
4626 static PyObject*
copyArgumentWChar(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4627 copyArgumentWChar(PyObject* d_o, PyObject* a_o,
4628 		  CORBA::CompletionStatus compstatus)
4629 {
4630   if (!PyUnicode_Check(a_o)) {
4631     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4632 		       omniPy::formatString("Expecting unicode, got %r",
4633 					    "O", a_o->ob_type));
4634   }
4635   if (PyUnicode_GET_SIZE(a_o) != 1) {
4636     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4637 		       omniPy::formatString("Expecting unicode of length 1, "
4638 					    "got %r",
4639 					    "O", a_o));
4640   }
4641   Py_INCREF(a_o); return a_o;
4642 }
4643 
4644 
4645 static PyObject*
copyArgumentWString(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4646 copyArgumentWString(PyObject* d_o, PyObject* a_o,
4647 		    CORBA::CompletionStatus compstatus)
4648 { // max_length
4649 
4650   PyObject* t_o = PyTuple_GET_ITEM(d_o, 1);
4651   OMNIORB_ASSERT(Int_Check(t_o));
4652 
4653   CORBA::ULong max_len = Int_AS_LONG(t_o);
4654 
4655   if (!PyUnicode_Check(a_o)) {
4656     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4657 		       omniPy::formatString("Expecting unicode, got %r",
4658 					    "O", a_o->ob_type));
4659   }
4660 
4661 #if (PY_VERSION_HEX < 0x03030000) // Earlier than Python 3.3
4662 
4663   CORBA::ULong len = PyUnicode_GET_SIZE(a_o);
4664 
4665   if (max_len > 0 && len > max_len)
4666     OMNIORB_THROW(MARSHAL, MARSHAL_WStringIsTooLong, compstatus);
4667 
4668   // Check for nulls
4669   Py_UNICODE* str = PyUnicode_AS_UNICODE(a_o);
4670   for (CORBA::ULong i=0; i<len; i++) {
4671     if (str[i] == 0) {
4672       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
4673 			 omniPy::formatString("Embedded null in unicode "
4674 					      "at position %d",
4675 					      "i", i));
4676     }
4677   }
4678 
4679 #else // New Unicode API
4680 
4681   CORBA::ULong len = PyUnicode_GET_LENGTH(a_o);
4682 
4683   if (max_len > 0 && len > max_len)
4684     OMNIORB_THROW(MARSHAL, MARSHAL_WStringIsTooLong, compstatus);
4685 
4686   // Check for nulls
4687   int   kind = PyUnicode_KIND(a_o);
4688   void* data = PyUnicode_DATA(a_o);
4689 
4690   for (CORBA::ULong i=0; i<len; i++) {
4691     if (PyUnicode_READ(kind, data, i) == 0) {
4692       THROW_PY_BAD_PARAM(BAD_PARAM_EmbeddedNullInPythonString, compstatus,
4693 			 omniPy::formatString("Embedded null in unicode "
4694 					      "at position %d", "i", i));
4695     }
4696   }
4697 #endif
4698 
4699   // After all that, we don't actually have to copy the string,
4700   // since they're immutable
4701   Py_INCREF(a_o);
4702   return a_o;
4703 }
4704 
4705 
4706 static PyObject*
copyArgumentFixed(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4707 copyArgumentFixed(PyObject* d_o, PyObject* a_o,
4708 		  CORBA::CompletionStatus compstatus)
4709 {
4710   if (!omnipyFixed_Check(a_o)) {
4711     THROW_PY_BAD_PARAM(BAD_PARAM_WrongPythonType, compstatus,
4712 		       omniPy::formatString("Expecting fixed, got %r",
4713 					    "O", a_o->ob_type));
4714   }
4715 
4716   PyObject* t_o;
4717 
4718   t_o = PyTuple_GET_ITEM(d_o, 1); int dlimit = Int_AS_LONG(t_o);
4719   t_o = PyTuple_GET_ITEM(d_o, 2); int slimit = Int_AS_LONG(t_o);
4720 
4721   CORBA::Fixed f(*((omnipyFixedObject*)a_o)->ob_fixed);
4722   f.PR_setLimits(dlimit, slimit);
4723   return omniPy::newFixedObject(f);
4724 }
4725 
4726 
4727 static PyObject*
copyArgumentNative(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4728 copyArgumentNative(PyObject* d_o, PyObject* a_o,
4729 		   CORBA::CompletionStatus compstatus)
4730 {
4731   OMNIORB_THROW(NO_IMPLEMENT, NO_IMPLEMENT_Unsupported, compstatus);
4732   return 0;
4733 }
4734 
4735 
4736 // copyArgumentAbstractInterface is in pyAbstractIntf.cc
4737 
4738 static PyObject*
copyArgumentLocalInterface(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4739 copyArgumentLocalInterface(PyObject* d_o, PyObject* a_o,
4740 			   CORBA::CompletionStatus compstatus)
4741 {
4742   Py_INCREF(a_o);
4743   return a_o;
4744 }
4745 
4746 PyObject*
4747 omniPy::
copyArgumentIndirect(PyObject * d_o,PyObject * a_o,CORBA::CompletionStatus compstatus)4748 copyArgumentIndirect(PyObject* d_o, PyObject* a_o,
4749 		     CORBA::CompletionStatus compstatus)
4750 {
4751   PyObject* l = PyTuple_GET_ITEM(d_o, 1); OMNIORB_ASSERT(PyList_Check(l));
4752   PyObject* d = PyList_GET_ITEM(l, 0);
4753 
4754   if (String_Check(d)) {
4755     // Indirection to a repoId -- find the corresponding descriptor
4756     d = PyDict_GetItem(pyomniORBtypeMap, d);
4757     if (!d) OMNIORB_THROW(BAD_PARAM,
4758 			  BAD_PARAM_IncompletePythonType,
4759 			  compstatus);
4760 
4761     Py_INCREF(d);
4762     PyList_SetItem(l, 0, d);
4763   }
4764   return copyArgument(d, a_o, compstatus);
4765 }
4766 
4767 
4768 const omniPy::CopyArgumentFn omniPy::copyArgumentFns[] = {
4769   copyArgumentNull,
4770   copyArgumentVoid,
4771   copyArgumentShort,
4772   copyArgumentLong,
4773   copyArgumentUShort,
4774   copyArgumentULong,
4775   copyArgumentFloat,
4776   copyArgumentDouble,
4777   copyArgumentBoolean,
4778   copyArgumentChar,
4779   copyArgumentOctet,
4780   copyArgumentAny,
4781   copyArgumentTypeCode,
4782   copyArgumentPrincipal,
4783   copyArgumentObjref,
4784   copyArgumentStruct,
4785   copyArgumentUnion,
4786   copyArgumentEnum,
4787   copyArgumentString,
4788   copyArgumentSequence,
4789   copyArgumentArray,
4790   copyArgumentAlias,
4791   copyArgumentExcept,
4792   copyArgumentLongLong,
4793   copyArgumentULongLong,
4794   copyArgumentLongDouble,
4795   copyArgumentWChar,
4796   copyArgumentWString,
4797   copyArgumentFixed,
4798   omniPy::copyArgumentValue,
4799   omniPy::copyArgumentValueBox,
4800   copyArgumentNative,
4801   omniPy::copyArgumentAbstractInterface,
4802   copyArgumentLocalInterface
4803 };
4804 
4805 
4806 
4807 //
4808 // PyUnlockingCdrStream
4809 //
4810 
4811 void
4812 omniPy::
put_octet_array(const _CORBA_Octet * b,int size,omni::alignment_t align)4813 PyUnlockingCdrStream::put_octet_array(const _CORBA_Octet* b, int size,
4814 				      omni::alignment_t align)
4815 {
4816   omniPy::InterpreterUnlocker _u;
4817   cdrStreamAdapter::put_octet_array(b, size, align);
4818 }
4819 
4820 void
4821 omniPy::
get_octet_array(_CORBA_Octet * b,int size,omni::alignment_t align)4822 PyUnlockingCdrStream::get_octet_array(_CORBA_Octet* b,int size,
4823 				      omni::alignment_t align)
4824 {
4825   omniPy::InterpreterUnlocker _u;
4826   cdrStreamAdapter::get_octet_array(b, size, align);
4827 }
4828 
4829 void
4830 omniPy::
skipInput(_CORBA_ULong size)4831 PyUnlockingCdrStream::skipInput(_CORBA_ULong size)
4832 {
4833   omniPy::InterpreterUnlocker _u;
4834   cdrStreamAdapter::skipInput(size);
4835 }
4836 
4837 void
4838 omniPy::
copy_to(cdrStream & stream,int size,omni::alignment_t align)4839 PyUnlockingCdrStream::copy_to(cdrStream& stream, int size,
4840 			      omni::alignment_t align)
4841 {
4842   omniPy::InterpreterUnlocker _u;
4843   cdrStreamAdapter::copy_to(stream, size, align);
4844 }
4845 
4846 void
4847 omniPy::
fetchInputData(omni::alignment_t align,size_t required)4848 PyUnlockingCdrStream::fetchInputData(omni::alignment_t align, size_t required)
4849 {
4850   omniPy::InterpreterUnlocker _u;
4851   cdrStreamAdapter::fetchInputData(align, required);
4852 }
4853 
4854 _CORBA_Boolean
4855 omniPy::
4856 PyUnlockingCdrStream::
reserveOutputSpaceForPrimitiveType(omni::alignment_t align,size_t required)4857 reserveOutputSpaceForPrimitiveType(omni::alignment_t align, size_t required)
4858 {
4859   omniPy::InterpreterUnlocker _u;
4860   return cdrStreamAdapter::reserveOutputSpaceForPrimitiveType(align, required);
4861 }
4862 
4863 _CORBA_Boolean
4864 omniPy::
4865 PyUnlockingCdrStream::
maybeReserveOutputSpace(omni::alignment_t align,size_t required)4866 maybeReserveOutputSpace(omni::alignment_t align, size_t required)
4867 {
4868   omniPy::InterpreterUnlocker _u;
4869   return cdrStreamAdapter::maybeReserveOutputSpace(align, required);
4870 }
4871