Home | History | Annotate | Download | only in blob
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 #include "platform/blob/BlobData.h"
     33 
     34 #include "platform/UUID.h"
     35 #include "platform/blob/BlobRegistry.h"
     36 #include "platform/text/LineEnding.h"
     37 #include "wtf/ArrayBuffer.h"
     38 #include "wtf/ArrayBufferView.h"
     39 #include "wtf/OwnPtr.h"
     40 #include "wtf/PassRefPtr.h"
     41 #include "wtf/RefPtr.h"
     42 #include "wtf/Vector.h"
     43 #include "wtf/text/CString.h"
     44 #include "wtf/text/TextEncoding.h"
     45 
     46 namespace blink {
     47 
     48 const long long BlobDataItem::toEndOfFile = -1;
     49 
     50 RawData::RawData()
     51 {
     52 }
     53 
     54 void RawData::detachFromCurrentThread()
     55 {
     56 }
     57 
     58 void BlobDataItem::detachFromCurrentThread()
     59 {
     60     data->detachFromCurrentThread();
     61     path = path.isolatedCopy();
     62     fileSystemURL = fileSystemURL.copy();
     63 }
     64 
     65 PassOwnPtr<BlobData> BlobData::create()
     66 {
     67     return adoptPtr(new BlobData());
     68 }
     69 
     70 void BlobData::detachFromCurrentThread()
     71 {
     72     m_contentType = m_contentType.isolatedCopy();
     73     for (size_t i = 0; i < m_items.size(); ++i)
     74         m_items.at(i).detachFromCurrentThread();
     75 }
     76 
     77 void BlobData::appendData(PassRefPtr<RawData> data, long long offset, long long length)
     78 {
     79     m_items.append(BlobDataItem(data, offset, length));
     80 }
     81 
     82 void BlobData::appendFile(const String& path)
     83 {
     84     m_items.append(BlobDataItem(path));
     85 }
     86 
     87 void BlobData::appendFile(const String& path, long long offset, long long length, double expectedModificationTime)
     88 {
     89     m_items.append(BlobDataItem(path, offset, length, expectedModificationTime));
     90 }
     91 
     92 void BlobData::appendBlob(PassRefPtr<BlobDataHandle> dataHandle, long long offset, long long length)
     93 {
     94     m_items.append(BlobDataItem(dataHandle, offset, length));
     95 }
     96 
     97 void BlobData::appendFileSystemURL(const KURL& url, long long offset, long long length, double expectedModificationTime)
     98 {
     99     m_items.append(BlobDataItem(url, offset, length, expectedModificationTime));
    100 }
    101 
    102 void BlobData::appendText(const String& text, bool doNormalizeLineEndingsToNative)
    103 {
    104     RefPtr<RawData> data = RawData::create();
    105     Vector<char>* buffer = data->mutableData();
    106 
    107     CString utf8Text = UTF8Encoding().normalizeAndEncode(text, WTF::EntitiesForUnencodables);
    108     if (doNormalizeLineEndingsToNative) {
    109         normalizeLineEndingsToNative(utf8Text, *buffer);
    110     } else {
    111         buffer->append(utf8Text.data(), utf8Text.length());
    112     }
    113 
    114     m_items.append(BlobDataItem(data.release()));
    115 }
    116 
    117 void BlobData::appendBytes(const void* bytes, size_t length)
    118 {
    119     RefPtr<RawData> data = RawData::create();
    120     Vector<char>* buffer = data->mutableData();
    121     buffer->append(static_cast<const char *>(bytes), length);
    122     m_items.append(BlobDataItem(data.release()));
    123 }
    124 
    125 void BlobData::appendArrayBuffer(const ArrayBuffer* arrayBuffer)
    126 {
    127     appendBytes(arrayBuffer->data(), arrayBuffer->byteLength());
    128 }
    129 
    130 void BlobData::appendArrayBufferView(const ArrayBufferView* arrayBufferView)
    131 {
    132     appendBytes(arrayBufferView->baseAddress(), arrayBufferView->byteLength());
    133 }
    134 
    135 void BlobData::swapItems(BlobDataItemList& items)
    136 {
    137     m_items.swap(items);
    138 }
    139 
    140 long long BlobData::length() const
    141 {
    142     long long length = 0;
    143 
    144     for (Vector<BlobDataItem>::const_iterator it = m_items.begin(); it != m_items.end(); ++it) {
    145         const BlobDataItem& item = *it;
    146         if (item.length != BlobDataItem::toEndOfFile) {
    147             ASSERT(item.length >= 0);
    148             length += item.length;
    149             continue;
    150         }
    151 
    152         switch (item.type) {
    153         case BlobDataItem::Data:
    154             length += item.data->length();
    155             break;
    156         case BlobDataItem::File:
    157         case BlobDataItem::Blob:
    158         case BlobDataItem::FileSystemURL:
    159             return BlobDataItem::toEndOfFile;
    160         }
    161     }
    162     return length;
    163 }
    164 
    165 BlobDataHandle::BlobDataHandle()
    166     : m_uuid(createCanonicalUUIDString())
    167     , m_size(0)
    168 {
    169     BlobRegistry::registerBlobData(m_uuid, BlobData::create());
    170 }
    171 
    172 BlobDataHandle::BlobDataHandle(PassOwnPtr<BlobData> data, long long size)
    173     : m_uuid(createCanonicalUUIDString())
    174     , m_type(data->contentType().isolatedCopy())
    175     , m_size(size)
    176 {
    177     BlobRegistry::registerBlobData(m_uuid, data);
    178 }
    179 
    180 BlobDataHandle::BlobDataHandle(const String& uuid, const String& type, long long size)
    181     : m_uuid(uuid.isolatedCopy())
    182     , m_type(type.isolatedCopy())
    183     , m_size(size)
    184 {
    185     BlobRegistry::addBlobDataRef(m_uuid);
    186 }
    187 
    188 BlobDataHandle::~BlobDataHandle()
    189 {
    190     BlobRegistry::removeBlobDataRef(m_uuid);
    191 }
    192 
    193 } // namespace blink
    194