ibm-messaging / mq-golang

Calling IBM MQ from Go applications
Apache License 2.0
168 stars 60 forks source link

Fail Get if buf created with len=0 #110

Closed romapres2010 closed 5 years ago

romapres2010 commented 5 years ago

In method (object MQObject) Get you used bufflen := len(buffer)

but if you create buffer as Buf = make([]byte, 0, 1024), then len(Buf) would be 0. So any attempts of calling Get method failed.

I think it’s better to use cap(buffer) instead of len(buffer).

ibmmqmet commented 5 years ago

It is quite common to want to use zero-length buffers during GET.

Sometimes to just browse, sometimes as a quick way to clear messages you are not interested in, sometimes to see what the real length is. The actual message body may not be important. We cannot tell in the Get() processing what use the application wants to make of its buffers; we need to be told how much space to try to fill.

So I believe len(buf) is the right thing to use.

MQGMO flags decide whether the truncation is treated as an error or warning - when it's a warning, the message is removed from the queue.

romapres2010 commented 5 years ago

For example. I have message about 512 byte. But I do not know real size, so I create buffer - buf = make([]byte, 1024). len(buf) = 1024, cap(buf) = 1024. After calling Get() method, I have len(buf) = 1024, cap(buf) = 1024, datalen = 512.

Instead of len(buf) = 512, cap(buf) = 1024. This is not very convenient. If I try to use this buf, then between 513 and 1024 byte I have trash. So I need to use additional operation buf = buf[0,datalen].

ibmmqmet commented 5 years ago

The cgo interface does not play very well with slices. For example I just tried changing to cap(buffer) and it either didn't work at all (where's the pointer to the buffer if it's created with make([]byte,0,1024)?) or even with a few further tweaks did not actually change either the capacity or - more important - the length of the returned buffer even though the correct data was returned in that buffer. There might be more complex routes to making it work but, apart from introducing incompatibilities with current apps, it seems potentially fragile.

romapres2010 commented 5 years ago

May be add buffer = buffer[0:datalen] in method Get() to avoid trash between buffer[datalen] and buffer[cap(buffer)]

godatalen := int(datalen) buffer = buffer[0:datalen] copyMDfromC(&mqmd, gomd) copyGMOfromC(&mqgmo, gogmo)

ibmmqmet commented 5 years ago

V4.1.0 adds a new GetSlice() verb that does something like this. Had to be a new verb to maintain compatibility. Perhaps eventually I could go through a deprecate/replace cycle but this should meet the requiremen.

romapres2010 commented 5 years ago

Thanks. It is works well