[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