xref: /aosp_15_r20/external/cronet/net/http/http_byte_range.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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