WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
36903
Implement BlobBuilder internal class for BlobBuilder support as defined in FileWriter
https://bugs.webkit.org/show_bug.cgi?id=36903
Summary
Implement BlobBuilder internal class for BlobBuilder support as defined in Fi...
Kinuko Yasuda
Reported
2010-03-31 15:18:44 PDT
Split from
bug 36568
. Implement c++ BlobBuilder object for BlobBuilder interface support defined in FileWriter spec. The spec is:
http://dev.w3.org/2009/dap/file-system/file-writer.html
Attachments
Patch
(20.69 KB, patch)
2010-03-31 16:38 PDT
,
Kinuko Yasuda
no flags
Details
Formatted Diff
Diff
Patch (rebased)
(20.63 KB, patch)
2010-03-31 17:03 PDT
,
Kinuko Yasuda
no flags
Details
Formatted Diff
Diff
Patch
(32.80 KB, patch)
2010-04-02 11:43 PDT
,
Kinuko Yasuda
no flags
Details
Formatted Diff
Diff
Patch
(17.65 KB, patch)
2010-06-09 10:51 PDT
,
Kinuko Yasuda
no flags
Details
Formatted Diff
Diff
Patch
(17.47 KB, patch)
2010-06-10 15:02 PDT
,
Kinuko Yasuda
no flags
Details
Formatted Diff
Diff
Patch
(17.65 KB, patch)
2010-06-11 16:19 PDT
,
Kinuko Yasuda
jianli
: review+
Details
Formatted Diff
Diff
Show Obsolete
(5)
View All
Add attachment
proposed patch, testcase, etc.
Kinuko Yasuda
Comment 1
2010-03-31 16:38:44 PDT
Created
attachment 52223
[details]
Patch
Kinuko Yasuda
Comment 2
2010-03-31 17:03:26 PDT
Created
attachment 52227
[details]
Patch (rebased)
Kent Tamura
Comment 3
2010-04-01 00:11:17 PDT
Comment on
attachment 52227
[details]
Patch (rebased)
> diff --git a/WebCore/html/BlobBuilder.cpp b/WebCore/html/BlobBuilder.cpp > new file mode 100644 > index 0000000..c076180 > --- /dev/null > +++ b/WebCore/html/BlobBuilder.cpp > +typedef HashMap<String, BlobBuilder::EndingsType, CaseFoldingHash> EndingsTypeMap; > +static const EndingsTypeMap* createEndingsTypeMap() > +{ > + EndingsTypeMap* map = new EndingsTypeMap; > + map->add("transparent", BlobBuilder::ENDING_TRANSPARENT); > + map->add("native", BlobBuilder::ENDING_NATIVE); > + map->add("lf", BlobBuilder::ENDING_LF); > + map->add("cr", BlobBuilder::ENDING_CR); > + map->add("crlf", BlobBuilder::ENDING_CRLF);
Are all the "endings" strings fixed? If so, we had better use AtomicString instead of String. AtomicString is faster in comparing instances.
> +String BlobBuilder::endings() const > +{ > + switch (m_endings) { > + case ENDING_TRANSPARENT: return "transparent"; > + case ENDING_NATIVE: return "native"; > + case ENDING_LF: return "lf"; > + case ENDING_CR: return "cr"; > + case ENDING_CRLF: return "crlf"; > + } > + ASSERT_NOT_REACHED(); > + return "transparent";
ditto. AtomicString is better.
> diff --git a/WebCore/html/ByteStore.h b/WebCore/html/ByteStore.h > new file mode 100644 > index 0000000..c1a99cf > --- /dev/null > +++ b/WebCore/html/ByteStore.h > + // Reads the data into |out| at most |maxLength| bytes. > + int64_t read(char* out, size_t offset, size_t maxLength) const; > + > + // Appends raw data |in|. Returns false if the data could not be added. > + bool append(const char* in, size_t length);
WebKit doesn't have |parameter| notation.
Dmitry Titov
Comment 4
2010-04-01 18:29:50 PDT
Comment on
attachment 52227
[details]
Patch (rebased) General comment: it seems you are taking the path of converting the parts appended by append() method to ByteStore immediately and synchronously on append(). This will have 2 undesired effects: 1. Converting strings happen right away, while the result may not even be used at the end. 2. When you will need to implement append(FileBlob) you will need to fetch the file data immediately, because it can come between 2 append(String) calls 3. When someone appends an bunch of Strings and then changes Blob.endings, those strings will have to be re-appended, which is multiple work. I'm not sure how it will even work with the FileBlobs in the mix. It seems the Blob should simply contain a list of all appended items, and delay the actual conversions to the end usage point. this way, perhaps you will never even need ByteStore object - indeed, the Blob could just implement read(...) method by walking the list and converting/filling the provided buffer in 'on demand' fashion. I mentioned in the webkit-dev discussion and still think that introducing ByteStore will eventually make Blob.append(FileBlob) a read-file-right-now operation... And if we don't read/combine anything until absolutely necessary, we shouldn't have to need ByteStore, at least in this explicit form. r- because strings can not be converted/merged right in the append(String) method, due to reasons above.
Kinuko Yasuda
Comment 5
2010-04-02 11:42:42 PDT
(In reply to
comment #4
)
> (From update of
attachment 52227
[details]
) > General comment: it seems you are taking the path of converting the parts > appended by append() method to ByteStore immediately and synchronously on > append(). This will have 2 undesired effects:
For append(Blob) I was/am going to put them into a list and wasn't going to read them immediately, but I was missing the point that BlobBuilder.endings may be changed after Strings are added. In the spec there's a notion that BlobBuilder.append(string) may throw encoding exceptions, so I had assumed append(string) does some conversion right away. (Actually I think we can drop this part as we now do not have encoding parameters in BlobBuilder.) It makes me wonder when we should really convert the strings; 1. BlobBuilder.append, 2. BlobBuilder.getBlob or 3. when we read Blob. 1. is not efficient as you suggested, but I think we will want some raw data at 2., because Blob.size and Blob.slice seem to be byte-based methods/operations. Does this sound correct? I'm attaching a new patch that do not convert Strings into ByteStore at append() but at getBlob() timing. This time I'm including changes in Blob too to give more overview.
Kinuko Yasuda
Comment 6
2010-04-02 11:43:13 PDT
Created
attachment 52429
[details]
Patch
Dmitry Titov
Comment 7
2010-04-09 23:53:42 PDT
It is much better now. Thanks for iterating on it! I don't think it can go in in this form, but added code definitely added some clarity. A few points: It seems converting strings at getBlob time is just fine indeed, for the reasons you mentioned. Obviously, we'll not want to do the same for file fragments but it's not in this patch. Looking at the patch, I think we can make what you have as CombinedBlob to be the only type of the blob... A Blob. It would be always a list of BlobItems. A BlobItem would be an abstract class, with implementations like FileBlobItem, StringBlobItem, ByteArrayBlobItem.When File derives from the Blob, such Blob would only have 1 FielBlobitem in the list... StringBlobItem would be the one constructed from string and stored in a mutable list of BlobBuilder. Once BlobBuilder::getBlob() (it probably should be createBlob()) is called, the new list created, with FileBlobItems just copied, and StringBlobItems replaced with ByteArrayBlobItems, with encoding and current endings attached. BTW, why do we need to make all Blobs (or BlobItems, if we'll have them) ThreadSafeShared? I suspect it's because of the FileThread? It would be unfortunate, since it would slow down cases when FileThread is not in the picture (building a blob and sending it via XHR does not require thread safety). Also, and it may be a bigger issue, it is unclear to me what is the story about BlobBuilder and FormData. They feel almost identical objects. It seems we might want to have one of those 'lists of blobs builders'.
Kinuko Yasuda
Comment 8
2010-04-27 18:43:18 PDT
Thanks for your comments. Let me update with the current status. (In reply to
comment #7
)
> Looking at the patch, I think we can make what you have as CombinedBlob to be > the only type of the blob... A Blob. It would be always a list of BlobItems. A > BlobItem would be an abstract class, with implementations like FileBlobItem, > StringBlobItem, ByteArrayBlobItem.When File derives from the Blob, such Blob > would only have 1 FielBlobitem in the list... StringBlobItem would be the one > constructed from string and stored in a mutable list of BlobBuilder. Once > BlobBuilder::getBlob() (it probably should be createBlob()) is called, the new > list created, with FileBlobItems just copied, and StringBlobItems replaced with > ByteArrayBlobItems, with encoding and current endings attached.
I've started to make those changes with an attempt to refactor BlobBuilder and FormData. In my local tree I'm trying / have tried to: - move most of Blob implementation into BlobItems and make Blob a simple collection of BlobItems. - File would be a special Blob that contains only one FileBlobItem. - BlobBuilder would be a very lightweight class as well. - refactor FormDataList::Item and FormDataElement as a wrapper of BlobItem. This makes appending Blobs to FormData much simpler (it can just pass a list of BlobItems). For now I'm trying to make them keep the same interface as before to avoid refactoring in platform-dependent code. The changes are still rough but I want to get some feedbacks in a design aspect before I go too far. How do they sound to you? Fyi my current patch is uploaded at:
http://codereview.chromium.org/1769002
> BTW, why do we need to make all Blobs (or BlobItems, if we'll have them) > ThreadSafeShared? I suspect it's because of the FileThread?
No, we won't need it to be ThreadSafeShared. When I wrote the initial patch I wasn't very sure but in the current design it'll be ok without making it ThreadSafeShared (at least for FileReader/Writer usage).
Kinuko Yasuda
Comment 9
2010-06-09 10:51:45 PDT
Created
attachment 58260
[details]
Patch
Kinuko Yasuda
Comment 10
2010-06-09 10:54:55 PDT
Uploaded a new patch for BlobBuilder based on BlobItem.
Jian Li
Comment 11
2010-06-09 14:59:18 PDT
Comment on
attachment 58260
[details]
Patch WebCore/html/Blob.h:74 + Blob(const String& type, const BlobItemList& items); 'items' can be omitted. WebCore/html/Blob.cpp:94 + return Blob::create(contentType, items); // FIXME: Pass content type when we add it to slice's arguments. return Blob::create(String(), items); WebCore/html/BlobBuilder.cpp:39 + #include "StringHash.h" Is this include needed? WebCore/html/BlobBuilder.cpp:41 + #include <wtf/HashMap.h> Is this include needed? WebCore/html/BlobBuilder.cpp:81 + if (!blob) Probably it is simpler to say: if (blob) for (...) ... return true; WebCore/html/BlobBuilder.h:37 + #include "ExceptionCode.h" Including ExceptionCode.h is not needed. WebCore/html/BlobBuilder.h:51 + bool appendString(const WebCore::String& text, const WebCore::String& ending, ExceptionCode& ec); The namespace WebCore is not necessary. WebCore/html/BlobBuilder.h:54 + PassRefPtr<Blob> getBlob(const WebCore::String& contentType) const; ditto. WebCore/platform/BlobItem.cpp:135 + #else How about CR in mac?
Kinuko Yasuda
Comment 12
2010-06-10 15:02:50 PDT
Created
attachment 58416
[details]
Patch
Kinuko Yasuda
Comment 13
2010-06-10 15:10:06 PDT
(In reply to
comment #11
)
> (From update of
attachment 58260
[details]
) > WebCore/html/Blob.h:74 > + Blob(const String& type, const BlobItemList& items); > 'items' can be omitted.
Done.
> WebCore/html/Blob.cpp:94 > + return Blob::create(contentType, items); > // FIXME: Pass content type when we add it to slice's arguments. > return Blob::create(String(), items);
Done. Accordingly changed the Blob::create's first param const String& -> const String (its implementation is just a RefPtr).
> WebCore/html/BlobBuilder.cpp:39 > + #include "StringHash.h" > + #include <wtf/HashMap.h>
Removed both includes.
> WebCore/html/BlobBuilder.cpp:81 > + if (!blob) > Probably it is simpler to say: > if (blob) > for (...) > ... > return true;
Fixed.
> WebCore/html/BlobBuilder.h:37 > + #include "ExceptionCode.h" > Including ExceptionCode.h is not needed.
Fixed.
> WebCore/html/BlobBuilder.h:51 > + bool appendString(const WebCore::String& text, const WebCore::String& ending, ExceptionCode& ec); > The namespace WebCore is not necessary.
Fixed.
> + PassRefPtr<Blob> getBlob(const WebCore::String& contentType) const; > ditto.
Fixed.
> WebCore/platform/BlobItem.cpp:135 > + #else > How about CR in mac?
Is older Mac supported by WebKit?
Jian Li
Comment 14
2010-06-11 15:56:28 PDT
Comment on
attachment 58416
[details]
Patch Some more comments. WebCore/html/Blob.h:44 + static PassRefPtr<Blob> create(const String type, const BlobItemList& items) "const String" in create() is inconsistent with "const String&" in Blob(). WebCore/html/Blob.h:73 + Blob() { } Is this needed? WebCore/html/BlobBuilder.h:40 + #include <wtf/Vector.h> This seems not to be needed. WebCore/html/BlobBuilder.h:57 + BlobBuilder(); We do not really need this default constructor.
Kinuko Yasuda
Comment 15
2010-06-11 16:19:35 PDT
Created
attachment 58523
[details]
Patch
Kinuko Yasuda
Comment 16
2010-06-11 16:35:44 PDT
(In reply to
comment #14
)
> (From update of
attachment 58416
[details]
) > Some more comments. > > WebCore/html/Blob.h:44 > + static PassRefPtr<Blob> create(const String type, const BlobItemList& items) > "const String" in create() is inconsistent with "const String&" in Blob().
Fixed.
> WebCore/html/Blob.h:73 > + Blob() { } > WebCore/html/BlobBuilder.h:40 > + #include <wtf/Vector.h> > WebCore/html/BlobBuilder.h:57 > + BlobBuilder();
Removed them.
Jian Li
Comment 17
2010-06-11 17:13:20 PDT
Comment on
attachment 58523
[details]
Patch r=me
Kinuko Yasuda
Comment 18
2010-06-14 14:41:26 PDT
Committed
r61149
: <
http://trac.webkit.org/changeset/61149
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug