[omniORB] Exception while sending an octet sequence

baileyk at schneider.com baileyk at schneider.com
Fri Nov 21 08:54:27 GMT 2003


These two lines concerned me the most

  image_oct_buf = new CORBA::Octet(stat_values.st_size);

    *(image_seq + i) = *(image_oct_buf + i);

The first line must allocate a single CORBA::Octet on the heap and
initialize it's value to the low order byte of stat_values.st_size.  By
changing the parens to square brackets it allocates an array of length
stat_values.st_size, which is clearly what you wanted.

The second line treats the image_seq as a pointer to an array of BinaryFile
objects, which it is not.  My guess it that this compiles because the octet
on the right hand side is converted by the compiler using the max-capacity
constructor for BinaryFile and then BinaryFile::operator=( BinaryFile
const& ) is called.  Perhaps that constructor should be marked 'explicit'
if it isn't already, although older compilers would need that ifdef'd out.
Someone correct me if I'm wrong here.

The image_seq pointer points to only one BinaryFile object, and to access
the i_th element, you *must* use syntax like one of these

image_seq->operator[]( i )  or  (*image_seq)[i]

You can't treat a pointer to a CORBA sequence like a pointer to a C-style
array.  Using a _var type does two things 1) protects against exceptions
that might be thrown and 2) provides a nice operator[] that does not
require the ugly syntax above.

Given the improper use of pointers, your original code could crash in any
number of ways, not only when returning.

By the way, the call to read() is not guaranteed to always read the entire
file, is it?  The return value is being ignored, but read() returns the
number of bytes actually read into the array.  To be robust, I think you
need a loop that keeps reading until the number of bytes you want have been
read.  Something like

size_t bytes_read = 0;
while( bytes_read < stat_values.st_size )
{
   int bytes = read(file_handle,image_oct_buf+bytes_read,
                    stat_value.st_size-bytes_read);
   if( bytes < 0 ) {
      // handle errno values
      break;
   }else{
      bytes_read += bytes;
   }
}



Kendall




                                                                                                                               
                      "Ali Reza"                                                                                               
                      <A.Reza at zensar.co        To:       <baileyk at schneider.com>                                               
                      m>                       cc:       "omniORB Submissions (E-mail)" <omniorb-list at omniorb-support.com>     
                                               Fax to:                                                                         
                      11/21/2003 07:16         Subject:  RE: [omniORB] Exception while sending an octet sequence               
                      AM                                                                                                       
                                                                                                                               
                                                                                                                               




Hi!
I tried analyzing the mistake I made but apparently I could not find any
reason why
  BinaryFile_var image_seq = new BinaryFile(stat_values.st_size);
should work....and
  BinaryFile *image_seq = new BinaryFile(stat_values.st_size);
should not work ?
  I agree that usage of a smart pointer is a better practice ? But in my
case the program was crashing when
I returned return image_seq; instead of return image_seq._retn();

Could somebody explain - why ?

-----Original Message-----
From: baileyk at schneider.com [mailto:baileyk at schneider.com]
Sent: Wednesday, November 19, 2003 9:58 PM
To: Ali Reza
Cc: omniORB Submissions (E-mail)
Subject: Re: [omniORB] Exception while sending an octet sequence



Note some fixes on these lines

  image_oct_buf = new CORBA::Octet[stat_values.st_size]; // you need square
brackets
  BinaryFile_var image_seq = new BinaryFile(stat_values.st_size); // _var
is safer
  image_seq->length( stat_values.st_size ); // still need to set the length

...
    image_seq[i] = *(image_oct_buf + i); // _var type has convenient
operator[]

...
  return image_seq._retn();

Hope this helps.

Kendall





                      "Ali Reza"

                      <A.Reza at zensar.com>                  To:
"omniORB Submissions (E-mail)"
                      Sent by:
<omniorb-list at omniorb-support.com>
                      omniorb-list-bounces at omniorb-        cc:

                      support.com                          Fax to:

                                                           Subject:
[omniORB] Exception while sending an octet sequence

                      11/19/2003 09:15 AM







I have encountered the following exception while trying to use an octet
sequence....

CORBA System ExceptionIDL:omg.org/CORBA/UNKNOWN:1.0
Completion status 2
Minor 1330446337
Meaningful name for minor code UNKNOWN_UserException

My servant code is...

BinaryFile* TS::BinaryFileExchange_impl::fetch(const char* file_name)
{
  int file_handle = open(file_name,_A_RDONLY);
  struct stat stat_values;
  fstat(file_handle,&stat_values);
  CORBA::Octet *image_oct_buf;
  image_oct_buf = new CORBA::Octet(stat_values.st_size);
  BinaryFile *image_seq = new BinaryFile(stat_values.st_size);
  image_seq->length(stat_values.st_size);


  read(file_handle,image_oct_buf,stat_values.st_size);
  for (int i = 0; i < stat_values.st_size ; ++i) {
    *(image_seq + i) = *(image_oct_buf + i);
  }
  delete [] image_oct_buf;
  close(file_handle);

  return image_seq
}

// My IDL is ...
  typedef sequence<octet> BinaryFile;
  interface BinaryFileExchange {
    void send(in BinaryFile f, in string file_name);
    BinaryFile fetch(in string file_name);
  };

Could somebody explain whats happening ? Where things are going wrong ??
on   cout <<  "Length of image_seq" << image_seq->length() << endl;
I get a proper sized sequence i.e. the size of the number of bytes of ,y
gif file.

Thx./Ali














More information about the omniORB-list mailing list