15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2009 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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/format_macros.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringprintf.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_byte_range.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kPositionNotSpecified = -1;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpByteRange::HttpByteRange()
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : first_byte_position_(kPositionNotSpecified),
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_byte_position_(kPositionNotSpecified),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      suffix_length_(kPositionNotSpecified),
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      has_computed_bounds_(false) {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)HttpByteRange HttpByteRange::Bounded(int64 first_byte_position,
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                     int64 last_byte_position) {
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HttpByteRange range;
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  range.set_first_byte_position(first_byte_position);
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  range.set_last_byte_position(last_byte_position);
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return range;
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)HttpByteRange HttpByteRange::RightUnbounded(int64 first_byte_position) {
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HttpByteRange range;
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  range.set_first_byte_position(first_byte_position);
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return range;
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// static
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)HttpByteRange HttpByteRange::Suffix(int64 suffix_length) {
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  HttpByteRange range;
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  range.set_suffix_length(suffix_length);
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return range;
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpByteRange::IsSuffixByteRange() const {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return suffix_length_ != kPositionNotSpecified;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpByteRange::HasFirstBytePosition() const {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return first_byte_position_ != kPositionNotSpecified;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpByteRange::HasLastBytePosition() const {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return last_byte_position_ != kPositionNotSpecified;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpByteRange::IsValid() const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (suffix_length_ > 0)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (first_byte_position_ >= 0 &&
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (last_byte_position_ == kPositionNotSpecified ||
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           last_byte_position_ >= first_byte_position_));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string HttpByteRange::GetHeaderValue() const {
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(IsValid());
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (IsSuffixByteRange())
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return base::StringPrintf("bytes=-%" PRId64, suffix_length());
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(HasFirstBytePosition());
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!HasLastBytePosition())
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return base::StringPrintf("bytes=%" PRId64 "-", first_byte_position());
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return base::StringPrintf("bytes=%" PRId64 "-%" PRId64,
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            first_byte_position(), last_byte_position());
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpByteRange::ComputeBounds(int64 size) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (size < 0)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (has_computed_bounds_)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  has_computed_bounds_ = true;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Empty values.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!HasFirstBytePosition() &&
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !HasLastBytePosition() &&
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !IsSuffixByteRange()) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    first_byte_position_ = 0;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_byte_position_ = size - 1;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsValid())
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (IsSuffixByteRange()) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    first_byte_position_ = size - std::min(size, suffix_length_);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_byte_position_ = size - 1;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (first_byte_position_ < size) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (HasLastBytePosition())
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_byte_position_ = std::min(size - 1, last_byte_position_);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_byte_position_ = size - 1;
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
118