void BlobRegistryImpl::registerBlobURL(const KURL& url, PassOwnPtr<BlobData> blobData) { ASSERT(isMainThread()); registerBlobResourceHandleConstructor(); RefPtr<BlobStorageData> blobStorageData = BlobStorageData::create(blobData->contentType(), blobData->contentDisposition()); // The blob data is stored in the "canonical" way. That is, it only contains a list of Data and File items. // 1) The Data item is denoted by the raw data and the range. // 2) The File item is denoted by the file path, the range and the expected modification time. // 3) The URL item is denoted by the URL, the range and the expected modification time. // All the Blob items in the passing blob data are resolved and expanded into a set of Data and File items. for (BlobDataItemList::const_iterator iter = blobData->items().begin(); iter != blobData->items().end(); ++iter) { switch (iter->type) { case BlobDataItem::Data: blobStorageData->m_data.appendData(iter->data, 0, iter->data->length()); break; case BlobDataItem::File: blobStorageData->m_data.appendFile(iter->path, iter->offset, iter->length, iter->expectedModificationTime); break; case BlobDataItem::URL: blobStorageData->m_data.appendURL(iter->url, iter->offset, iter->length, iter->expectedModificationTime); break; case BlobDataItem::Blob: if (m_blobs.contains(iter->url.string())) appendStorageItems(blobStorageData.get(), m_blobs.get(iter->url.string())->items(), iter->offset, iter->length); break; } } m_blobs.set(url.string(), blobStorageData); }
Blob::Blob(PassOwnPtr<BlobData> blobData, long long size) : m_type(blobData->contentType()) , m_size(size) { ASSERT(blobData); // Create a new internal URL and register it with the provided blob data. m_internalURL = BlobURL::createInternalURL(); ThreadableBlobRegistry::registerBlobURL(m_internalURL, blobData); }