@@ -936,8 +936,11 @@ class Attachment final : public RefCntIface<IAttachmentImpl<Attachment, CheckSta
936936 void internalDetach (CheckStatusWrapper* status);
937937 void internalDropDatabase (CheckStatusWrapper* status);
938938 SLONG getSingleInfo (CheckStatusWrapper* status, UCHAR infoItem);
939- bool getWireStatsInfo (unsigned int item_length, const unsigned char * items,
940- unsigned int buffer_length, unsigned char * buffer) const ;
939+
940+ // Returns nullptr if all items was handled or if user buffer is full, else
941+ // returns pointer into unused buffer space. Handled info items are removed.
942+ unsigned char * getWireStatsInfo (UCharBuffer& info, unsigned int buffer_length,
943+ unsigned char * buffer);
941944
942945 Rdb* rdb;
943946 const PathName dbPath;
@@ -1968,16 +1971,19 @@ IAttachment* Loopback::createDatabase(CheckStatusWrapper* status, const char* fi
19681971}
19691972
19701973
1971- bool Attachment::getWireStatsInfo (unsigned int item_length, const unsigned char * items ,
1972- unsigned int buffer_length, unsigned char * buffer) const
1974+ unsigned char * Attachment::getWireStatsInfo (UCharBuffer& info, unsigned int buffer_length ,
1975+ unsigned char * buffer)
19731976{
19741977 const rem_port* const port = rdb->rdb_port ;
19751978
19761979 UCHAR* ptr = buffer;
19771980 const UCHAR* const end = buffer + buffer_length;
19781981
1979- for (auto item = items ; item < items + item_length; item++ )
1982+ for (auto item = info. begin () ; item < info. end (); )
19801983 {
1984+ if (ptr >= end)
1985+ return nullptr ;
1986+
19811987 switch (*item)
19821988 {
19831989 case fb_info_wire_snd_packets:
@@ -1997,23 +2003,28 @@ bool Attachment::getWireStatsInfo(unsigned int item_length, const unsigned char*
19972003 else
19982004 ptr = fb_utils::putInfoItemInt (*item, value, ptr, end);
19992005
2000- fb_assert (ptr);
2006+ if (!ptr)
2007+ return nullptr ;
2008+
2009+ info.remove (item);
20012010 break ;
20022011 }
20032012
20042013 case isc_info_end:
2005- if (ptr < end )
2006- *ptr++ = *item ;
2014+ if (info. getCount () > 1 )
2015+ return ptr ;
20072016
2008- return true ;
2017+ *ptr++ = *item;
2018+ info.remove (item);
2019+ return nullptr ;
20092020
20102021 default :
2011- // Let someone else handle unknown item
2012- return false ;
2022+ item++;
2023+ break ;
20132024 }
20142025 }
20152026
2016- return true ;
2027+ return info. isEmpty () ? nullptr : ptr ;
20172028}
20182029
20192030
@@ -2045,18 +2056,22 @@ void Attachment::getInfo(CheckStatusWrapper* status,
20452056
20462057 RefMutexGuard portGuard (*port->port_sync , FB_FUNCTION);
20472058
2048- if (getWireStatsInfo (item_length, items, buffer_length, buffer))
2059+ UCharBuffer tempInfo (items, item_length);
2060+ UCHAR* ptr = getWireStatsInfo (tempInfo, buffer_length, buffer);
2061+ if (!ptr)
20492062 return ;
20502063
2064+ buffer_length -= ptr - buffer;
2065+
20512066 UCHAR* temp_buffer = temp.getBuffer (buffer_length);
20522067
20532068 info (status, rdb, op_info_database, rdb->rdb_id , 0 ,
2054- item_length, items , 0 , 0 , buffer_length, temp_buffer);
2069+ tempInfo. getCount (), tempInfo. begin () , 0 , 0 , buffer_length, temp_buffer);
20552070
20562071 string version;
20572072 port->versionInfo (version);
20582073
2059- MERGE_database_info (temp_buffer, buffer , buffer_length,
2074+ MERGE_database_info (temp_buffer, ptr , buffer_length,
20602075 DbImplementation::current.backwardCompatibleImplementation (), 3 , 1 ,
20612076 reinterpret_cast <const UCHAR*>(version.c_str ()),
20622077 reinterpret_cast <const UCHAR*>(port->port_host ->str_data ),
0 commit comments