C ++ gsoap MIME / DIME для двоичных файлов в Windows - PullRequest
2 голосов
/ 22 июня 2010

Я очень близок к тому, чтобы потерять голову здесь;)

Я разрабатываю сервис, который использует gsoap. Я хотел бы вернуть ответ пантомимы. У меня все работает, но при чтении бинарных файлов все виды файлов, такие как jpeg, pdf и т. Д. ... содержат символ \0 несколько раз над данными (при открытии в блокноте можно увидеть много NUL).

Таким образом, любой код для чтения необработанного файла терпит неудачу, как только он находит символ конца файла. Я попытался заменить \0, но файл стал отображаться неправильно.

Я также попробовал несколько методов, включая пример, который поставляется с gsoap.

Так возобновляется,

Общий код fstream не работает.

for (i = 0; i < MAX_FILE_SIZE; i++)
    { if ((c = fgetc(fd)) == EOF)
        break;
      image.__ptr[i] = c;
    } 

тоже не работает

QFile::ReadAll работает, но при преобразовании QString в char* массив обрезается в первом NUL.

Итак, как лучше всего читать весь двоичный файл? Это безумие, как иногда C ++ в основном.

Заранее спасибо.

Я пробовал это, как предложено ниже,

    UrlToPdf urlToPdf;  
urlToPdf.getUrl(&input, &result);  

QByteArray raw = urlToPdf.getPdf(QString(result.data.c_str()));  

int   size      = raw.toBase64().size();  
char* arraydata = new char[size];  
strcpy(arraydata, raw.toBase64().data());  

soap_set_mime(this, "MIME_boundary", NULL);  
if(soap_set_mime_attachment(this, arraydata, size, SOAP_MIME_BASE64, "application/pdf", NULL, NULL, NULL))  
{  
    soap_clr_mime(this);  

    soapMessage = this->error;  
}  

но не повезло ... ответ MIME больше, чем фактический файл ...

Дэвид Г Ортега

Ответы [ 3 ]

2 голосов
/ 22 июня 2010

для чтения двоичных файлов используйте fread () После того, как вы прочитаете его, обработайте его как массив байтов, а не как строку. Строковые функции не допускаются.

РЕДАКТИРОВАТЬ: в разделе 14.1 документации gSOAP объясняется, как отправлять вложения MIME. Я имею в виду только соответствующие функции (пожалуйста, прочитайте все это).

  int soap_set_mime_attachment(struct soap *soap, char *buf_ptr, size_t buf_size, 
        enum soap_mime_encoding encoding, 
        const char *type, const char *id, 
        const char *location, const char *description);

char *buf_ptr ваш буфер. size_t buf_size - длина вашего буфера.

Так что просто сделайте свой QFile::ReadAll.

это возвращает вам QByteArray. QByteArray имеет метод

QByteArray QByteArray :: toBase64 () const

это вернет

 QByteArray base64image = QByteArray::toBase64(rawImage);    

так что теперь просто сделайте

soap_set_mime(soap, "MIME_boundary", "<boundary.xml@just-testing.com>"); 
/* add a base64 encoded image (base64image points to base64 data) */ 
soap_set_mime_attachment(soap, 
        base64image.data(), base64image.size(), 
        SOAP_MIME_BASE64, "image/jpeg", 
        "<boundary.jpeg@just-testing.com>", NULL, NULL); 

Я не проверял это, но должен быть близок к завершению.

1 голос
/ 09 июля 2010

У меня есть решение для этого ... Как предложил Реник, я попробовал его идею, но она потерпела неудачу, не понимая ее так много ... С логической точки зрения рекник был прав ... но правда в том, что любой король Работа со строками с использованием QT QByteArray, std или mem будет остановлена, когда findind первый символ \ 0, Qt QString может сделать это без проблем, но при преобразовании его в строку c (char *) данные снова будут обрезаны с первым \ 0

Я обнаружил, что использование QDataStream :: readRawData считывает файл в символ *, учитывая размер для чтения. Так вот как я совершил сделку ...

QFile file("test.pdf");
file.open(QIODevice::ReadOnly);

int         size   = file.size();
char*       buffer = new char[size];    
QDataStream stream(&file);
stream.readRawData(buffer, size);

soap_set_mime(this, "MIME_boundary", NULL);
if(soap_set_mime_attachment(this, buffer, size, SOAP_MIME_BINARY, "application/pdf", NULL, NULL, NULL))
{
    soap_clr_mime(this);

    soapMessage = this->error;
}

Обратите внимание, что в строке

if(soap_set_mime_attachment(this, buffer, size, SOAP_MIME_BINARY, "application/pdf", NULL, NULL, NULL))

Я все еще использую size var вместо sizeof (buffer) или любого другого подхода, так как этот будет снова обрезать данные qhen, находя первый \ 0 ...

Надеюсь, это поможет ...

Дэвид Г Ортега

1 голос
/ 22 июня 2010

QFile :: ReadAll работает, но при преобразовании QString в char * массив обрезается в первом NUL.

Вы уверены, что он на самом деле обрезан, или вы просто не можете напечатать /просмотреть массив в отладчике [поскольку строки в стиле C завершены 0]?

Если самой QString недостаточно для ваших нужд, вы можете преобразовать ее в std :: vector или аналогичный, используя диапазонконструктор или присвоение диапазона, у вас будет гораздо меньше скорби по поводу того, сколько данных содержит контейнер.

РЕДАКТИРОВАТЬ: Вот пример кода для чтения fstream из двоичного файла:

std::ifstream image( <image_file_name>, std::ios_base::in | std::ios_base::binary );
std::istream_iterator< char > image_begin( image ), image_end;
std::vector< char > vctImage( image_begin, image_end ); 

std::ios_base::binary является самой важной частью (похоже на fopen/fread ["rb"] и, вероятно, QFile имеет нечто похожее)

Кроме того, публикация некоторого примера кода обычно помогает получить правильный ответ.

HIH

...