paulscherrerinstitute / StreamDevice

EPICS Driver for message based I/O
GNU General Public License v3.0
28 stars 42 forks source link

Added compatibility for using vsnprintf on VS2010 and lower #48

Closed DominicOram closed 4 years ago

DominicOram commented 4 years ago

Under earlier versions of visual studio (VS2010 and below) vsnprintf will return a -1 if there is not enough room to print. Later versions (and linux) will return the number of characters that would have been printed if there was room, which was then used in StreamBuffer to expand the buffer. This leads to an infinite loop on VS2010.

This change calls _vscprintf instead (for VS2010) to get the size required to expand the buffer.

I also thought about using epicsVsnprintf from EPICS base but as that hasn't already been used for the vxWorks compatibility I assume you don't want to add an EPICS dependency into StreamBuffer?

dirk-zimoch commented 4 years ago

I assume you don't want to add an EPICS dependency into StreamBuffer?

Correct. Also other older compilers (or rather libc implementations, e.g. glibc 2.0) may have a vsnprintf function that simply returns -1. I may want to implement a solution that is not _MSC_VER specific. The Linux sprintf man page has an example how to do this. Basically: as long as vsnprintf returns -1 double the buffer size and try again.

DominicOram commented 4 years ago

Ok, sorry, I'm a little confused. The current implementation will call grow(len) if vsnprintf returns -1 which keeps the buffer size constant, this is why it was failing on VS2010. Are you saying the implementation should be to double the buffer size, i.e. grow(len+len)? Or that grow(len) should double the buffer size? There's also the issue where vsnprintf returning -1 could be indicative of a problem other than just capacity and so you will get stuck in an infinite loop increasing the buffer size.

dirk-zimoch commented 4 years ago

grow(len) should increase the buffer. It does not because it demands to increase the buffer size to the current filling+1. That makes no sense because it is almost always already fulfilled. grow(cap*2-1) would make sense I think. It doubles the capacity (buffer size).

dirk-zimoch commented 4 years ago

I pushed the fix I proposed above. Reopen it it does not fix the problem.