1 // Copyright 2009 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <algorithm>
6
7 #include "base/check.h"
8 #include "base/format_macros.h"
9 #include "base/strings/stringprintf.h"
10 #include "net/http/http_byte_range.h"
11
12 namespace {
13
14 const int64_t kPositionNotSpecified = -1;
15
16 } // namespace
17
18 namespace net {
19
HttpByteRange()20 HttpByteRange::HttpByteRange()
21 : first_byte_position_(kPositionNotSpecified),
22 last_byte_position_(kPositionNotSpecified),
23 suffix_length_(kPositionNotSpecified) {}
24
25 // static
Bounded(int64_t first_byte_position,int64_t last_byte_position)26 HttpByteRange HttpByteRange::Bounded(int64_t first_byte_position,
27 int64_t last_byte_position) {
28 HttpByteRange range;
29 range.set_first_byte_position(first_byte_position);
30 range.set_last_byte_position(last_byte_position);
31 return range;
32 }
33
34 // static
RightUnbounded(int64_t first_byte_position)35 HttpByteRange HttpByteRange::RightUnbounded(int64_t first_byte_position) {
36 HttpByteRange range;
37 range.set_first_byte_position(first_byte_position);
38 return range;
39 }
40
41 // static
Suffix(int64_t suffix_length)42 HttpByteRange HttpByteRange::Suffix(int64_t suffix_length) {
43 HttpByteRange range;
44 range.set_suffix_length(suffix_length);
45 return range;
46 }
47
IsSuffixByteRange() const48 bool HttpByteRange::IsSuffixByteRange() const {
49 return suffix_length_ != kPositionNotSpecified;
50 }
51
HasFirstBytePosition() const52 bool HttpByteRange::HasFirstBytePosition() const {
53 return first_byte_position_ != kPositionNotSpecified;
54 }
55
HasLastBytePosition() const56 bool HttpByteRange::HasLastBytePosition() const {
57 return last_byte_position_ != kPositionNotSpecified;
58 }
59
IsValid() const60 bool HttpByteRange::IsValid() const {
61 if (suffix_length_ > 0)
62 return true;
63 return (first_byte_position_ >= 0 &&
64 (last_byte_position_ == kPositionNotSpecified ||
65 last_byte_position_ >= first_byte_position_));
66 }
67
GetHeaderValue() const68 std::string HttpByteRange::GetHeaderValue() const {
69 DCHECK(IsValid());
70
71 if (IsSuffixByteRange())
72 return base::StringPrintf("bytes=-%" PRId64, suffix_length());
73
74 DCHECK(HasFirstBytePosition());
75
76 if (!HasLastBytePosition())
77 return base::StringPrintf("bytes=%" PRId64 "-", first_byte_position());
78
79 return base::StringPrintf("bytes=%" PRId64 "-%" PRId64,
80 first_byte_position(), last_byte_position());
81 }
82
ComputeBounds(int64_t size)83 bool HttpByteRange::ComputeBounds(int64_t size) {
84 if (size < 0)
85 return false;
86 if (has_computed_bounds_)
87 return false;
88 has_computed_bounds_ = true;
89
90 // Empty values.
91 if (!HasFirstBytePosition() &&
92 !HasLastBytePosition() &&
93 !IsSuffixByteRange()) {
94 first_byte_position_ = 0;
95 last_byte_position_ = size - 1;
96 return true;
97 }
98 if (!IsValid())
99 return false;
100 if (IsSuffixByteRange()) {
101 first_byte_position_ = size - std::min(size, suffix_length_);
102 last_byte_position_ = size - 1;
103 return true;
104 }
105 if (first_byte_position_ < size) {
106 if (HasLastBytePosition())
107 last_byte_position_ = std::min(size - 1, last_byte_position_);
108 else
109 last_byte_position_ = size - 1;
110 return true;
111 }
112 return false;
113 }
114
115 } // namespace net
116