Попытка использовать URLRequestInfo::SetStreamToFile и URLResponseInfo::GetBodyAsFileRef

Я работаю над плагином NaCl для Chrome и пытаюсь загрузить файл ресурсов URL локально, во временный кеш Chrome, но безуспешно.

Вот как я поступаю:

// I indicate that I want the resource to be downloaded to a file
m_URLRequestInfo.SetStreamToFile( true );

// I open the request:
m_URLLoader.Open( m_URLRequestInfo, m_CCFactory.NewCallback( &MyClass::OnOpen ) );

...    
// My callback (OnOpen) is eventually called.
// I then check to make sure the status code is 200 using this call:
m_URLLoader.GetResponseInfo().GetStatusCode()

// Then I ask to download the whole file:
m_URLLoader.FinishStreamingToFile( m_CCFactory.NewOptionalCallback( &MyClass::OnFileDownloaded ) );

...
// My other callback (OnFileDownloaded) gets eventually called,
// and again the status code is 200.
// Then I query the FileRef using this call:
pp::FileRef l_FileRef = m_URLLoader.GetResponseInfo().GetBodyAsFileRef();

Возвращенный pp::FileRef выглядит нормально, но pp::FileRef::GetFileSystemType() возвращает PP_FILESYSTEMTYPE_EXTERNAL, а затем вызов pp::FileRef::GetPath() терпит неудачу (он возвращает UNDEFINED pp::Var).

Так что с этого момента я потерян. Я не знаю, что еще я должен сделать, чтобы получить действительный pp::FileRef, указывающий на локальный файл в кеше браузера. Моя конечная цель — открыть этот локальный файл (в моем случае файл изображения) с помощью стандартного системного файла ввода-вывода, такого как fopen().

Спасибо за любой свет!


person user2920712    schedule 25.10.2013    source источник


Ответы (2)


Есть ли причина, по которой вы не можете использовать библиотеку nacl_io? С его помощью вы можете написать что-то вроде этого:

#include <stdio.h>
#include <sys/mount.h>

// Mount an HTTP filesystem that reads files from "http://example.com/path/...".
mount("http://example.com/path/", "/mnt/http", "httpfs", 0, "");

// Performs a URL Request of "http://example.com/path/my_image.png".
FILE* file = fopen("/mnt/http/my_image.png", "r");
...

Взгляните на демонстрацию nacl_io в SDK. Он находится по адресу $NACL_SDK_ROOT/examples/demo/nacl_io.

person binji    schedule 25.10.2013

После более тщательного прочтения документации и проведения большего количества тестов я наконец понял, что я делаю неправильно.

Когда мы вызываем pp::URLLoader::FinishStreamingToFile, файл загружается в кеш браузера, но его нельзя открыть/прочитать с помощью обычных сервисов stdio, таких как fopen, fread и т. д. Нам нужно использовать сервисы класса pp::FileIO, чтобы открыть полученный pp::FileRef и прочитать содержимое файла.

Итак, вот что я сделал, чтобы успешно загрузить и прочитать файл, который был загружен для меня браузером. В основном я продолжал использовать сервисы C++ PPAPI.

(1) после обратного вызова из m_URLLoader->FinishStreamingToFile мы затем вызываем m_FileIO->Open, чтобы открыть загруженный файл, используя полученный FileRef;

(2) после обратного вызова из m_FileIO->Open мы затем вызываем m_FileIO->Query для получения размера загруженного файла (и некоторых других атрибутов файла);

(3) после обратного вызова из pp::FileIO::Query мы затем проверяем тип атрибута файла (например, не папка), выделяем достаточно большой буфер памяти, чтобы вместить все содержимое файла, и начинаем вызывать pp::FileIO: :Read для получения содержимого файла;

(4) при обратном вызове из pp::FileIO::Read, если полученный аргумент nResult равен 0, то мы достигли EOF и закончили чтение содержимого файла в наш буфер памяти; если полученный nResult > 0, то он указывает количество успешно прочитанных байтов, и мы снова вызываем m_FileIO->Read, чтобы продолжить чтение байтов и сохранить их в другом смещении в нашем буфере памяти; если полученный nResult ‹ 0, то произошла ошибка и мы должны завершить процесс чтения.

Много шагов и множество обратных вызовов для управления, но в итоге все работает гладко.

person user2920712    schedule 30.10.2013