home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / fns101.zip / Add-Ons / Fnorb / src / cdrmodule.c < prev    next >
C/C++ Source or Header  |  1999-06-28  |  19KB  |  713 lines

  1. /***************************************************************
  2.  
  3.   Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1997, 1998, 1999
  4.   Unpublished work.  All Rights Reserved.
  5.  
  6.   The software contained on this media is the property of the
  7.   DSTC Pty Ltd.  Use of this software is strictly in accordance
  8.   with the license agreement in the accompanying LICENSE.HTML
  9.   file.  If your distribution of this software does not contain
  10.   a LICENSE.HTML file then you have no rights to use this
  11.   software in any manner and should contact DSTC at the address
  12.   below to determine an appropriate licensing arrangement.
  13.  
  14.      DSTC Pty Ltd
  15.      Level 7, Gehrmann Labs
  16.      University of Queensland
  17.      St Lucia, 4072
  18.      Australia
  19.      Tel: +61 7 3365 4310
  20.      Fax: +61 7 3365 4311
  21.      Email: enquiries@dstc.edu.au
  22.  
  23.   This software is being provided "AS IS" without warranty of
  24.   any kind.  In no event shall DSTC Pty Ltd be liable for
  25.   damage of any kind arising out of or in connection with
  26.   the use or performance of this software.
  27.  
  28.  
  29.   Project:      Fnorb
  30.   File:         $Source: /units/arch/src/Fnorb-1.0/src/RCS/cdrmodule.c,v $
  31.   Version:      @(#)$RCSfile: cdrmodule.c,v $ $Revision: 1.12 $
  32.  
  33.  
  34.   Description:    Python interface to CORBA CDR marshalling/unmarshalling
  35.                 functions.
  36.  
  37. ****************************************************************/
  38.  
  39. #if !defined(lint)
  40. static const char rcsid[] = "@(#)$RCSfile: cdrmodule.c,v $ $Revision: 1.12 $";
  41. #endif
  42.  
  43. /*
  44.  * Standard library includes (e.g., stdio)
  45.  */
  46.  
  47. /*
  48.  * Application library includes (e.g., X, DCE)
  49.  */
  50. #include "Python.h"                /* Python API        */
  51.  
  52. /*
  53.  * DSTC library includes (e.g., dstc_stdlib.h)
  54.  */
  55.  
  56. /*
  57.  * Project library includes              
  58.  */
  59. #include "fnorb.h"
  60. #include "cdr.h"
  61.  
  62. /*
  63.  * Local file includes
  64.  */
  65.  
  66. /*
  67.  * CDR error object.
  68.  */
  69. #define CDR_ERROR        "error"
  70. #define CDR_ERROR_STRING    "cdr.error"
  71.  
  72. static PyObject* CDRError;
  73.  
  74. /*
  75.  * Version.
  76.  */
  77. #define CDR_VERSION "1.1"
  78.  
  79. /*
  80.  * Raise a CDR error (return NULL for convenience).
  81.  */
  82. static PyObject*
  83. cdr_error(char* message, int status)
  84. {
  85.     PyObject* error_value;
  86.     
  87.     /*
  88.      * Initialise the error value.
  89.      */
  90.     error_value = Py_BuildValue("zi", message, (long) status);    
  91.     if (error_value != NULL)
  92.     {
  93.     PyErr_SetObject(CDRError, error_value);
  94.     Py_DECREF(error_value);
  95.     }
  96.  
  97.     return NULL;
  98. }
  99.  
  100. static PyObject*
  101. cdr_version(PyObject* self, PyObject* args)
  102. {
  103.     /* Return the version of this module! */
  104.     return PyString_FromString(CDR_VERSION);
  105. }
  106.  
  107. static PyObject*
  108. cdr_host_byte_order(PyObject* self, PyObject* args)
  109. {
  110.     /* The return value is 0 if the host byte order is BIG endian, 1 if the
  111.      * host byte order is LITTLE endian.
  112.      */
  113.     return PyInt_FromLong((long) HOST_BYTE_ORDER);
  114. }
  115.  
  116. static PyObject*
  117. cdr_octet_to_ASCII(PyObject* self, PyObject* args)
  118. {
  119.     PyObject* py_octet;
  120.     CORBA_octet* octet;
  121.     CORBA_unsigned_long len_octet;
  122.  
  123.     PyObject* py_ascii;
  124.     char* ascii;
  125.  
  126.     CORBA_unsigned_long i;
  127.     char s[3];
  128.  
  129.     /* Parse the arguments. */
  130.     if (!PyArg_ParseTuple(args, "O!", &PyString_Type, &py_octet)) {
  131.     return NULL;
  132.     }
  133.  
  134.     /* Get the size of the octet stream. */
  135.     len_octet = PyString_Size(py_octet);
  136.  
  137.     /* Each octet is represented as two ASCII characters, so (not surprisingly)
  138.      * we create a string that is twice the size of the octet stream.
  139.      */
  140.     py_ascii = PyString_FromStringAndSize((char*) NULL, len_octet * 2);
  141.  
  142.     /* Get to the 'innards' of the octet and ASCII Python string objects. */
  143.     octet = (CORBA_octet*) PyString_AsString(py_octet);
  144.     ascii = PyString_AsString(py_ascii);
  145.  
  146.     /* Do the translation! */
  147.     for(i = 0; i < len_octet; i++, octet++)
  148.     {
  149.     sprintf(s, "%02X", *octet);
  150.     strcpy(&ascii[i * 2], s);
  151.     }
  152.  
  153.     return py_ascii;
  154. }
  155.  
  156. static PyObject*
  157. cdr_ASCII_to_octet(PyObject* self, PyObject* args)
  158. {
  159.     PyObject* py_ascii;
  160.     char* ascii;
  161.     CORBA_unsigned_long len_ascii;
  162.  
  163.     PyObject* py_octet;
  164.     CORBA_octet* octet;
  165.  
  166.     CORBA_unsigned_long i;
  167.     CORBA_long val;
  168.     char hex[3];
  169.     hex[2] = '\0';
  170.  
  171.     /* Parse the arguments. */
  172.     if (!PyArg_ParseTuple(args, "O!", &PyString_Type, &py_ascii)) {
  173.     return NULL;
  174.     }
  175.  
  176.     /* Get the size of the ASCII string. */
  177.     len_ascii = PyString_Size(py_ascii);
  178.  
  179.     /* Make sure that there are an even number of ASCII characters! */
  180.     if (len_ascii % 2 != 0) {
  181.     return cdr_error("Odd length ASCII string", len_ascii);
  182.     }
  183.  
  184.     /* Every two ASCII characters becomes a single octet, so (again, not
  185.      * surprisingly) we create a string that is half the size of the ASCII
  186.      * string.
  187.      */
  188.     py_octet = PyString_FromStringAndSize((char*) NULL, len_ascii / 2);
  189.  
  190.     /* Get to the 'innards' of the ASCII and octet Python string objects. */
  191.     ascii = PyString_AsString(py_ascii);
  192.     octet = (CORBA_octet*) PyString_AsString(py_octet);
  193.  
  194.     for(i = 0; i < len_ascii / 2; i++)
  195.     {
  196.     hex[0] = *ascii++;
  197.     hex[1] = *ascii++;
  198.     sscanf(hex, "%x", &val);
  199.     octet[i] = val;
  200.     }
  201.  
  202.     return py_octet;
  203. }
  204.  
  205. static PyObject*
  206. cdr_count(PyObject* self, PyObject* args)
  207. {
  208.     /* Arguments. */
  209.     char format;
  210.     PyObject* octet_string;
  211.     unsigned long offset;
  212.     PyObject* value;
  213.     CORBA_boolean byte_order;
  214.  
  215.     /* The return value is the new offset after 'marshalling' the data. */
  216.     PyObject* result;
  217.  
  218.     /* Stuff to get the job done! */
  219.     CORBA_octet* os;
  220.     CORBA_octet* p;
  221.  
  222.     CORBA_boolean boolean_val;
  223.     CORBA_octet octet_val;
  224.     CORBA_unsigned_short ushort_val;
  225.     CORBA_short short_val;
  226.     CORBA_unsigned_long ulong_val;
  227.     CORBA_long long_val;
  228.     CORBA_unsigned_longlong ulonglong_val;
  229.     CORBA_longlong longlong_val;
  230.     CORBA_float float_val;
  231.     CORBA_double double_val;
  232.     CORBA_char* string_val;
  233.     CORBA_octet* octets_val;
  234.     CORBA_unsigned_long len;
  235.     
  236.     /* Parse the arguments. */
  237.     if (!PyArg_ParseTuple(args, "cO!lbO", &format, &PyString_Type,
  238.               &octet_string, (long*) &offset, &byte_order, &value))
  239.     {
  240.     return NULL;
  241.     }
  242.  
  243.     /* Get a pointer to the data of the Python string. */
  244.     os = (CORBA_octet*) PyString_AsString(octet_string);
  245.     p = &os[offset];
  246.  
  247.     switch(format) {
  248.  
  249.     case 'b':
  250.     /* boolean */
  251.     boolean_val = (CORBA_boolean) PyInt_AsLong(value);
  252.     (void) cdr_count_boolean(os, &p, byte_order, boolean_val);
  253.     result = Py_BuildValue ("l", p - os);
  254.      break;
  255.  
  256.     case 'c':
  257.     /* char */
  258.     string_val = (CORBA_char*) PyString_AsString(value);
  259.     (void) cdr_count_char(os, &p, byte_order, (CORBA_char) string_val[0]);
  260.     result = Py_BuildValue ("l", p - os);
  261.     break;
  262.  
  263.     case 'o':
  264.     /* octet */
  265.     octet_val = (CORBA_octet) PyInt_AsLong(value);
  266.     (void) cdr_count_octet(os, &p, byte_order, octet_val);
  267.     result = Py_BuildValue ("l", p - os);
  268.     break;
  269.  
  270.     case 'h':
  271.     /* short */
  272.     short_val = (CORBA_short) PyInt_AsLong(value);
  273.     (void) cdr_count_short(os, &p, byte_order, short_val);
  274.     result = Py_BuildValue ("l", p - os);
  275.     break;
  276.  
  277.     case 'H':
  278.     /* unsigned short */
  279.     ushort_val = (CORBA_unsigned_short) PyInt_AsLong(value);
  280.     (void) cdr_count_unsigned_short(os,&p, byte_order, ushort_val);
  281.     result = Py_BuildValue ("l", p - os);
  282.     break;
  283.  
  284.     case 'l':
  285.     /* long */
  286.     long_val = (CORBA_long) PyInt_AsLong(value);
  287.     (void) cdr_count_long(os, &p, byte_order, long_val);
  288.     result = Py_BuildValue ("l", p - os);
  289.     break;
  290.  
  291.     case 'L':
  292.     /* unsigned long */
  293.     if PyInt_Check(value) {
  294.       ulong_val = (CORBA_unsigned_long) PyInt_AsLong(value);
  295.     }
  296.     else {
  297.       ulong_val = (CORBA_unsigned_long) PyLong_AsUnsignedLong(value);
  298.         }
  299.     (void) cdr_count_unsigned_long(os, &p, byte_order, ulong_val);
  300.     result = Py_BuildValue ("l", p - os);
  301.     break;
  302.  
  303.     case 'n':
  304.     /* long long */
  305.     (void) cdr_count_longlong(os, &p, byte_order, longlong_val);
  306.     result = Py_BuildValue ("l", p - os);
  307.     break;
  308.  
  309.     case 'N':
  310.     /* unsigned long long */
  311.     (void) cdr_count_unsigned_longlong(os, &p, byte_order, ulonglong_val);
  312.     result = Py_BuildValue ("l", p - os);
  313.     break;
  314.  
  315.     case 'f':
  316.     /* float */
  317.     float_val = (CORBA_float) PyFloat_AsDouble(value);
  318.     (void) cdr_count_float(os, &p, byte_order, float_val);
  319.     result = Py_BuildValue ("l", p - os);
  320.     break;
  321.  
  322.     case 'd':
  323.     /* double */
  324.     double_val = (CORBA_double) PyFloat_AsDouble(value);
  325.     (void) cdr_count_double(os, &p, byte_order, double_val);
  326.     result = Py_BuildValue ("l", p - os);
  327.     break;
  328.  
  329.     case 's':
  330.     /* string */
  331.     string_val = (CORBA_char*) PyString_AsString(value);
  332.     (void) cdr_count_string(os, &p, byte_order, string_val);
  333.     result = Py_BuildValue ("l", p - os);
  334.     break;
  335.  
  336.     case 'O':
  337.     /* sequence of octets */
  338.     len = PyString_Size(value);
  339.     octets_val = (CORBA_octet*) PyString_AsString(value);
  340.     (void) cdr_count_octets(os, &p, byte_order, octets_val, len);
  341.     result = Py_BuildValue ("l", p - os);
  342.     break;
  343.  
  344.     default:
  345.     return cdr_error("Invalid format character", 0);
  346.     };
  347.  
  348.     return result;
  349. }
  350.  
  351. static PyObject*
  352. cdr_marshal(PyObject* self, PyObject* args)
  353. {
  354.     /* Arguments. */
  355.     char format;
  356.     PyObject* octet_string;
  357.     unsigned long offset;
  358.     PyObject* value;
  359.     CORBA_boolean byte_order;
  360.  
  361.     /* Return value is the new offset after marshalling the data. */
  362.     PyObject* result;
  363.  
  364.     /* Stuff to get the job done! */
  365.     CORBA_octet* os;
  366.     CORBA_octet* p;
  367.  
  368.     CORBA_boolean boolean_val;
  369.     CORBA_octet octet_val;
  370.     CORBA_unsigned_short ushort_val;
  371.     CORBA_short short_val;
  372.     CORBA_unsigned_long ulong_val;
  373.     CORBA_long long_val;
  374.     CORBA_unsigned_longlong ulonglong_val;
  375.     CORBA_longlong longlong_val;
  376.     CORBA_float float_val;
  377.     CORBA_double double_val;
  378.     CORBA_char* string_val;
  379.     CORBA_octet* octets_val;
  380.     CORBA_unsigned_long len;
  381.  
  382.     /* Parse the arguments. */
  383.     if (!PyArg_ParseTuple(args, "cO!lbO", &format, &PyString_Type,
  384.               &octet_string, (long*) &offset, &byte_order, &value))
  385.     {
  386.     return NULL;
  387.     }
  388.  
  389.     /* Get a pointer to the data of the Python string. */
  390.     os = (CORBA_octet*) PyString_AsString(octet_string);
  391.     p = &os[offset];
  392.  
  393.     switch(format) {
  394.  
  395.     case 'b':
  396.     /* boolean */
  397.     boolean_val = (CORBA_boolean) PyInt_AsLong(value);
  398.     (void) cdr_put_boolean(os, &p, byte_order, boolean_val);
  399.     result = Py_BuildValue ("l", p - os);
  400.      break;
  401.  
  402.     case 'c':
  403.     /* char */
  404.     string_val = (CORBA_char*) PyString_AsString(value);
  405.     (void) cdr_put_char(os, &p, byte_order, (CORBA_char) string_val[0]);
  406.     result = Py_BuildValue ("l", p - os);
  407.     break;
  408.  
  409.     case 'o':
  410.     /* octet */
  411.     octet_val = (CORBA_octet) PyInt_AsLong(value);
  412.     (void) cdr_put_octet(os, &p, byte_order, octet_val);
  413.     result = Py_BuildValue ("l", p - os);
  414.     break;
  415.  
  416.     case 'h':
  417.     /* short */
  418.     short_val = (CORBA_short) PyInt_AsLong(value);
  419.     (void) cdr_put_short(os, &p, byte_order, short_val);
  420.     result = Py_BuildValue ("l", p - os);
  421.     break;
  422.  
  423.     case 'H':
  424.     /* unsigned short */
  425.     ushort_val = (CORBA_unsigned_short) PyInt_AsLong(value);
  426.     (void) cdr_put_unsigned_short(os, &p, byte_order, ushort_val);
  427.     result = Py_BuildValue ("l", p - os);
  428.     break;
  429.  
  430.     case 'l':
  431.     /* long */
  432.     long_val = (CORBA_long) PyInt_AsLong(value);
  433.     (void) cdr_put_long(os, &p, byte_order, long_val);
  434.     result = Py_BuildValue ("l", p - os);
  435.     break;
  436.  
  437.     case 'L':
  438.     /* unsigned long */
  439.     if PyInt_Check(value)
  440.     {
  441.       ulong_val = (CORBA_unsigned_long) PyInt_AsLong(value);
  442.     }
  443.     else
  444.         {
  445.       ulong_val = (CORBA_unsigned_long) PyLong_AsUnsignedLong(value);
  446.         }
  447.     (void) cdr_put_unsigned_long(os, &p, byte_order, ulong_val);
  448.     result = Py_BuildValue ("l", p - os);
  449.     break;
  450.  
  451.     case 'n':
  452.     /* long long */
  453.     longlong_from_py_long(&longlong_val, value);
  454.     (void) cdr_put_longlong(os, &p, byte_order, longlong_val);
  455.     result = Py_BuildValue ("l", p - os);
  456.     break;
  457.  
  458.     case 'N':
  459.     /* unsigned long long */
  460.     ulonglong_from_py_long(&ulonglong_val, value);
  461.     (void) cdr_put_unsigned_longlong(os, &p, byte_order, ulonglong_val);
  462.     result = Py_BuildValue ("l", p - os);
  463.     break;
  464.  
  465.     case 'f':
  466.     /* float */
  467.     float_val = (CORBA_float) PyFloat_AsDouble(value);
  468.     (void) cdr_put_float(os, &p, byte_order, float_val);
  469.     result = Py_BuildValue ("l", p - os);
  470.     break;
  471.  
  472.     case 'd':
  473.     /* double */
  474.     double_val = (CORBA_double) PyFloat_AsDouble(value);
  475.     (void) cdr_put_double(os, &p, byte_order, double_val);
  476.     result = Py_BuildValue ("l", p - os);
  477.     break;
  478.  
  479.     case 's':
  480.     /* string */
  481.     string_val = (CORBA_char*) PyString_AsString(value);
  482.     (void) cdr_put_string(os, &p, byte_order, string_val);
  483.     result = Py_BuildValue ("l", p - os);
  484.     break;
  485.  
  486.     case 'O':
  487.     /* sequence of octets */
  488.     len = PyString_Size(value);
  489.     octets_val = (CORBA_octet*) PyString_AsString(value);
  490.     (void) cdr_put_octets(os, &p, byte_order, octets_val, len);
  491.     result = Py_BuildValue ("l", p - os);
  492.     break;
  493.  
  494.     default:
  495.     return cdr_error("Invalid format character", 0);
  496.     };
  497.  
  498.     return result;
  499. }
  500.  
  501. static PyObject*
  502. cdr_unmarshal(PyObject* self, PyObject* args)
  503. {
  504.     /* Arguments. */
  505.     char format;
  506.     PyObject* octet_string;
  507.     unsigned long offset;
  508.     CORBA_boolean byte_order;
  509.  
  510.     /* Return value is a tuple (NewOffset, UnmarshalledValue). */
  511.     PyObject* result;
  512.     PyObject* py_long_val;
  513.  
  514.     /* Stuff to get the job done! */
  515.     CORBA_octet* os;
  516.     CORBA_octet* p;
  517.  
  518.     /* fixme: Should probably use a union here! */
  519.     CORBA_boolean boolean_val;
  520.     CORBA_octet octet_val;
  521.     CORBA_unsigned_short ushort_val;
  522.     CORBA_short short_val;
  523.     CORBA_unsigned_long ulong_val;
  524.     CORBA_long long_val;
  525.     CORBA_unsigned_longlong ulonglong_val;
  526.     CORBA_longlong longlong_val;
  527.     CORBA_float float_val;
  528.     CORBA_double double_val;
  529.     CORBA_char* string_val;
  530.     CORBA_octet* octets_val;
  531.     CORBA_unsigned_long len;
  532.     CORBA_char char_val[2] = {'\0', '\0'};
  533.  
  534.     /* Parse the arguments. */
  535.     if (!PyArg_ParseTuple(args, "cO!lb", &format, &PyString_Type,
  536.               &octet_string, (long*) &offset, &byte_order)) {
  537.     return NULL;
  538.     }
  539.  
  540.     /* Get a pointer to the data of the Python string. */
  541.     os = (CORBA_octet*) PyString_AsString(octet_string);
  542.     p = &os[offset];
  543.  
  544.     switch(format) {
  545.  
  546.     case 'b':
  547.     /* boolean */
  548.     (void) cdr_get_boolean(os, &p, byte_order, &boolean_val);
  549.     result = Py_BuildValue ("(lb)", p - os,  boolean_val);
  550.      break;
  551.  
  552.     case 'c':
  553.     /* char */
  554.     (void) cdr_get_char(os, &p, byte_order, &char_val[0]);
  555.     result = Py_BuildValue ("(ls#)", p - os, char_val, 1);
  556.     break;
  557.  
  558.     case 'o':
  559.     /* octet */
  560.     (void) cdr_get_octet(os, &p, byte_order, &octet_val);
  561.     result = Py_BuildValue ("(lb)", p - os, octet_val);
  562.     break;
  563.  
  564.     case 'h':
  565.     /* short */
  566.     (void) cdr_get_short(os, &p, byte_order, &short_val);
  567.     result = Py_BuildValue ("(lh)", p - os, short_val);
  568.     break;
  569.  
  570.     case 'H':
  571.     /* unsigned short */
  572.     (void) cdr_get_unsigned_short(os, &p, byte_order, &ushort_val);
  573.     result = Py_BuildValue ("(lh)", p - os, ushort_val);
  574.     break;
  575.  
  576.     case 'l':
  577.     /* long */
  578.     (void) cdr_get_long(os, &p, byte_order, &long_val);
  579.     result = Py_BuildValue ("(ll)", p - os, long_val);
  580.     break;
  581.  
  582.     case 'L':
  583.     /* unsigned long */
  584.     (void) cdr_get_unsigned_long(os, &p, byte_order, &ulong_val);
  585.     py_long_val = PyLong_FromUnsignedLong(ulong_val);
  586.     result = Py_BuildValue ("(lO)", p - os, py_long_val);
  587.  
  588.     /* 'Py_BuildValue' increments the reference count. */
  589.     Py_DECREF(py_long_val);
  590.     break;
  591.  
  592.     case 'n':
  593.     /* long long */
  594.     (void) cdr_get_longlong(os, &p, byte_order, &longlong_val);
  595.     py_long_val = longlong_to_py_long(&longlong_val);
  596.     result = Py_BuildValue ("(lO)", p - os, py_long_val);
  597.  
  598.     /* 'Py_BuildValue' increments the reference count. */
  599.     Py_DECREF(py_long_val);
  600.     break;
  601.  
  602.     case 'N':
  603.     /* unsigned long long */
  604.     (void) cdr_get_unsigned_longlong(os, &p, byte_order, &ulonglong_val);
  605.     py_long_val = ulonglong_to_py_long(&ulonglong_val);
  606.     result = Py_BuildValue ("(lO)", p - os, py_long_val);
  607.  
  608.     /* 'Py_BuildValue' increments the reference count. */
  609.     Py_DECREF(py_long_val);
  610.     break;
  611.  
  612.     case 'f':
  613.     /* float */
  614.     (void) cdr_get_float(os, &p, byte_order, &float_val);
  615.     result = Py_BuildValue ("(lf)", p - os, float_val);
  616.     break;
  617.  
  618.     case 'd':
  619.     /* double */
  620.     (void) cdr_get_double(os, &p, byte_order, &double_val);
  621.     result = Py_BuildValue ("(ld)", p - os, double_val);
  622.     break;
  623.  
  624.     case 's':
  625.     /* string */
  626.  
  627.     /* Strings CANNOT be zero length because the length always     */
  628.     /* includes the NULL terminator.  Therefore, even an 'empty'     */
  629.     /* string is of    length 1.                     */
  630.     len = cdr_get_string(os, &p, byte_order, &string_val);
  631.     if (len > 0) {
  632.         /* If we didn't get a buffer then one could not be allocated */
  633.         /* to match the size of the string.                          */
  634.         /* This can be caused by a bad string length value.          */
  635.         if (string_val == 0)
  636.         return cdr_error("Invalid string sequence", 0);
  637.         
  638.         result = Py_BuildValue ("(ls)", p - os, string_val);
  639.         free(string_val);
  640.     }
  641.     /* If we *do* get a zero length string, then the message must    */
  642.     /* have come from some other (buggy!) ORB. In a remarkable     */
  643.     /* display of tolerance, we don't raise an exception, but     */
  644.     /* instead, just create an "empty" string!            */
  645.     else {
  646.         /* This is what we *should* do!                */
  647.         /* return cdr_error("Zero length string", 0);        */
  648.  
  649.         /* But this is what we actually do!                */
  650.         result = Py_BuildValue ("(ls)", p - os, "");
  651.     }
  652.     break;
  653.  
  654.     case 'O':
  655.     /* sequence of octets */        
  656.     len = cdr_get_octets(os, &p, byte_order, &octets_val);
  657.     if (len > 0) {
  658.         /* If we didn't get a buffer then one could not be allocated */
  659.         /* to match the size of the sequence.                        */
  660.         /* This can be caused by a bad sequence length value.        */
  661.         if (octets_val == 0)
  662.         return cdr_error("Invalid octet sequence", 0);
  663.         result = Py_BuildValue ("(ls#)", p - os, octets_val, len);
  664.         free(octets_val);
  665.     }
  666.     else {
  667.         result = Py_BuildValue ("(ls#)", p - os, octets_val, len);
  668.     }
  669.     break;
  670.  
  671.     default:
  672.     return cdr_error("Invalid format character", 0);
  673.     };
  674.  
  675.     return result;
  676. }
  677.  
  678. static PyMethodDef CDRMethods [] =
  679. {
  680.     {"version",         cdr_version,        1},
  681.     {"host_byte_order", cdr_host_byte_order,    1},
  682.     {"octet_to_ASCII",  cdr_octet_to_ASCII,    1},
  683.     {"ASCII_to_octet",  cdr_ASCII_to_octet,    1},
  684.     {"count",           cdr_count,        1},
  685.     {"marshal",        cdr_marshal,        1},
  686.     {"unmarshal",    cdr_unmarshal,        1},
  687.     {NULL, NULL, (int) NULL} /* Sentinel. */
  688. };
  689.  
  690. void
  691. initcdr()
  692. {
  693.     PyObject* module;
  694.     PyObject* dict;
  695.     
  696.     module = Py_InitModule("cdr", CDRMethods);
  697.     dict = PyModule_GetDict(module);
  698.  
  699.     CDRError = PyString_FromString(CDR_ERROR_STRING);
  700.     if (CDRError == NULL)
  701.     {
  702.     Py_FatalError ("Unable to create CDR error object.");
  703.     }
  704.  
  705.     if (PyDict_SetItemString(dict, CDR_ERROR, CDRError) != 0)
  706.     {
  707.     Py_FatalError ("Unable to add CDR error name to dictionary.");
  708.     }    
  709. }
  710.  
  711. /***************************************************************/
  712. /* end of cdrmodule.c */
  713.