Search code examples
c++stringcorbastrstream

String stream related problems


I am trying to do the following

std::stringstream str;
string  string1, string2;
long a = 23343;
long b = 323234;
str << std::hex << a;
str >> string1;       //line no. 6
str << std::hex << b;
str >> string2;       //line no.8

a & b are values contained inside a structure and this structure is being sent as an event to other process, which extracts these values. The problem I encounter is when I do

str.flush()

after line no.6, the string string1 is empty and an empty string is passed to other process.

Is there any way to reuse the stringstream str for different values?

Here is the actual code --

void* CIAppDiagService::SendDidValue(void *arg)
{

DiagService::SReadDIDResponse didResponse;
didResponse.ComponentId = ::DiagService::eComponentMin;  //Todo
didResponse.bStatus=false;
didResponse.nDIDCode=((CIAppDiagService*)arg)->mDIDCode;


if(didResponse.nDIDCode ==  0xD95C)
{
    ::CIApplicationManager::UUIDList_var aUidList;
    //get uuid list
    AppMgrServerData::getAppMgrServerData()->AppDirectory().getList(aUidList.out()); //fills the UUIDList which is a sequence of string

    if(aUidList->length() > 0)
    {
        std::string aAppDetails,aAppVersion,aAppVersionString,aAppIDString,NumberOfAppsInstalledString;
        AppId aAppId;   //typedef long AppId
        CORBA::ULong ulength = aUidList->length();
        std::stringstream stream,stream1,stream2;
        short int iAppVersion;
        aAppDetails.append("000000ff");
        short int iNumberOfAppsInstalled = AppMgrServerData::getAppMgrServerData()->AppDirectory().getTotalAppsInstalled();  // returns and integer
        stream << std::hex << iNumberOfAppsInstalled;
        stream >> NumberOfAppsInstalledString;
        stream.clear();
        if(1 == NumberOfAppsInstalledString.length() )
        {
            NumberOfAppsInstalledString = "000" + NumberOfAppsInstalledString;
        }
        else if(2 == NumberOfAppsInstalledString.length() )
        {
            NumberOfAppsInstalledString = "00" + NumberOfAppsInstalledString;
        }
        else if(3 == NumberOfAppsInstalledString.length() )
        {
            NumberOfAppsInstalledString = "0" + NumberOfAppsInstalledString;
        }
        strcat(const_cast<char*>(aAppDetails.c_str()),NumberOfAppsInstalledString.c_str());

        for(int count = 0; count< aUidList->length(); count++)
        {
                        aAppId = AppMgrServerData::getAppMgrServerData()->AppDirectory().getApplicationAppIDByUid((aUidList[count]));
            aAppVersion = AppMgrServerData::getAppMgrServerData()->AppDirectory().getAppVersion(string(aUidList[count]));


            stream1 << std::hex << aAppId % (std::numeric_limits<uint16_t>::max()+1);


            stream1 >> aAppIDString; //convert aAppID into string

            stream1.clear();

            strcat(const_cast<char*>(aAppDetails.c_str()),aAppIDString.c_str());
            TRACE(cout<<"check 1"<<endl);
            iAppVersion = atoi(aAppVersion.c_str());
            stream2 << std::hex << aAppVersion;
            TRACE(cout<<"CIAppDiagService::: SendDidValue::: aAppVersion stream = "<< stream2 << endl);
            stream2.seekg(0, std::ios::beg);
            stream2 >> aAppVersionString;

            stream2.clear();

//The following is some restriction/implementation that i need to follow.

            if(1 == aAppVersionString.length() )
            {
                aAppVersionString = "000" + aAppVersionString;
            }
            else if(2 == aAppVersionString.length() )
            {
                aAppVersionString = "00" + aAppVersionString;
            }
            else if(3 == aAppVersionString.length() )
            {
                aAppVersionString = "0" + aAppVersionString;
            }
            strcat(const_cast<char*>(aAppDetails.c_str()),aAppVersionString.c_str()); //aAppVersion concatenated

        }
        int length = strlen(aAppDetails.c_str()) + 1;
        if(length)
        {
            didResponse.DIDValue.length(length);
            for(int i=0; i < length; i++)
            {
                didResponse.DIDValue[i]=aAppDetails[i];
                cout<<" CIAppDiagService::SendDidValue:: didResponse.DIDValue[i]"<<didResponse.DIDValue[i]<<endl;
            }
        //  didResponse.DIDValue[length] = '\0';
            didResponse.bStatus = true;
        }
        else
        {
            char errResult[]={0x7F,0x22,0x22};  //error codes from media team/to be changed
            didResponse.DIDValue.length(3);
            didResponse.bStatus=false;

            for(int i=0; i<3; i++)
            {
                didResponse.DIDValue[i]=errResult[i];
            }
        }
            ((CIAppDiagService*)arg)->SendEvent_ResponseDidValue(didResponse);
    }
    else
    {
        cout<<" No applications installed/No AppIDs found. "<<endl;
    }
}

return 0;

}

void CIAppDiagService::SendEvent_ResponseDidValue(DiagService::SReadDIDResponse didResponse)
{
TRACE(cout<<"CIAppDiagService::entered in Send_Event Response"<<endl);
CosNotification::StructuredEvent event;
event.header.fixed_header.event_type.domain_name = CORBA::string_dup(DiagService::gDiagnosisServiceDomain);
event.header.fixed_header.event_name = CORBA::string_dup(DiagService::gReadDIDEventName);
event.header.variable_header.length(0); // put nothing here
event.filterable_data.length(0);

 DiagService::SReadDIDResponse *tmp = new DiagService::SReadDIDResponse;
 if (tmp != NULL) {
    tmp->ComponentId = didResponse.ComponentId; //TODO
    tmp->DIDValue = didResponse.DIDValue;
    tmp->bStatus = didResponse.bStatus;
    tmp->nDIDCode = didResponse.nDIDCode;

    event.remainder_of_body <<= *tmp;
    TRACE(cout<<"CIAppDiagService::SendEvent_ResponseDidValue:: calling send event"<< endl);
    mCIDiagSupplier->send_event(event);
 }

TRACE(cout<<"CIAppDiagService::exited from Send_Event Response"<<endl);

}

The idea is to concatenate all strings into a string appDetails and fill the structure member SReadDIDResponse.DIDValue And here is the structure SReadDIDResponse

struct SReadDIDResponse {
EComponent ComponentId;   //enum values
TID nDIDCode;             // integer
OctetSeq DIDValue;       //octet sequence
boolean bStatus;
};

Solution

  • Use str.clear() to reset the string stream after line 6.

    See Problem with re-using a stringstream object