_popen() i czytanie wejścia binarnego

0

Witam, piszę właśnie program parsujący pewne rodzaje skryptów poprzez CGI. Do odpalenia i wczytania wyjścia parsera używam funkcji _popen(), a następnie zapisuję uzyskane wyniki do strumienia std::stringstream. Algorytm działa świetnie dopóki parser nie zwróci wyjścia binarnego (na przykład gdy parser PHP zwróci dynamicznie utworzony obrazek). Wtedy dane wczytane do strumienia są uszkodzone, na przykład ładuje się tylko pół obrazka a reszta jest ucięta. Oto kod użyty do wczytywania:

 
std::string ExcuteProccess(const std::string& process, const std::string& scriptHome)
{
	std::string command = std::string("cd ") + scriptHome + " && " + process;

	//Open pipe
	#ifndef _WIN32
		command += " 2> dev/null"; //Redirect stderr to null device
		FILE* pipe = popen(process.c_str(), "r");
	#else
		command += " 2> nul";
		FILE* pipe = _popen(command.c_str(), "rb");
	#endif

         if(!pipe) return "ERROR";

	//Read output
	std::stringstream result;
	char buffer[128];
        while(!feof(pipe)) 
	{
		memset(buffer, 0, 128); 
		size_t dataSize = 0;

		if((dataSize = fread(buffer, 1, 128, pipe)) != NULL)
			result.write(buffer, (std::streamsize)dataSize);
         }

	//Close pipe
        #ifndef _WIN32
		pclose(pipe);
	#else
		_pclose(pipe);
	#endif

    return result.str();
}

Ma ktoś jakiś pomysł jak można poprawnie te dane odczytać?
Z góry dziękuję i pozdrawiam.

0

Bo string się urywa na najbliższym znaku \0. Musisz użyć C-stringów i zwracać jakoś ilość pobranych danych.

0

Ale nie znam ilości danych jaka zostanie zwrócona. Musiałbym reallokować bufor przy każdym obiegu pętli wczytującej. Tak?

0

Ano tak. Z resztą i tak to robisz, ale ukryte w funkcjach STL'a.

0

Nie rozumiem. Po co miałbym w takim razie używać c-stringów skoro to samo mogę uzyskać dzięki std::string. W c-stringach znak '\0' przypadkiem też nie ucina reszty danych?

EDIT: Dobra, poradziłem sobie. Zamiast do stringstream'a zapisuję pobrane dane do obiektu typu std::vector<char>. Potem wystarczy stworzyć obiekt std::string(&endBuffer[0], endBuffer.size()) i mam pięknie zapisane dane binarne.

Pozdrawiam

0

Nie ucina, jedynie jeśli korzystasz z funkcji jak strcpy to one kopiują dane aż nie napotkają znaku \0. C-string a żadnym wypadku nigdy nie jest ucinany, to jest zwykła tablica znaków.

1 użytkowników online, w tym zalogowanych: 0, gości: 1