DTerr FileHandleCompressedFD::open_file (const FilePath &pathname, DTsize start, DTsize length, DTsize uncompressed_length)
{
    DTint fd;

    fd = ::open(pathname.full_path().c_str(), O_RDONLY);
    if (fd < 0) {
        return DT3_ERR_FILE_OPEN_FAILED;
    }

    _eof = false;
    _file_g = 0;

    set_fd(fd,start,length,uncompressed_length);

    return DT3_ERR_NONE;
}
Exemple #2
0
void AssetDownloader::downloader_task   (   const URL url,
                                            const FilePath save_path,
                                            DTfloat timeout)
{
    std::shared_ptr<DeviceNetwork> network = System::network_manager();

    //
    // Connecting Phase
    //
    
    // Update status
    update_status (STATUS_CONNECTING, 0,0);
    
    // Resolve the host
    NetworkSocket socket;
    NetworkAddress ip; 
    
    DTerr err = network->resolve_host( ip, url.hostname(), url.port() );
    if (err != DT3_ERR_NONE) {
        LOG_MESSAGE << "HTTPRequest: Unable to resolve host.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
        
    err = network->tcp_open(socket,ip);
    if (err != DT3_ERR_NONE) {
        LOG_MESSAGE << "HTTPRequest: Unable to resolve host.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
        
	// Send http request
    std::string server = url.hostname();
    std::string path = url.path();
    
    // Note:
    // HTTP/1.1 defines the "close" connection option for the sender to signal that the connection 
    // will be closed after completion of the response. For example,
    //      Connection: close
    // in either the request or the response header fields indicates that the connection SHOULD NOT
    // be considered `persistent' (section 8.1) after the current request/response is complete.
    // HTTP/1.1 applications that do not support persistent connections MUST include the "close" 
    // connection option in every message.

    std::string request =   "GET " + path + " HTTP/1.1\r\n" +
                            "Host: " + server + "\r\n" +
                            "User-Agent: DT3\r\n" +
                            "Accept: */*\r\n" +
                            "Cache-Control: max-age=0\r\n" +
                            "Connection: close\r\n" +
                            "\r\n";

    LOG_MESSAGE << "Sending...";
    LOG_MESSAGE << request;
    
    NetworkPacket packet_request;
    packet_request.set_data(request);
    
    err = network->tcp_send(packet_request, socket);
    if (err != DT3_ERR_NONE) {
        network->tcp_close(socket);
        
        LOG_MESSAGE << "HTTPRequest: Unable to send packet.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
    
    //
    // Downloading Phase
    //
    
    update_status (STATUS_DOWNLOADING, 0,0);

    // Hash the URL
    FilePath temp_file_path = FilePath(HAL::save_dir().full_path() + "/" + MoreStrings::cast_to_string(MoreStrings::hash(url.full_url())));
    
    // Create a temporary file
    BinaryFileStream temp_file;
    err = FileManager::open(temp_file, temp_file_path, false);
    
    if (err != DT3_ERR_NONE) {
        network->tcp_close(socket);
        
        LOG_MESSAGE << "HTTPRequest: Unable to open file for writing.";
        update_status (STATUS_ERROR, 0,0);
        return;
    }
    
    LOG_MESSAGE << "HTTPRequest: Opened temp file at " << temp_file_path.full_path();

    
    // Temporary storage for buffer
    std::string data;
        
    // Timer for timeout
    TimerHires timeout_timer;
    
    do {

        // Get the results
        NetworkPacket packet;
        packet.set_data_size(1024*16);

        err = network->tcp_recv(packet,socket);
        
        // If we recieved some data, append it to the buffer
        if (packet.data_size() > 0) {
            data += packet.data_as_string();
            append_data(data, temp_file);
            timeout_timer.reset_abs_time();
        }
        
        // Check complete
        if ( (_current_size == _total_size) && (_total_size > 0) ) {
            break;
        }
        
        // If we hit our timeout, then we abort
        if (timeout_timer.abs_time() > timeout) {
            network->tcp_close(socket);
            
            LOG_MESSAGE << "Http request timed out!";
            update_status (STATUS_ERROR, 0,0);
            
            // Remove the temporary file
            temp_file_path.del();
            return;
        }
        
        // Check for cancel
        if (_cancelled) {
            network->tcp_close(socket);
            
            LOG_MESSAGE << "Http request cancelled!";
            update_status (STATUS_CANCELLED, 0,0);
            
            // Remove the temporary file
            temp_file_path.del();
            return;
        }
        
    } while (err == DT3_ERR_NET_WOULD_BLOCK || err == DT3_ERR_NONE);
    
    // Close the connection, we're done
    network->tcp_close(socket);
    
    // Close off the stream
    finalize_data(data, temp_file);

    //
    // Finalizing phase
    //
    
    // Move the file
    save_path.del();
    temp_file_path.move(save_path);
    
    LOG_MESSAGE << "Saving file to " << save_path.full_path();


    // Final update of status
    update_status (STATUS_COMPLETE, _current_size, _total_size);
}
Exemple #3
0
static void fileOpenCB (const FilePath &path, std::shared_ptr<FileHandle> &file_handle, DTsize &start, DTsize &length, void *data)
{
    // Check if it's an asset
    if (path.full_path().substr(0,6) != "Asset@") {
        file_handle = NULL;
        return;
    }

    // State
    struct android_app* state = (struct android_app*) data;

    // Get the asset manager
    AAssetManager* mgr = state->activity->assetManager;


    // Open Files
    if (path.in_package()) {
        // In package
        std::string full_path = path.package_path();
        full_path = full_path.substr(6);    // Strip off "Asset@"

        LOG_MESSAGE << "Opening Asset from Package: " << full_path;

        // Get the asset from the asset manager
        AAsset* asset = AAssetManager_open(mgr, full_path.c_str(), AASSET_MODE_UNKNOWN);

        // Get a file descriptor for the asset
        off_t outStart, outLength;
        int fd = AAsset_openFileDescriptor(asset, &outStart, &outLength);

        // Close the asset
        AAsset_close(asset);

        // Error check
        if (fd < 0) {
            file_handle = NULL;
            return;
        }

        // Find file in package
        FilePath packagename;
        DTsize file_start, file_length, file_uncompressed_length;
        FileManager::start_and_length(path, packagename, file_start, file_length, file_uncompressed_length);

        LOG_MESSAGE << " Asset: " << path.full_path();
        LOG_MESSAGE << " Start: " << file_start;
        LOG_MESSAGE << " Length: " << file_length;
        LOG_MESSAGE << " Uncompressed Length: " << file_uncompressed_length;

        if (file_length == file_uncompressed_length) {
            auto fh = FileHandleUncompressedFD::create();
            fh->set_fd(fd);

            file_handle = fh;
            start = file_start;
            length = file_length;

        } else {
            auto fh = FileHandleCompressedFD::create();
            fh->set_fd(fd,file_start,file_length,file_uncompressed_length);

            file_handle = fh;
            start = 0;
            length = file_uncompressed_length;
        }

    } else {
        // Not in Package
        std::string full_path = path.full_path();
        full_path = full_path.substr(6);    // Strip off "Asset@"

        LOG_MESSAGE << "Opening Asset: " << full_path;

        // Get the asset from the asset manager
        AAsset* asset = AAssetManager_open(mgr, full_path.c_str(), AASSET_MODE_UNKNOWN);

        // Get a file descriptor for the asset
        off_t outStart, outLength;
        int fd = AAsset_openFileDescriptor(asset, &outStart, &outLength);

        // Close the asset
        AAsset_close(asset);

        // Error check
        if (fd < 0) {
            file_handle = NULL;
            return;
        }

        auto fh = FileHandleUncompressedFD::create();
        fh->set_fd(fd);

        file_handle = fh;
        start = outStart;
        length = outLength;
    }

}