summaryrefslogtreecommitdiff
path: root/chromium/webkit/common/data_element.h
blob: f93960ba1bdf3a7394f7066d377f12dea3c3688c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_COMMON_DATA_ELEMENT_H_
#define WEBKIT_COMMON_DATA_ELEMENT_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/time/time.h"
#include "url/gurl.h"
#include "webkit/common/webkit_common_export.h"

namespace webkit_common {

// Represents a base Web data element. This could be either one of
// bytes, file or blob data.
class WEBKIT_COMMON_EXPORT DataElement {
 public:
  enum Type {
    TYPE_UNKNOWN = -1,
    TYPE_BYTES,
    TYPE_FILE,
    TYPE_BLOB,
    TYPE_FILE_FILESYSTEM,
  };

  DataElement();
  ~DataElement();

  Type type() const { return type_; }
  const char* bytes() const { return bytes_ ? bytes_ : &buf_[0]; }
  const base::FilePath& path() const { return path_; }
  const GURL& filesystem_url() const { return filesystem_url_; }

  // TODO(michaeln): crbug/174200, fully switch to using string uuids.
  // Note: Identifying blobs by url is being deprecated, but while
  // transitioning, there's a little of both going on in the project.
  const std::string& blob_uuid() const { return blob_uuid_; }
  const GURL& blob_url() const { return blob_url_; }
  uint64 offset() const { return offset_; }
  uint64 length() const { return length_; }
  const base::Time& expected_modification_time() const {
    return expected_modification_time_;
  }

  // Sets TYPE_BYTES data. This copies the given data into the element.
  void SetToBytes(const char* bytes, int bytes_len) {
    type_ = TYPE_BYTES;
    buf_.assign(bytes, bytes + bytes_len);
    length_ = buf_.size();
  }

  // Sets TYPE_BYTES data. This does NOT copy the given data and the caller
  // should make sure the data is alive when this element is accessed.
  void SetToSharedBytes(const char* bytes, int bytes_len) {
    type_ = TYPE_BYTES;
    bytes_ = bytes;
    length_ = bytes_len;
  }

  // Sets TYPE_FILE data.
  void SetToFilePath(const base::FilePath& path) {
    SetToFilePathRange(path, 0, kuint64max, base::Time());
  }

  // Sets TYPE_BLOB data.
  void SetToBlobUrl(const GURL& blob_url) {
    SetToBlobUrlRange(blob_url, 0, kuint64max);
  }
  void SetToBlob(const std::string& uuid) {
    SetToBlobRange(uuid, 0, kuint64max);
  }

  // Sets TYPE_FILE data with range.
  void SetToFilePathRange(const base::FilePath& path,
                          uint64 offset, uint64 length,
                          const base::Time& expected_modification_time);

  // Sets TYPE_BLOB data with range.
  void SetToBlobUrlRange(const GURL& blob_url,
                         uint64 offset, uint64 length);
  void SetToBlobRange(const std::string& blob_uuid,
                      uint64 offset, uint64 length);

  // Sets TYPE_FILE_FILESYSTEM with range.
  void SetToFileSystemUrlRange(const GURL& filesystem_url,
                               uint64 offset, uint64 length,
                               const base::Time& expected_modification_time);

 private:
  Type type_;
  std::vector<char> buf_;  // For TYPE_BYTES.
  const char* bytes_;  // For TYPE_BYTES.
  base::FilePath path_;  // For TYPE_FILE.
  GURL filesystem_url_;  // For TYPE_FILE_FILESYSTEM.
  GURL blob_url_;
  std::string blob_uuid_;
  uint64 offset_;
  uint64 length_;
  base::Time expected_modification_time_;
};

#if defined(UNIT_TEST)
inline bool operator==(const DataElement& a, const DataElement& b) {
  if (a.type() != b.type() ||
      a.offset() != b.offset() ||
      a.length() != b.length())
    return false;
  switch (a.type()) {
    case DataElement::TYPE_BYTES:
      return memcmp(a.bytes(), b.bytes(), b.length()) == 0;
    case DataElement::TYPE_FILE:
      return a.path() == b.path() &&
             a.expected_modification_time() == b.expected_modification_time();
    case DataElement::TYPE_BLOB:
      return a.blob_uuid().empty() ? (a.blob_url() == b.blob_url())
                                   : (a.blob_uuid() == b.blob_uuid());
    case DataElement::TYPE_FILE_FILESYSTEM:
      return a.filesystem_url() == b.filesystem_url();
    case DataElement::TYPE_UNKNOWN:
      NOTREACHED();
      return false;
  }
  return false;
}

inline bool operator!=(const DataElement& a, const DataElement& b) {
  return !(a == b);
}
#endif  // defined(UNIT_TEST)

}  // namespace webkit_common

#endif  // WEBKIT_COMMON_DATA_ELEMENT_H_