| Index: chrome/browser/drive/drive_api_util.cc
|
| diff --git a/chrome/browser/drive/drive_api_util.cc b/chrome/browser/drive/drive_api_util.cc
|
| index 064f4a2d8740af5dc150982e12f84a2570fe56ca..d9da506be82e550ff013b9779bd8c61c6dbc52aa 100644
|
| --- a/chrome/browser/drive/drive_api_util.cc
|
| +++ b/chrome/browser/drive/drive_api_util.cc
|
| @@ -16,6 +16,9 @@
|
| #include "base/values.h"
|
| #include "google_apis/drive/drive_api_parser.h"
|
| #include "net/base/escape.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "storage/browser/blob/file_stream_reader.h"
|
| #include "third_party/re2/re2/re2.h"
|
| #include "url/gurl.h"
|
|
|
| @@ -40,6 +43,8 @@ const HostedDocumentKind kHostedDocumentKinds[] = {
|
|
|
| const char kUnknownHostedDocumentExtension[] = ".glink";
|
|
|
| +const int kMd5DigestBufferSize = 512 * 1024; // 512 kB.
|
| +
|
| } // namespace
|
|
|
| std::string EscapeQueryStringValue(const std::string& str) {
|
| @@ -131,8 +136,6 @@ std::string CanonicalizeResourceId(const std::string& resource_id) {
|
| }
|
|
|
| std::string GetMd5Digest(const base::FilePath& file_path) {
|
| - const int kBufferSize = 512 * 1024; // 512kB.
|
| -
|
| base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
|
| if (!file.IsValid())
|
| return std::string();
|
| @@ -141,9 +144,9 @@ std::string GetMd5Digest(const base::FilePath& file_path) {
|
| base::MD5Init(&context);
|
|
|
| int64 offset = 0;
|
| - scoped_ptr<char[]> buffer(new char[kBufferSize]);
|
| + scoped_ptr<char[]> buffer(new char[kMd5DigestBufferSize]);
|
| while (true) {
|
| - int result = file.Read(offset, buffer.get(), kBufferSize);
|
| + int result = file.Read(offset, buffer.get(), kMd5DigestBufferSize);
|
| if (result < 0) {
|
| // Found an error.
|
| return std::string();
|
| @@ -163,6 +166,54 @@ std::string GetMd5Digest(const base::FilePath& file_path) {
|
| return MD5DigestToBase16(digest);
|
| }
|
|
|
| +FileStreamMd5Digester::FileStreamMd5Digester()
|
| + : buffer_(new net::IOBuffer(kMd5DigestBufferSize)) {
|
| +}
|
| +
|
| +FileStreamMd5Digester::~FileStreamMd5Digester() {
|
| +}
|
| +
|
| +void FileStreamMd5Digester::GetMd5Digest(
|
| + scoped_ptr<storage::FileStreamReader> stream_reader,
|
| + const ResultCallback& callback) {
|
| + reader_ = stream_reader.Pass();
|
| + callback_ = callback;
|
| + base::MD5Init(&md5_context_);
|
| +
|
| + // Start the read/hash.
|
| + ReadNextChunk();
|
| +}
|
| +
|
| +void FileStreamMd5Digester::ReadNextChunk() {
|
| + const int result = reader_->Read(
|
| + buffer_.get(), kMd5DigestBufferSize,
|
| + base::Bind(&FileStreamMd5Digester::OnChunkRead, base::Unretained(this)));
|
| + if (result != net::ERR_IO_PENDING) {
|
| + OnChunkRead(result);
|
| + }
|
| +}
|
| +
|
| +void FileStreamMd5Digester::OnChunkRead(int result) {
|
| + if (result < 0) {
|
| + // Error - just return empty string.
|
| + callback_.Run("");
|
| + return;
|
| + } else if (result == 0) {
|
| + // EOF.
|
| + base::MD5Digest digest;
|
| + base::MD5Final(&digest, &md5_context_);
|
| + std::string result = MD5DigestToBase16(digest);
|
| + callback_.Run(result);
|
| + return;
|
| + }
|
| +
|
| + // Read data and digest it.
|
| + base::MD5Update(&md5_context_, base::StringPiece(buffer_->data(), result));
|
| +
|
| + // Kick off the next read.
|
| + ReadNextChunk();
|
| +}
|
| +
|
| std::string GetHostedDocumentExtension(const std::string& mime_type) {
|
| for (size_t i = 0; i < arraysize(kHostedDocumentKinds); ++i) {
|
| if (mime_type == kHostedDocumentKinds[i].mime_type)
|
|
|