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)
5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#define WEBKIT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/completion_callback.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_info.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "webkit/browser/webkit_storage_browser_export.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/common/appcache/appcache_interfaces.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IOBuffer;
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace appcache {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppCacheService;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kUnkownResponseDataSize = -1;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Response info for a particular response id. Instances are tracked in
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the working set.
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheResponseInfo
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCounted<AppCacheResponseInfo> {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AppCacheResponseInfo takes ownership of the http_info.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseInfo(AppCacheService* service, const GURL& manifest_url,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int64 response_id, net::HttpResponseInfo* http_info,
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       int64 response_data_size);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL& manifest_url() const { return manifest_url_; }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 response_id() const { return response_id_; }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const net::HttpResponseInfo* http_response_info() const {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return http_response_info_.get();
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 response_data_size() const { return response_data_size_; }
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<AppCacheResponseInfo>;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheResponseInfo();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL manifest_url_;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 response_id_;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const scoped_ptr<net::HttpResponseInfo> http_response_info_;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 response_data_size_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const AppCacheService* service_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A refcounted wrapper for HttpResponseInfo so we can apply the
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// refcounting semantics used with IOBuffer with these structures too.
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)struct WEBKIT_STORAGE_BROWSER_EXPORT HttpResponseInfoIOBuffer
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public base::RefCountedThreadSafe<HttpResponseInfoIOBuffer> {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::HttpResponseInfo> http_info;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_data_size;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HttpResponseInfoIOBuffer();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit HttpResponseInfoIOBuffer(net::HttpResponseInfo* info);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCountedThreadSafe<HttpResponseInfoIOBuffer>;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~HttpResponseInfoIOBuffer();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Low level storage API used by the response reader and writer.
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheDiskCacheInterface {
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class Entry {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int Read(int index, int64 offset, net::IOBuffer* buf, int buf_len,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const net::CompletionCallback& callback) = 0;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int Write(int index, int64 offset, net::IOBuffer* buf, int buf_len,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const net::CompletionCallback& callback) = 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int64 GetSize(int index) = 0;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void Close() = 0;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~Entry() {}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int CreateEntry(int64 key, Entry** entry,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const net::CompletionCallback& callback) = 0;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int OpenEntry(int64 key, Entry** entry,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const net::CompletionCallback& callback) = 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual int DoomEntry(int64 key, const net::CompletionCallback& callback) = 0;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class base::RefCounted<AppCacheDiskCacheInterface>;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheDiskCacheInterface() {}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Common base class for response reader and writer.
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheResponseIO {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheResponseIO();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 response_id() const { return response_id_; }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseIO(int64 response_id,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int64 group_id,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     AppCacheDiskCacheInterface* disk_cache);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnIOComplete(int result) = 0;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsIOPending() { return !callback_.is_null(); }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ScheduleIOCompletionCallback(int result);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void InvokeUserCompletionCallback(int result);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ReadRaw(int index, int offset, net::IOBuffer* buf, int buf_len);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteRaw(int index, int offset, net::IOBuffer* buf, int buf_len);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 response_id_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int64 group_id_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheDiskCacheInterface* disk_cache_;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheDiskCacheInterface::Entry* entry_;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::IOBuffer> buffer_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int buffer_len_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback callback_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<AppCacheResponseIO> weak_factory_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnRawIOComplete(int result);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads existing response data from storage. If the object is deleted
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and there is a read in progress, the implementation will return
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately but will take care of any side effect of cancelling the
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation.  In other words, instances are safe to delete at will.
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheResponseReader
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public AppCacheResponseIO {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheResponseReader();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads http info from storage. Always returns the result of the read
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // asynchronously through the 'callback'. Returns the number of bytes read
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a net:: error code. Guaranteed to not perform partial reads of
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the info data. The reader acquires a reference to the 'info_buf' until
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // completion at which time the callback is invoked with either a negative
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error code or the number of bytes read. The 'info_buf' argument should
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // contain a NULL http_info when ReadInfo is called. The 'callback' is a
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // required parameter.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called where there is no Read operation in progress.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (virtual for testing)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const net::CompletionCallback& callback);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads data from storage. Always returns the result of the read
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // asynchronously through the 'callback'. Returns the number of bytes read
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a net:: error code. EOF is indicated with a return value of zero.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The reader acquires a reference to the provided 'buf' until completion
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at which time the callback is invoked with either a negative error code
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or the number of bytes read. The 'callback' is a required parameter.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called where there is no Read operation in progress.
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (virtual for testing)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ReadData(net::IOBuffer* buf, int buf_len,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const net::CompletionCallback& callback);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there is a read operation, for data or info, pending.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsReadPending() { return IsIOPending(); }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to support range requests. If not called, the reader will
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // read the entire response body. If called, this must be called prior
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to the first call to the ReadData method.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetReadRange(int offset, int length);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheStorageImpl;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class MockAppCacheStorage;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be constructed by the storage class.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseReader(int64 response_id,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int64 group_id,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         AppCacheDiskCacheInterface* disk_cache);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnIOComplete(int result) OVERRIDE;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueReadInfo();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueReadData();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OpenEntryIfNeededAndContinue();
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnOpenEntryComplete(AppCacheDiskCacheInterface::Entry** entry, int rv);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int range_offset_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int range_length_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int read_position_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback open_callback_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<AppCacheResponseReader> weak_factory_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Writes new response data to storage. If the object is deleted
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and there is a write in progress, the implementation will return
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// immediately but will take care of any side effect of cancelling the
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operation. In other words, instances are safe to delete at will.
1977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class WEBKIT_STORAGE_BROWSER_EXPORT AppCacheResponseWriter
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    : public AppCacheResponseIO {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppCacheResponseWriter();
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes the http info to storage. Always returns the result of the write
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // asynchronously through the 'callback'. Returns the number of bytes written
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a net:: error code. The writer acquires a reference to the 'info_buf'
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // until completion at which time the callback is invoked with either a
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // negative error code or the number of bytes written. The 'callback' is a
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // required parameter. The contents of 'info_buf' are not modified.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called where there is no Write operation in progress.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteInfo(HttpResponseInfoIOBuffer* info_buf,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const net::CompletionCallback& callback);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Writes data to storage. Always returns the result of the write
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // asynchronously through the 'callback'. Returns the number of bytes written
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or a net:: error code. Guaranteed to not perform partial writes.
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The writer acquires a reference to the provided 'buf' until completion at
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which time the callback is invoked with either a negative error code or
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the number of bytes written. The 'callback' is a required parameter.
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The contents of 'buf' are not modified.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be called where there is no Write operation in progress.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void WriteData(net::IOBuffer* buf, int buf_len,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 const net::CompletionCallback& callback);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if there is a write pending.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsWritePending() { return IsIOPending(); }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the amount written, info and data.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 amount_written() { return info_size_ + write_position_; }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class AppCacheStorageImpl;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class MockAppCacheStorage;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum CreationPhase {
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NO_ATTEMPT,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    INITIAL_ATTEMPT,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOOM_EXISTING,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SECOND_ATTEMPT
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should only be constructed by the storage class.
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCacheResponseWriter(int64 response_id,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         int64 group_id,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         AppCacheDiskCacheInterface* disk_cache);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnIOComplete(int result) OVERRIDE;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueWriteInfo();
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ContinueWriteData();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateEntryIfNeededAndContinue();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnCreateEntryComplete(AppCacheDiskCacheInterface::Entry** entry, int rv);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int info_size_;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int write_position_;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int write_amount_;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreationPhase creation_phase_;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::CompletionCallback create_callback_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<AppCacheResponseWriter> weak_factory_;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace appcache
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
261868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif  // WEBKIT_BROWSER_APPCACHE_APPCACHE_RESPONSE_H_
262