Search code examples
c++indy10rad-studio

Is there an equivalent of Indy 9's ReadBuffer() in Indy 10?


This code is written in Borland C++Builder 6 using Indy 9:

void __fastcall TfrmMain::ServerConnect(TIdPeerThread *AThread)
{
     BKUK_PACKET Pkt;
----------(中略)---------------------------------------

AThread->Connection->ReadBuffer((BYTE *)&Pkt,sizeof(BKUK_PACKET));

----------(中略)---------------------------------------
}

The function named ReadBuffer() is not found in Indy 10. Is there an equivalent function?

BKUK_PACKET is a structure of about 1200 bytes.

typedef struct _BKUK_PACKET_
{
    BYTE head[4];
    WORD PayLoad;
    WORD Length;
    BYTE Data[1200];
    WORD Ver;
    BYTE tail[2];
}BKUK_PACKET;

I found ReadBytes() when I was looking at the instruction manual for Indy 10. But when I tried to program as below, I get an error:

Context->Connection->IOHandler->ReadBytes((BYTE *)&Pkt,sizeof(BKUK_PACKET))

[bcc32c error] Main.cpp(530): non-const lvalue reference to type 'Idglobal::TIdBytes' (aka 'DynamicArray<unsigned char>') cannot bind to a temporary of type 'BYTE *' (aka 'unsigned char *')

IdIOHandler.hpp(235): passing argument to parameter 'VBuffer' here

Please tell me how to fix this code.


Solution

  • The signature of ReadBytes() is

    virtual void __fastcall ReadBytes(Idglobal::TIdBytes &VBuffer, 
                                      int AByteCount,
                                      bool AAppend = true);
    

    TIdBytes dynamic nature makes ReadBytes() not a good choice if you want to populate Pkt without using an intermediate variable.

    You could however use TIdIOHandler's

    System::Byte __fastcall ReadByte();
    

    and create your own function to populate objects:

    template<typename T>
    void __fastcall Populate(T& obj, TIdIOHandler* ioh) {
        System::Byte* p = (System::Byte*) &obj;
        for(unsigned count=0; count<sizeof(T); ++count, ++p)
            *p = ioh->ReadByte();
    }
    

    and use it like this:

    BKUK_PACKET Pkt;
    Populate(Pkt, Context->Connection->IOHandler);