15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_response.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 11ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 135e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/browser/appcache/appcache_storage.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/base/net_errors.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace content { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disk cache entry data indices. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kResponseInfoIndex, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kResponseContentIndex 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An IOBuffer that wraps a pickle's data. Ownership of the 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pickle is transfered to the WrappedPickleIOBuffer object. 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WrappedPickleIOBuffer : public net::WrappedIOBuffer { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit WrappedPickleIOBuffer(const Pickle* pickle) : 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::WrappedIOBuffer(reinterpret_cast<const char*>(pickle->data())), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle_(pickle) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pickle->data()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~WrappedPickleIOBuffer() {} 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<const Pickle> pickle_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anon namespace 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseInfo ---------------------------------------------- 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseInfo::AppCacheResponseInfo( 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) AppCacheStorage* storage, const GURL& manifest_url, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id, net::HttpResponseInfo* http_info, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_data_size) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : manifest_url_(manifest_url), response_id_(response_id), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_response_info_(http_info), response_data_size_(response_data_size), 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) storage_(storage) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(http_info); 58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK(response_id != kAppCacheNoResponseId); 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) storage_->working_set()->AddResponseInfo(this); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseInfo::~AppCacheResponseInfo() { 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) storage_->working_set()->RemoveResponseInfo(this); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HttpResponseInfoIOBuffer ------------------------------------------ 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer() 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : response_data_size(kUnkownResponseDataSize) {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::HttpResponseInfoIOBuffer(net::HttpResponseInfo* info) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : http_info(info), response_data_size(kUnkownResponseDataSize) {} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpResponseInfoIOBuffer::~HttpResponseInfoIOBuffer() {} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseIO ---------------------------------------------- 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseIO::AppCacheResponseIO( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : response_id_(response_id), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_id_(group_id), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) disk_cache_(disk_cache), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_(NULL), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len_(0), 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseIO::~AppCacheResponseIO() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_->Close(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::ScheduleIOCompletionCallback(int result) { 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&AppCacheResponseIO::OnIOComplete, 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), result)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::InvokeUserCompletionCallback(int result) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear the user callback and buffers prior to invoking the callback 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so the caller can schedule additional operations in the callback. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = NULL; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_ = NULL; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CompletionCallback cb = callback_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Reset(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cb.Run(result); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::ReadRaw(int index, int offset, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf, int buf_len) { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry_); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = entry_->Read( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index, offset, buf, buf_len, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheResponseIO::OnRawIOComplete, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(rv); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::WriteRaw(int index, int offset, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf, int buf_len) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry_); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = entry_->Write( 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) index, offset, buf, buf_len, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheResponseIO::OnRawIOComplete, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr())); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(rv); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseIO::OnRawIOComplete(int result) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(net::ERR_IO_PENDING, result); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnIOComplete(result); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseReader ---------------------------------------------- 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseReader::AppCacheResponseReader( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : AppCacheResponseIO(response_id, group_id, disk_cache), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_offset_(0), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_length_(kint32max), 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_(0), 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseReader::~AppCacheResponseReader() { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ReadInfo(HttpResponseInfoIOBuffer* info_buf, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsReadPending()); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_buf); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!info_buf->http_info.get()); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!buffer_.get()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!info_buffer_.get()); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_ = info_buf; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; // cleared on completion 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenEntryIfNeededAndContinue(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ContinueReadInfo() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry_) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = entry_->GetSize(kResponseInfoIndex); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (size <= 0) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = new net::IOBuffer(size); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadRaw(kResponseInfoIndex, 0, buffer_.get(), size); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ReadData(net::IOBuffer* buf, int buf_len, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsReadPending()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf_len >= 0); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!buffer_.get()); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!info_buffer_.get()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = buf; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len_ = buf_len; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; // cleared on completion 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpenEntryIfNeededAndContinue(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::ContinueReadData() { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry_) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(net::ERR_CACHE_MISS); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (read_position_ + buffer_len_ > range_length_) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(michaeln): What about integer overflows? 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(range_length_ >= read_position_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_len_ = range_length_ - read_position_; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 207868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ReadRaw(kResponseContentIndex, 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) range_offset_ + read_position_, 209868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buffer_.get(), 210868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) buffer_len_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::SetReadRange(int offset, int length) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsReadPending() && !read_position_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_offset_ = offset; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) range_length_ = length; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OnIOComplete(int result) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result >= 0) { 221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (info_buffer_.get()) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Deserialize the http info structure, ensuring we got headers. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(buffer_->data(), result); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool response_truncated = false; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!info->InitFromPickle(pickle, &response_truncated) || 227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !info->headers.get()) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokeUserCompletionCallback(net::ERR_FAILED); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!response_truncated); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_->http_info.reset(info.release()); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Also return the size of the response body 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry_); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_->response_data_size = 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_->GetSize(kResponseContentIndex); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_position_ += result; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokeUserCompletionCallback(result); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OpenEntryIfNeededAndContinue() { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = net::OK; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!disk_cache_) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = net::ERR_FAILED; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ptr = new AppCacheDiskCacheInterface::Entry*; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_callback_ = 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheResponseReader::OnOpenEntryComplete, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = disk_cache_->OpenEntry(response_id_, entry_ptr, open_callback_); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnOpenEntryComplete(entry_ptr, rv); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseReader::OnOpenEntryComplete( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDiskCacheInterface::Entry** entry, int rv) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_buffer_.get() || buffer_.get()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!open_callback_.is_null()) { 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::OK) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(entry); 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = *entry; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open_callback_.Reset(); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 276868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (info_buffer_.get()) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueReadInfo(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueReadData(); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppCacheResponseWriter ---------------------------------------------- 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseWriter::AppCacheResponseWriter( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 response_id, int64 group_id, AppCacheDiskCacheInterface* disk_cache) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : AppCacheResponseIO(response_id, group_id, disk_cache), 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_size_(0), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_position_(0), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_amount_(0), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_(INITIAL_ATTEMPT), 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppCacheResponseWriter::~AppCacheResponseWriter() { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::WriteInfo( 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpResponseInfoIOBuffer* info_buf, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsWritePending()); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_buf); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_buf->http_info.get()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!buffer_.get()); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!info_buffer_.get()); 306868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(info_buf->http_info->headers.get()); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_ = info_buf; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; // cleared on completion 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateEntryIfNeededAndContinue(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::ContinueWriteInfo() { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry_) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(net::ERR_FAILED); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool kSkipTransientHeaders = true; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool kTruncated = false; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle* pickle = new Pickle; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_buffer_->http_info->Persist(pickle, kSkipTransientHeaders, kTruncated); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_amount_ = static_cast<int>(pickle->size()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = new WrappedPickleIOBuffer(pickle); // takes ownership of pickle 325868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WriteRaw(kResponseInfoIndex, 0, buffer_.get(), write_amount_); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::WriteData( 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IOBuffer* buf, int buf_len, const net::CompletionCallback& callback) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!IsWritePending()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(buf_len >= 0); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!buffer_.get()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!info_buffer_.get()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_ = buf; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_amount_ = buf_len; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_ = callback; // cleared on completion 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateEntryIfNeededAndContinue(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::ContinueWriteData() { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!entry_) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleIOCompletionCallback(net::ERR_FAILED); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WriteRaw( 349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kResponseContentIndex, write_position_, buffer_.get(), write_amount_); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::OnIOComplete(int result) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result >= 0) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(write_amount_ == result); 355868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!info_buffer_.get()) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) write_position_ += result; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info_size_ = result; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InvokeUserCompletionCallback(result); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::CreateEntryIfNeededAndContinue() { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDiskCacheInterface::Entry** entry_ptr = NULL; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (entry_) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_ = NO_ATTEMPT; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = net::OK; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!disk_cache_) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_ = NO_ATTEMPT; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = net::ERR_FAILED; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_ = INITIAL_ATTEMPT; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ptr = new AppCacheDiskCacheInterface::Entry*; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_callback_ = 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheResponseWriter::OnCreateEntryComplete, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = disk_cache_->CreateEntry(response_id_, entry_ptr, create_callback_); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCreateEntryComplete(entry_ptr, rv); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppCacheResponseWriter::OnCreateEntryComplete( 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDiskCacheInterface::Entry** entry, int rv) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(info_buffer_.get() || buffer_.get()); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (creation_phase_ == INITIAL_ATTEMPT) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::OK) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We may try to overwrite existing entries. 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_ = DOOM_EXISTING; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = disk_cache_->DoomEntry(response_id_, create_callback_); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCreateEntryComplete(NULL, rv); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (creation_phase_ == DOOM_EXISTING) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_phase_ = SECOND_ATTEMPT; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppCacheDiskCacheInterface::Entry** entry_ptr = 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AppCacheDiskCacheInterface::Entry*; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_callback_ = 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AppCacheResponseWriter::OnCreateEntryComplete, 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_factory_.GetWeakPtr(), base::Owned(entry_ptr)); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = disk_cache_->CreateEntry(response_id_, entry_ptr, create_callback_); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != net::ERR_IO_PENDING) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnCreateEntryComplete(entry_ptr, rv); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!create_callback_.is_null()) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv == net::OK) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry_ = *entry; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_callback_.Reset(); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 417868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (info_buffer_.get()) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueWriteInfo(); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContinueWriteData(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} // namespace content 424