• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
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/format_macros.h"
8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h"
10 #include "net/http/http_byte_range.h"
11 
12 namespace {
13 
14 const int64 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       has_computed_bounds_(false) {
25 }
26 
27 // static
Bounded(int64 first_byte_position,int64 last_byte_position)28 HttpByteRange HttpByteRange::Bounded(int64 first_byte_position,
29                                      int64 last_byte_position) {
30   HttpByteRange range;
31   range.set_first_byte_position(first_byte_position);
32   range.set_last_byte_position(last_byte_position);
33   return range;
34 }
35 
36 // static
RightUnbounded(int64 first_byte_position)37 HttpByteRange HttpByteRange::RightUnbounded(int64 first_byte_position) {
38   HttpByteRange range;
39   range.set_first_byte_position(first_byte_position);
40   return range;
41 }
42 
43 // static
Suffix(int64 suffix_length)44 HttpByteRange HttpByteRange::Suffix(int64 suffix_length) {
45   HttpByteRange range;
46   range.set_suffix_length(suffix_length);
47   return range;
48 }
49 
IsSuffixByteRange() const50 bool HttpByteRange::IsSuffixByteRange() const {
51   return suffix_length_ != kPositionNotSpecified;
52 }
53 
HasFirstBytePosition() const54 bool HttpByteRange::HasFirstBytePosition() const {
55   return first_byte_position_ != kPositionNotSpecified;
56 }
57 
HasLastBytePosition() const58 bool HttpByteRange::HasLastBytePosition() const {
59   return last_byte_position_ != kPositionNotSpecified;
60 }
61 
IsValid() const62 bool HttpByteRange::IsValid() const {
63   if (suffix_length_ > 0)
64     return true;
65   return (first_byte_position_ >= 0 &&
66           (last_byte_position_ == kPositionNotSpecified ||
67            last_byte_position_ >= first_byte_position_));
68 }
69 
GetHeaderValue() const70 std::string HttpByteRange::GetHeaderValue() const {
71   DCHECK(IsValid());
72 
73   if (IsSuffixByteRange())
74     return base::StringPrintf("bytes=-%" PRId64, suffix_length());
75 
76   DCHECK(HasFirstBytePosition());
77 
78   if (!HasLastBytePosition())
79     return base::StringPrintf("bytes=%" PRId64 "-", first_byte_position());
80 
81   return base::StringPrintf("bytes=%" PRId64 "-%" PRId64,
82                             first_byte_position(), last_byte_position());
83 }
84 
ComputeBounds(int64 size)85 bool HttpByteRange::ComputeBounds(int64 size) {
86   if (size < 0)
87     return false;
88   if (has_computed_bounds_)
89     return false;
90   has_computed_bounds_ = true;
91 
92   // Empty values.
93   if (!HasFirstBytePosition() &&
94       !HasLastBytePosition() &&
95       !IsSuffixByteRange()) {
96     first_byte_position_ = 0;
97     last_byte_position_ = size - 1;
98     return true;
99   }
100   if (!IsValid())
101     return false;
102   if (IsSuffixByteRange()) {
103     first_byte_position_ = size - std::min(size, suffix_length_);
104     last_byte_position_ = size - 1;
105     return true;
106   }
107   if (first_byte_position_ < size) {
108     if (HasLastBytePosition())
109       last_byte_position_ = std::min(size - 1, last_byte_position_);
110     else
111       last_byte_position_ = size - 1;
112     return true;
113   }
114   return false;
115 }
116 
117 }  // namespace net
118