Class: Protocol::Media::Range
- Inherits:
-
Object
- Object
- Protocol::Media::Range
- Defined in:
- lib/protocol/media/range.rb
Overview
A media range and its parameters.
Direct Known Subclasses
Constant Summary collapse
- TOKEN =
/[!#$%&'*+\-.^_`|~0-9A-Z]+/i- QUOTED_STRING =
/"(?:.(?!(?<!\\)"))*.?"/- MEDIA_TYPE =
/(?<type>#{TOKEN})\/(?<subtype>#{TOKEN})/- PARAMETER =
/\s*;\s*(?<key>#{TOKEN})=((?<value>#{TOKEN})|(?<quoted_value>#{QUOTED_STRING}))/
Instance Attribute Summary collapse
-
#parameters ⇒ Object
readonly
Returns the value of attribute parameters.
-
#subtype ⇒ Object
readonly
Returns the value of attribute subtype.
- #The subtype, e.g. `plain` or `*`.(subtype, e.g.`plain`) ⇒ Object readonly
- #The top-level type, e.g. `text` or `*`.(top-leveltype, e.g.`text`) ⇒ Object readonly
-
#type ⇒ Object
readonly
Returns the value of attribute type.
Class Method Summary collapse
-
.build(type, subtype = "*", parameters = {}) ⇒ Object
Build a normalized media range.
-
.for(value) ⇒ Object
Parse strings into media ranges while preserving compatible objects.
-
.parse(text, normalize_whitespace = true) ⇒ Object
Parse a media range.
-
.parse_parameters(scanner, normalize_whitespace = true) ⇒ Object
Parse media type parameters from the scanner.
- .unquote(value, normalize_whitespace) ⇒ Object
Instance Method Summary collapse
-
#eql?(other) ⇒ Boolean
(also: #==)
Compare this media range with another media range.
-
#freeze ⇒ Object
Freeze the media range and its direct values.
-
#hash ⇒ Object
Generate a hash key consistent with #eql?.
-
#initialize(type, subtype = "*", parameters = {}) ⇒ Range
constructor
A new instance of Range.
-
#match?(media_range) ⇒ Boolean
(also: #===)
Whether this range matches the given media type or range.
-
#name ⇒ Object
(also: #mime_type)
The complete media range name.
- #The media range parameters.=(mediarangeparameters. = (value)) ⇒ Object
-
#to_s ⇒ Object
(also: #to_str)
Convert the media range and parameters to a string.
Constructor Details
#initialize(type, subtype = "*", parameters = {}) ⇒ Range
Returns a new instance of Range.
107 108 109 110 111 |
# File 'lib/protocol/media/range.rb', line 107 def initialize(type, subtype = "*", parameters = {}) @type = type @subtype = subtype @parameters = parameters end |
Instance Attribute Details
#parameters ⇒ Object (readonly)
Returns the value of attribute parameters.
102 103 104 |
# File 'lib/protocol/media/range.rb', line 102 def parameters @parameters end |
#subtype ⇒ Object (readonly)
Returns the value of attribute subtype.
99 100 101 |
# File 'lib/protocol/media/range.rb', line 99 def subtype @subtype end |
#The subtype, e.g. `plain` or `*`.(subtype, e.g.`plain`) ⇒ Object (readonly)
99 |
# File 'lib/protocol/media/range.rb', line 99 attr_reader :subtype |
#The top-level type, e.g. `text` or `*`.(top-leveltype, e.g.`text`) ⇒ Object (readonly)
96 |
# File 'lib/protocol/media/range.rb', line 96 attr_reader :type |
#type ⇒ Object (readonly)
Returns the value of attribute type.
96 97 98 |
# File 'lib/protocol/media/range.rb', line 96 def type @type end |
Class Method Details
.build(type, subtype = "*", parameters = {}) ⇒ Object
Build a normalized media range.
25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/protocol/media/range.rb', line 25 def self.build(type, subtype = "*", parameters = {}) type = type.downcase subtype = subtype.downcase # A wildcard type requires a wildcard subtype: if type == "*" if subtype != "*" raise ArgumentError, "Invalid wildcards in media range: #{type}/#{subtype}" end end return new(type, subtype, parameters) end |
.for(value) ⇒ Object
Parse strings into media ranges while preserving compatible objects.
43 44 45 46 47 48 49 |
# File 'lib/protocol/media/range.rb', line 43 def self.for(value) if value.is_a?(String) parse(value) else value end end |
.parse(text, normalize_whitespace = true) ⇒ Object
Parse a media range.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/protocol/media/range.rb', line 56 def self.parse(text, normalize_whitespace = true) scanner = StringScanner.new(text) unless scanner.scan(MEDIA_TYPE) raise ArgumentError, "Invalid media range: #{text.inspect}" end type = scanner[:type] subtype = scanner[:subtype] parameters = parse_parameters(scanner, normalize_whitespace) unless scanner.eos? raise ArgumentError, "Invalid media range: #{text.inspect}" end return build(type, subtype, parameters) end |
.parse_parameters(scanner, normalize_whitespace = true) ⇒ Object
Parse media type parameters from the scanner.
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/protocol/media/range.rb', line 79 def self.parse_parameters(scanner, normalize_whitespace = true) parameters = {} while scanner.scan(PARAMETER) key = scanner[:key] if value = scanner[:value] parameters[key] = value elsif quoted_value = scanner[:quoted_value] parameters[key] = unquote(quoted_value, normalize_whitespace) end end parameters end |
.unquote(value, normalize_whitespace) ⇒ Object
197 198 199 200 201 202 |
# File 'lib/protocol/media/range.rb', line 197 def self.unquote(value, normalize_whitespace) value = value[1...-1] value.gsub!(/\\(.)/, '\\1') value.gsub!(/[\r\n]+\s+/, " ") if normalize_whitespace value end |
Instance Method Details
#eql?(other) ⇒ Boolean Also known as: ==
Compare this media range with another media range.
169 170 171 |
# File 'lib/protocol/media/range.rb', line 169 def eql?(other) other.instance_of?(self.class) && @type.eql?(other.type) && @subtype.eql?(other.subtype) && @parameters.eql?(other.parameters) end |
#freeze ⇒ Object
Freeze the media range and its direct values.
135 136 137 138 139 140 141 142 143 |
# File 'lib/protocol/media/range.rb', line 135 def freeze return self if frozen? @type.freeze @subtype.freeze @parameters.freeze return super end |
#hash ⇒ Object
Generate a hash key consistent with #eql?.
178 179 180 |
# File 'lib/protocol/media/range.rb', line 178 def hash [self.class, @type, @subtype, @parameters].hash end |
#match?(media_range) ⇒ Boolean Also known as: ===
Whether this range matches the given media type or range.
149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/protocol/media/range.rb', line 149 def match?(media_range) # Both type components must be compatible: unless component_match?(@type, media_range.type) return false end # Both subtype components must be compatible: unless component_match?(@subtype, media_range.subtype) return false end return true end |
#name ⇒ Object Also known as: mime_type
The complete media range name.
116 117 118 |
# File 'lib/protocol/media/range.rb', line 116 def name "#{@type}/#{@subtype}" end |
#The media range parameters.=(mediarangeparameters. = (value)) ⇒ Object
102 |
# File 'lib/protocol/media/range.rb', line 102 attr_reader :parameters |
#to_s ⇒ Object Also known as: to_str
Convert the media range and parameters to a string.
125 126 127 128 129 |
# File 'lib/protocol/media/range.rb', line 125 def to_s name + @parameters.collect do |key, value| "; #{key}=#{quote(value.to_s)}" end.join end |