Renamed CONNEG to content_negotiation.
Update MIME_PARSER to use HTTP_MEDIA_TYPE.
This commit is contained in:
@@ -1,79 +0,0 @@
|
|||||||
#!/usr/bin/env ruby
|
|
||||||
# Niklaus Giger, 15.01.2011
|
|
||||||
# Small ruby-script run all tests using ec (the Eiffel compiler)
|
|
||||||
# we assumen that ec outputs everything in english!
|
|
||||||
|
|
||||||
# For the command line options look at
|
|
||||||
# http://docs.eiffel.com/book/eiffelstudio/eiffelstudio-command-line-options
|
|
||||||
# we use often the -batch open.
|
|
||||||
#
|
|
||||||
# TODO: Fix problems when compiling takes too long and/or there
|
|
||||||
# are ec process lingering around from a previous failed build
|
|
||||||
|
|
||||||
require 'tempfile'
|
|
||||||
require 'fileutils'
|
|
||||||
|
|
||||||
# Override system command.
|
|
||||||
# run command. if not successful, complain and exit with error
|
|
||||||
def system(cmd)
|
|
||||||
puts cmd
|
|
||||||
res = Kernel.system(cmd)
|
|
||||||
if !res
|
|
||||||
puts "Failed running: #{cmd}"
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def runTestForProject(where)
|
|
||||||
if !File.directory?(where)
|
|
||||||
puts "Directory #{where} does not exist"
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
|
|
||||||
# create a temporary file with input for the
|
|
||||||
# interactive mode of ec
|
|
||||||
commands2run=<<EOF
|
|
||||||
T
|
|
||||||
E
|
|
||||||
q
|
|
||||||
EOF
|
|
||||||
file = Tempfile.new('commands2run')
|
|
||||||
file.puts commands2run
|
|
||||||
file.close
|
|
||||||
|
|
||||||
Dir.chdir(where)
|
|
||||||
# First we have to remove old compilation
|
|
||||||
FileUtils.rm_rf("EIFGENs")
|
|
||||||
|
|
||||||
# compile the library
|
|
||||||
cmd = "ec -config library/emime-safe.ecf -target emime -batch -c_compile"
|
|
||||||
res = system(cmd)
|
|
||||||
|
|
||||||
# compile the test
|
|
||||||
cmd = "ec -config test/test-safe.ecf -target test -batch -c_compile"
|
|
||||||
res = system(cmd)
|
|
||||||
|
|
||||||
|
|
||||||
logFile = "#{__FILE__}.log"
|
|
||||||
sleep 1
|
|
||||||
cmd = "ec -config test/test-safe.ecf -target test -batch -loop 1>#{logFile} 2>#{__FILE__}.auto_test_output <#{file.path}"
|
|
||||||
res = system(cmd)
|
|
||||||
m= nil
|
|
||||||
IO.readlines(logFile).each{
|
|
||||||
|line|
|
|
||||||
m = /(\d+) tests total \((\d+) executed, (\d+) failing, (\d+) unresolved/.match(line)
|
|
||||||
break if m
|
|
||||||
}
|
|
||||||
|
|
||||||
puts
|
|
||||||
if m[3].to_i == 0 and m[4].to_i == 0 then
|
|
||||||
puts "#{m[1]} tests completed successfully"
|
|
||||||
else
|
|
||||||
puts "Failures while running #{m[1]} failed. #{m[2]} executed #{m[3]} failures #{m[4]} unresolved"
|
|
||||||
exit 2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
runTestForProject(Dir.pwd)
|
|
||||||
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {CHARACTER_ENCODING_VARIANT_RESULTS}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
CHARACTER_ENCODING_VARIANT_RESULTS
|
|
||||||
feature
|
|
||||||
character_type : detachable STRING
|
|
||||||
set_character_type ( a_character_type: STRING)
|
|
||||||
do
|
|
||||||
character_type := a_character_type
|
|
||||||
ensure
|
|
||||||
set_character_type : a_character_type ~ character_type
|
|
||||||
end
|
|
||||||
|
|
||||||
variant_header : detachable STRING
|
|
||||||
set_variant_header
|
|
||||||
do
|
|
||||||
variant_header := "Accept-Charset"
|
|
||||||
end
|
|
||||||
|
|
||||||
supported_variants : detachable LIST[STRING]
|
|
||||||
set_supported_variants (a_supported : LIST[STRING])
|
|
||||||
do
|
|
||||||
supported_variants := a_supported
|
|
||||||
ensure
|
|
||||||
set_supported_variants : supported_variants = a_supported
|
|
||||||
end
|
|
||||||
|
|
||||||
is_acceptable : BOOLEAN
|
|
||||||
|
|
||||||
set_acceptable ( acceptable : BOOLEAN)
|
|
||||||
do
|
|
||||||
is_acceptable := acceptable
|
|
||||||
ensure
|
|
||||||
is_acceptable = acceptable
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {COMPRESSION_VARIANT_RESULTS}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
COMPRESSION_VARIANT_RESULTS
|
|
||||||
|
|
||||||
feature
|
|
||||||
compression_type : detachable STRING
|
|
||||||
set_compression_type ( a_compression_type: STRING)
|
|
||||||
do
|
|
||||||
compression_type := a_compression_type
|
|
||||||
ensure
|
|
||||||
set_compression_type : a_compression_type ~ compression_type
|
|
||||||
end
|
|
||||||
|
|
||||||
variant_header : detachable STRING
|
|
||||||
set_variant_header
|
|
||||||
do
|
|
||||||
variant_header := "Accept-Encoding"
|
|
||||||
end
|
|
||||||
|
|
||||||
supported_variants : detachable LIST[STRING]
|
|
||||||
set_supported_variants (a_supported : LIST[STRING])
|
|
||||||
do
|
|
||||||
supported_variants := a_supported
|
|
||||||
ensure
|
|
||||||
set_supported_variants : supported_variants = a_supported
|
|
||||||
end
|
|
||||||
|
|
||||||
is_acceptable : BOOLEAN
|
|
||||||
|
|
||||||
set_acceptable ( acceptable : BOOLEAN)
|
|
||||||
do
|
|
||||||
is_acceptable := acceptable
|
|
||||||
ensure
|
|
||||||
is_acceptable = acceptable
|
|
||||||
end
|
|
||||||
note
|
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {LANGUAGE_VARIANT_RESULTS}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
LANGUAGE_VARIANT_RESULTS
|
|
||||||
|
|
||||||
feature
|
|
||||||
language_type : detachable STRING
|
|
||||||
set_language_type ( a_language_type: STRING)
|
|
||||||
do
|
|
||||||
language_type := a_language_type
|
|
||||||
ensure
|
|
||||||
set_language_type : a_language_type ~ language_type
|
|
||||||
end
|
|
||||||
|
|
||||||
variant_header : detachable STRING
|
|
||||||
set_variant_header
|
|
||||||
do
|
|
||||||
variant_header := "Accept-Language"
|
|
||||||
end
|
|
||||||
|
|
||||||
supported_variants : detachable LIST[STRING]
|
|
||||||
set_supported_variants (a_supported : LIST[STRING])
|
|
||||||
do
|
|
||||||
supported_variants := a_supported
|
|
||||||
ensure
|
|
||||||
set_supported_variants : supported_variants = a_supported
|
|
||||||
end
|
|
||||||
|
|
||||||
is_acceptable : BOOLEAN
|
|
||||||
|
|
||||||
set_acceptable ( acceptable : BOOLEAN)
|
|
||||||
do
|
|
||||||
is_acceptable := acceptable
|
|
||||||
ensure
|
|
||||||
is_acceptable = acceptable
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {MEDIA_TYPE_VARIANT_RESULTS}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
MEDIA_TYPE_VARIANT_RESULTS
|
|
||||||
|
|
||||||
feature
|
|
||||||
|
|
||||||
media_type : detachable STRING
|
|
||||||
set_media_type ( a_media_type: STRING)
|
|
||||||
do
|
|
||||||
media_type := a_media_type
|
|
||||||
ensure
|
|
||||||
set_media_type : a_media_type ~ media_type
|
|
||||||
end
|
|
||||||
|
|
||||||
variant_header : detachable STRING
|
|
||||||
set_variant_header
|
|
||||||
do
|
|
||||||
variant_header := "Accept"
|
|
||||||
end
|
|
||||||
|
|
||||||
supported_variants : detachable LIST[STRING]
|
|
||||||
set_supported_variants (a_supported : LIST[STRING])
|
|
||||||
do
|
|
||||||
supported_variants := a_supported
|
|
||||||
ensure
|
|
||||||
set_supported_variants : supported_variants = a_supported
|
|
||||||
end
|
|
||||||
|
|
||||||
is_acceptable : BOOLEAN
|
|
||||||
|
|
||||||
set_acceptable ( acceptable : BOOLEAN)
|
|
||||||
do
|
|
||||||
is_acceptable := acceptable
|
|
||||||
ensure
|
|
||||||
is_acceptable = acceptable
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
note
|
|
||||||
description: "Summary description for {VARIANT_RESULTS}."
|
|
||||||
author: ""
|
|
||||||
date: "$Date$"
|
|
||||||
revision: "$Revision$"
|
|
||||||
|
|
||||||
class
|
|
||||||
VARIANT_RESULTS
|
|
||||||
|
|
||||||
feature -- Mime, Language, Charset and Encoding Results
|
|
||||||
|
|
||||||
mime_result : detachable STRING
|
|
||||||
|
|
||||||
set_mime_result ( a_mime: STRING)
|
|
||||||
-- set the mime_result with `a_mime'
|
|
||||||
do
|
|
||||||
mime_result := a_mime
|
|
||||||
ensure
|
|
||||||
set_mime_result: a_mime ~ mime_result
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
language_result : detachable STRING
|
|
||||||
|
|
||||||
set_language_result (a_language : STRING)
|
|
||||||
-- set the language_result with `a_language'
|
|
||||||
do
|
|
||||||
language_result := a_language
|
|
||||||
ensure
|
|
||||||
set_language : a_language ~ language_result
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
charset_result : detachable STRING
|
|
||||||
|
|
||||||
set_charset_result (a_charset : STRING)
|
|
||||||
-- set the charset_result with `a_charset'
|
|
||||||
do
|
|
||||||
charset_result := a_charset
|
|
||||||
ensure
|
|
||||||
set_charset : a_charset ~ charset_result
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
encoding_result : detachable STRING
|
|
||||||
|
|
||||||
set_encoding_defautl (an_encoding : STRING)
|
|
||||||
do
|
|
||||||
encoding_result := an_encoding
|
|
||||||
ensure
|
|
||||||
set_encoding : an_encoding ~ encoding_result
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
note
|
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
||||||
end
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
<assertions precondition="true"/>
|
<assertions precondition="true"/>
|
||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="http" location="..\http\http-safe.ecf"/>
|
<library name="http" location="..\http\http-safe.ecf" readonly="false"/>
|
||||||
<cluster name="conneg" location=".\src\" recursive="true"/>
|
<cluster name="conneg" location=".\src\" recursive="true"/>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {CHARACTER_ENCODING_VARIANT_RESULTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
CHARACTER_ENCODING_VARIANT_RESULTS
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
character_type: detachable STRING
|
||||||
|
|
||||||
|
variant_header: detachable STRING
|
||||||
|
|
||||||
|
supported_variants: detachable LIST [STRING]
|
||||||
|
|
||||||
|
is_acceptable: BOOLEAN
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_character_type (a_character_type: STRING)
|
||||||
|
-- Set `character_type' with `a_character_type'
|
||||||
|
do
|
||||||
|
character_type := a_character_type
|
||||||
|
ensure
|
||||||
|
character_type_set: character_type /= Void implies a_character_type = character_type
|
||||||
|
end
|
||||||
|
|
||||||
|
set_variant_header
|
||||||
|
-- Set variant header as `Accept-Charset'
|
||||||
|
do
|
||||||
|
variant_header := "Accept-Charset"
|
||||||
|
ensure
|
||||||
|
variant_header_set: attached variant_header as l_variant_header implies l_variant_header.same_string ("Accept-Charset")
|
||||||
|
end
|
||||||
|
|
||||||
|
set_supported_variants (a_supported: LIST [STRING])
|
||||||
|
-- Set `supported_variants' with `a_supported'
|
||||||
|
do
|
||||||
|
supported_variants := a_supported
|
||||||
|
ensure
|
||||||
|
supported_variants_set: supported_variants /= Void implies supported_variants = a_supported
|
||||||
|
end
|
||||||
|
|
||||||
|
set_acceptable (acceptable: BOOLEAN)
|
||||||
|
-- Set `is_acceptable' with `acceptabe'
|
||||||
|
do
|
||||||
|
is_acceptable := acceptable
|
||||||
|
ensure
|
||||||
|
is_acceptable_set: is_acceptable = acceptable
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -3,17 +3,15 @@ note
|
|||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
description : "[
|
EIS: "name=Charset", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2", "protocol=uri"
|
||||||
Charset Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2
|
EIS: "name=Encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
||||||
Encoding Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
|
|
||||||
]"
|
|
||||||
|
|
||||||
class
|
class
|
||||||
COMMON_ACCEPT_HEADER_PARSER
|
COMMON_ACCEPT_HEADER_PARSER
|
||||||
|
|
||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
parse_common (header: STRING): COMMON_RESULTS
|
|
||||||
|
parse_common (header: STRING): COMMON_RESULTS
|
||||||
-- Parses `header' charset/encoding into its component parts.
|
-- Parses `header' charset/encoding into its component parts.
|
||||||
-- For example, the charset 'iso-8889-5' would get parsed
|
-- For example, the charset 'iso-8889-5' would get parsed
|
||||||
-- into:
|
-- into:
|
||||||
@@ -28,7 +26,7 @@ feature -- Parser
|
|||||||
create Result.make
|
create Result.make
|
||||||
l_parts := header.split (';')
|
l_parts := header.split (';')
|
||||||
if l_parts.count = 1 then
|
if l_parts.count = 1 then
|
||||||
Result.put ("1.0", "q")
|
Result.put ("1.0", "q")
|
||||||
else
|
else
|
||||||
from
|
from
|
||||||
i := 1
|
i := 1
|
||||||
@@ -38,16 +36,15 @@ feature -- Parser
|
|||||||
p := l_parts.at (i)
|
p := l_parts.at (i)
|
||||||
sub_parts := p.split ('=')
|
sub_parts := p.split ('=')
|
||||||
if sub_parts.count = 2 then
|
if sub_parts.count = 2 then
|
||||||
Result.put (trim (sub_parts[2]), trim (sub_parts[1]))
|
Result.put (trim (sub_parts [2]), trim (sub_parts [1]))
|
||||||
end
|
end
|
||||||
i := i + 1
|
i := i + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
l_header := trim (l_parts[1])
|
l_header := trim (l_parts [1])
|
||||||
Result.set_field (trim (l_header))
|
Result.set_field (trim (l_header))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
fitness_and_quality_parsed (a_field: STRING; parsed_charsets: LIST [COMMON_RESULTS]): FITNESS_AND_QUALITY
|
fitness_and_quality_parsed (a_field: STRING; parsed_charsets: LIST [COMMON_RESULTS]): FITNESS_AND_QUALITY
|
||||||
-- Find the best match for a given charset/encoding against a list of charsets/encodings
|
-- Find the best match for a given charset/encoding against a list of charsets/encodings
|
||||||
-- that have already been parsed by parse_common. Returns a
|
-- that have already been parsed by parse_common. Returns a
|
||||||
@@ -65,7 +62,7 @@ feature -- Parser
|
|||||||
do
|
do
|
||||||
best_fitness := -1
|
best_fitness := -1
|
||||||
best_fit_q := 0.0
|
best_fit_q := 0.0
|
||||||
target := parse_common(a_field)
|
target := parse_common (a_field)
|
||||||
if attached target.item ("q") as q and then q.is_double then
|
if attached target.item ("q") as q and then q.is_double then
|
||||||
target_q := q.to_double
|
target_q := q.to_double
|
||||||
if target_q < 0.0 then
|
if target_q < 0.0 then
|
||||||
@@ -76,9 +73,7 @@ feature -- Parser
|
|||||||
else
|
else
|
||||||
target_q := 1.0
|
target_q := 1.0
|
||||||
end
|
end
|
||||||
|
if attached target.field as l_target_field then
|
||||||
if attached target.field as l_target_field
|
|
||||||
then
|
|
||||||
from
|
from
|
||||||
parsed_charsets.start
|
parsed_charsets.start
|
||||||
until
|
until
|
||||||
@@ -86,7 +81,7 @@ feature -- Parser
|
|||||||
loop
|
loop
|
||||||
range := parsed_charsets.item_for_iteration
|
range := parsed_charsets.item_for_iteration
|
||||||
if attached range.field as l_range_common then
|
if attached range.field as l_range_common then
|
||||||
if l_target_field.same_string (l_range_common) or l_target_field.same_string ("*") or l_range_common.same_string ("*") then
|
if l_target_field.same_string (l_range_common) or l_target_field.same_string ("*") or l_range_common.same_string ("*") then
|
||||||
if l_range_common.same_string (l_target_field) then
|
if l_range_common.same_string (l_target_field) then
|
||||||
l_fitness := 100
|
l_fitness := 100
|
||||||
else
|
else
|
||||||
@@ -109,7 +104,6 @@ feature -- Parser
|
|||||||
create Result.make (best_fitness, best_fit_q)
|
create Result.make (best_fitness, best_fit_q)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
quality_parsed (a_field: STRING; parsed_common: LIST [COMMON_RESULTS]): REAL_64
|
quality_parsed (a_field: STRING; parsed_common: LIST [COMMON_RESULTS]): REAL_64
|
||||||
-- Find the best match for a given charset/encoding against a list of charsets/encodings that
|
-- Find the best match for a given charset/encoding against a list of charsets/encodings that
|
||||||
-- have already been parsed by parse_charsets(). Returns the 'q' quality
|
-- have already been parsed by parse_charsets(). Returns the 'q' quality
|
||||||
@@ -119,14 +113,13 @@ feature -- Parser
|
|||||||
Result := fitness_and_quality_parsed (a_field, parsed_common).quality
|
Result := fitness_and_quality_parsed (a_field, parsed_common).quality
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
quality (a_field: STRING; commons: STRING): REAL_64
|
quality (a_field: STRING; commons: STRING): REAL_64
|
||||||
-- Returns the quality 'q' of a charset/encoding when compared against the
|
-- Returns the quality 'q' of a charset/encoding when compared against the
|
||||||
-- a list of charsets/encodings/
|
-- a list of charsets/encodings/
|
||||||
local
|
local
|
||||||
l_commons : LIST [STRING]
|
l_commons: LIST [STRING]
|
||||||
res : ARRAYED_LIST [COMMON_RESULTS]
|
res: ARRAYED_LIST [COMMON_RESULTS]
|
||||||
p_res : COMMON_RESULTS
|
p_res: COMMON_RESULTS
|
||||||
do
|
do
|
||||||
l_commons := commons.split (',')
|
l_commons := commons.split (',')
|
||||||
from
|
from
|
||||||
@@ -153,8 +146,6 @@ feature -- Parser
|
|||||||
do
|
do
|
||||||
l_res := header.split (',')
|
l_res := header.split (',')
|
||||||
create {ARRAYED_LIST [COMMON_RESULTS]} l_header_results.make (l_res.count)
|
create {ARRAYED_LIST [COMMON_RESULTS]} l_header_results.make (l_res.count)
|
||||||
|
|
||||||
|
|
||||||
from
|
from
|
||||||
l_res.start
|
l_res.start
|
||||||
until
|
until
|
||||||
@@ -164,9 +155,7 @@ feature -- Parser
|
|||||||
l_header_results.force (p_res)
|
l_header_results.force (p_res)
|
||||||
l_res.forth
|
l_res.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (supported.count)
|
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (supported.count)
|
||||||
|
|
||||||
from
|
from
|
||||||
supported.start
|
supported.start
|
||||||
until
|
until
|
||||||
@@ -201,12 +190,16 @@ feature -- Parser
|
|||||||
end
|
end
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
end
|
end
|
||||||
check weighted_matches.item = fitness_and_quality end
|
check
|
||||||
|
weighted_matches.item = fitness_and_quality
|
||||||
|
end
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
elseif first_one.is_equal (fitness_and_quality) then
|
elseif first_one.is_equal (fitness_and_quality) then
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
else
|
else
|
||||||
check first_one > fitness_and_quality end
|
check
|
||||||
|
first_one > fitness_and_quality
|
||||||
|
end
|
||||||
weighted_matches.remove
|
weighted_matches.remove
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -228,14 +221,16 @@ feature -- Parser
|
|||||||
loop
|
loop
|
||||||
fitness_and_quality := weighted_matches.item
|
fitness_and_quality := weighted_matches.item
|
||||||
if fitness_and_quality.mime_type.same_string (l_field) then
|
if fitness_and_quality.mime_type.same_string (l_field) then
|
||||||
--| Found
|
--| Found
|
||||||
else
|
else
|
||||||
fitness_and_quality := Void
|
fitness_and_quality := Void
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
check has_field: False end
|
check
|
||||||
|
has_field: False
|
||||||
|
end
|
||||||
end
|
end
|
||||||
l_header_results.forth
|
l_header_results.forth
|
||||||
end
|
end
|
||||||
@@ -267,7 +262,7 @@ feature -- Util
|
|||||||
trim (a_string: STRING): STRING
|
trim (a_string: STRING): STRING
|
||||||
-- trim whitespace from the beginning and end of a string
|
-- trim whitespace from the beginning and end of a string
|
||||||
require
|
require
|
||||||
valid_argument : a_string /= Void
|
valid_argument: a_string /= Void
|
||||||
do
|
do
|
||||||
a_string.left_adjust
|
a_string.left_adjust
|
||||||
a_string.right_justify
|
a_string.right_justify
|
||||||
@@ -277,6 +272,7 @@ feature -- Util
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -6,7 +6,9 @@ note
|
|||||||
|
|
||||||
class
|
class
|
||||||
COMMON_RESULTS
|
COMMON_RESULTS
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
ANY
|
ANY
|
||||||
redefine
|
redefine
|
||||||
out
|
out
|
||||||
@@ -31,7 +33,6 @@ feature -- Access
|
|||||||
|
|
||||||
field: detachable STRING
|
field: detachable STRING
|
||||||
|
|
||||||
|
|
||||||
item (a_key: STRING): detachable STRING
|
item (a_key: STRING): detachable STRING
|
||||||
-- Item associated with `a_key', if present
|
-- Item associated with `a_key', if present
|
||||||
-- otherwise default value of type `STRING'
|
-- otherwise default value of type `STRING'
|
||||||
@@ -57,15 +58,14 @@ feature -- Access
|
|||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
set_field (a_field: STRING)
|
set_field (a_field: STRING)
|
||||||
-- Set type with `a_charset'
|
-- Set type with `a_charset'
|
||||||
do
|
do
|
||||||
field := a_field
|
field := a_field
|
||||||
ensure
|
ensure
|
||||||
field_assigned: field ~ field
|
field_assigned: field /= Void implies field = a_field
|
||||||
end
|
end
|
||||||
|
|
||||||
|
put (new: STRING; key: STRING)
|
||||||
put (new: STRING; key: STRING)
|
|
||||||
-- Insert `new' with `key' if there is no other item
|
-- Insert `new' with `key' if there is no other item
|
||||||
-- associated with the same key. If present, replace
|
-- associated with the same key. If present, replace
|
||||||
-- the old value with `new'
|
-- the old value with `new'
|
||||||
@@ -90,7 +90,6 @@ feature -- Status Report
|
|||||||
Result.append_string ("'" + t + "',")
|
Result.append_string ("'" + t + "',")
|
||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
|
|
||||||
from
|
from
|
||||||
params.start
|
params.start
|
||||||
until
|
until
|
||||||
@@ -113,7 +112,10 @@ feature {NONE} -- Implementation
|
|||||||
params: HASH_TABLE [STRING, STRING]
|
params: HASH_TABLE [STRING, STRING]
|
||||||
--dictionary of all the parameters for the media range
|
--dictionary of all the parameters for the media range
|
||||||
|
|
||||||
;note
|
;
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {COMPRESSION_VARIANT_RESULTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
EIS: "name= Compression", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
||||||
|
|
||||||
|
class
|
||||||
|
COMPRESSION_VARIANT_RESULTS
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
compression_type: detachable STRING
|
||||||
|
|
||||||
|
variant_header: detachable STRING
|
||||||
|
|
||||||
|
supported_variants: detachable LIST [STRING]
|
||||||
|
|
||||||
|
is_acceptable: BOOLEAN
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_compression_type (a_compression_type: STRING)
|
||||||
|
-- Set `compression_type' with `a_compression_type'
|
||||||
|
do
|
||||||
|
compression_type := a_compression_type
|
||||||
|
ensure
|
||||||
|
compression_type_set: compression_type /= Void implies a_compression_type = compression_type
|
||||||
|
end
|
||||||
|
|
||||||
|
set_variant_header
|
||||||
|
-- Set variant_header as `Accept-Encoding'
|
||||||
|
do
|
||||||
|
variant_header := "Accept-Encoding"
|
||||||
|
ensure
|
||||||
|
variant_header_set: attached variant_header as l_variant_header implies l_variant_header.same_string ("Accept-Encoding")
|
||||||
|
end
|
||||||
|
|
||||||
|
set_supported_variants (a_supported: LIST [STRING])
|
||||||
|
-- Set `supported_variants' with `a_supported'
|
||||||
|
do
|
||||||
|
supported_variants := a_supported
|
||||||
|
ensure
|
||||||
|
supported_variants_set: supported_variants /= Void implies supported_variants = a_supported
|
||||||
|
end
|
||||||
|
|
||||||
|
set_acceptable (acceptable: BOOLEAN)
|
||||||
|
-- Set `is_acceptable' with `acceptable'
|
||||||
|
do
|
||||||
|
is_acceptable := acceptable
|
||||||
|
ensure
|
||||||
|
is_acceptable_set: is_acceptable = acceptable
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -11,129 +11,154 @@ note
|
|||||||
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
Server-driven negotiation is advantageous when the algorithm for selecting from among the available representations is difficult to describe to the user agent,
|
||||||
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
or when the server desires to send its "best guess" to the client along with the first response (hoping to avoid the round-trip delay of a subsequent request if the "best guess" is good enough for the user).
|
||||||
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response.
|
||||||
]"
|
]"
|
||||||
|
EIS: "name=server driven negotiation", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec12.html#sec12.", "protocol=uri"
|
||||||
|
|
||||||
class
|
class
|
||||||
CONNEG_SERVER_SIDE
|
CONNEG_SERVER_SIDE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
SHARED_CONNEG
|
SHARED_CONNEG
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
create
|
create
|
||||||
make
|
make
|
||||||
|
|
||||||
feature -- Initialization
|
feature -- Initialization
|
||||||
make ( a_mime: STRING; a_language : STRING; a_charset :STRING; an_encoding: STRING)
|
|
||||||
|
make (a_mime: STRING; a_language: STRING; a_charset: STRING; a_encoding: STRING)
|
||||||
do
|
do
|
||||||
set_mime_default (a_mime)
|
set_mime_default (a_mime)
|
||||||
set_language_default (a_language)
|
set_language_default (a_language)
|
||||||
set_charset_default (a_charset)
|
set_charset_default (a_charset)
|
||||||
set_encoding_defautl (an_encoding)
|
set_encoding_default (a_encoding)
|
||||||
|
ensure
|
||||||
|
mime_default_set: mime = a_mime
|
||||||
|
language_default_set: language_default = a_language
|
||||||
|
charset_default_set: charset_default = a_charset
|
||||||
|
encoding_default_set: encoding_default = a_encoding
|
||||||
end
|
end
|
||||||
feature -- Server Side Defaults Formats
|
|
||||||
mime_default : STRING
|
|
||||||
|
|
||||||
set_mime_default ( a_mime: STRING)
|
feature -- AccessServer Side Defaults Formats
|
||||||
-- set the mime_default with `a_mime'
|
|
||||||
|
mime_default: STRING
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
language_default: STRING
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
charset_default: STRING
|
||||||
|
|
||||||
|
|
||||||
|
encoding_default: STRING
|
||||||
|
|
||||||
|
set_encoding_defautl (an_encoding: STRING)
|
||||||
|
do
|
||||||
|
encoding_default := an_encoding
|
||||||
|
ensure
|
||||||
|
set_encoding: an_encoding ~ encoding_default
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_mime_default (a_mime: STRING)
|
||||||
|
-- set the mime_default with `a_mime'
|
||||||
do
|
do
|
||||||
mime_default := a_mime
|
mime_default := a_mime
|
||||||
ensure
|
ensure
|
||||||
set_mime_default: a_mime ~ mime_default
|
set_mime_default: a_mime = mime_default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_language_default (a_language: STRING)
|
||||||
language_default : STRING
|
|
||||||
|
|
||||||
set_language_default (a_language : STRING)
|
|
||||||
-- set the language_default with `a_language'
|
-- set the language_default with `a_language'
|
||||||
do
|
do
|
||||||
language_default := a_language
|
language_default := a_language
|
||||||
ensure
|
ensure
|
||||||
set_language : a_language ~ language_default
|
set_language: a_language = language_default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_charset_default (a_charset: STRING)
|
||||||
charset_default : STRING
|
|
||||||
|
|
||||||
set_charset_default (a_charset : STRING)
|
|
||||||
-- set the charset_default with `a_charset'
|
-- set the charset_default with `a_charset'
|
||||||
do
|
do
|
||||||
charset_default := a_charset
|
charset_default := a_charset
|
||||||
ensure
|
ensure
|
||||||
set_charset : a_charset ~ charset_default
|
set_charset: a_charset = charset_default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_encoding_default (a_encoding: STRING)
|
||||||
encoding_default : STRING
|
|
||||||
|
|
||||||
set_encoding_defautl (an_encoding : STRING)
|
|
||||||
do
|
do
|
||||||
encoding_default := an_encoding
|
encoding_default := a_encoding
|
||||||
ensure
|
ensure
|
||||||
set_encoding : an_encoding ~ encoding_default
|
set_encoding: a_encoding = encoding_default
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
feature -- Media Type Negotiation
|
feature -- Media Type Negotiation
|
||||||
|
|
||||||
media_type_preference ( mime_types_supported : LIST[STRING]; header: detachable READABLE_STRING_8) : MEDIA_TYPE_VARIANT_RESULTS
|
media_type_preference (mime_types_supported: LIST [STRING]; header: detachable READABLE_STRING_8): MEDIA_TYPE_VARIANT_RESULTS
|
||||||
-- mime_types_supported represent media types supported by the server.
|
-- mime_types_supported represent media types supported by the server.
|
||||||
-- header represent the Accept header, ie, the client preferences.
|
-- header represent the Accept header, ie, the client preferences.
|
||||||
-- Return which media type to use for representaion in a response, if the server support
|
-- Return which media type to use for representaion in a response, if the server support
|
||||||
-- one media type, or empty in other case.
|
-- one media type, or empty in other case.
|
||||||
-- Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
note
|
||||||
|
EIS: "name=media type", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
||||||
local
|
local
|
||||||
mime_match: STRING
|
mime_match: STRING
|
||||||
do
|
do
|
||||||
create Result
|
create Result
|
||||||
if header = Void or else header.is_empty then
|
if header = Void or else header.is_empty then
|
||||||
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
||||||
Result.set_acceptable (TRUE)
|
Result.set_acceptable (TRUE)
|
||||||
Result.set_media_type (mime_default)
|
Result.set_media_type (mime_default)
|
||||||
else
|
else
|
||||||
-- select the best match, server support, client preferences
|
-- select the best match, server support, client preferences
|
||||||
mime_match := mime.best_match (mime_types_supported, header)
|
mime_match := mime.best_match (mime_types_supported, header)
|
||||||
if mime_match.is_empty then
|
if mime_match.is_empty then
|
||||||
-- The server does not support any of the media types prefered by the client
|
-- The server does not support any of the media types prefered by the client
|
||||||
Result.set_acceptable (False)
|
Result.set_acceptable (False)
|
||||||
Result.set_supported_variants (mime_types_supported)
|
Result.set_supported_variants (mime_types_supported)
|
||||||
else
|
else
|
||||||
-- Set the best match
|
-- Set the best match
|
||||||
Result.set_media_type(mime_match)
|
Result.set_media_type (mime_match)
|
||||||
Result.set_acceptable (True)
|
Result.set_acceptable (True)
|
||||||
Result.set_variant_header
|
Result.set_variant_header
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Encoding Negotiation
|
feature -- Encoding Negotiation
|
||||||
|
|
||||||
charset_preference (server_charset_supported : LIST[STRING]; header: detachable READABLE_STRING_8) : CHARACTER_ENCODING_VARIANT_RESULTS
|
charset_preference (server_charset_supported: LIST [STRING]; header: detachable READABLE_STRING_8): CHARACTER_ENCODING_VARIANT_RESULTS
|
||||||
-- server_charset_supported represent a list of charset supported by the server.
|
-- server_charset_supported represent a list of charset supported by the server.
|
||||||
-- header represent the Accept-Charset header, ie, the client preferences.
|
-- header represent the Accept-Charset header, ie, the client preferences.
|
||||||
-- Return which Charset to use in a response, if the server support
|
-- Return which Charset to use in a response, if the server support
|
||||||
-- one Charset, or empty in other case.
|
-- one Charset, or empty in other case.
|
||||||
-- Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2
|
note
|
||||||
|
EIS: "name=charset", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2", "protocol=uri"
|
||||||
local
|
local
|
||||||
charset_match : STRING
|
charset_match: STRING
|
||||||
do
|
do
|
||||||
create Result
|
create Result
|
||||||
if header = Void or else header.is_empty then
|
if header = Void or else header.is_empty then
|
||||||
-- the request has no Accept-Charset header, ie the header is empty, in this case use default charset encoding
|
-- the request has no Accept-Charset header, ie the header is empty, in this case use default charset encoding
|
||||||
-- (UTF-8)
|
-- (UTF-8)
|
||||||
Result.set_acceptable (TRUE)
|
Result.set_acceptable (TRUE)
|
||||||
Result.set_character_type (charset_default)
|
Result.set_character_type (charset_default)
|
||||||
else
|
else
|
||||||
-- select the best match, server support, client preferences
|
-- select the best match, server support, client preferences
|
||||||
charset_match := common.best_match (server_charset_supported, header)
|
charset_match := common.best_match (server_charset_supported, header)
|
||||||
if charset_match.is_empty then
|
if charset_match.is_empty then
|
||||||
-- The server does not support any of the compression types prefered by the client
|
-- The server does not support any of the compression types prefered by the client
|
||||||
Result.set_acceptable (False)
|
Result.set_acceptable (False)
|
||||||
Result.set_supported_variants (server_charset_supported)
|
Result.set_supported_variants (server_charset_supported)
|
||||||
else
|
else
|
||||||
-- Set the best match
|
-- Set the best match
|
||||||
Result.set_character_type(charset_match)
|
Result.set_character_type (charset_match)
|
||||||
Result.set_acceptable (True)
|
Result.set_acceptable (True)
|
||||||
Result.set_variant_header
|
Result.set_variant_header
|
||||||
end
|
end
|
||||||
@@ -142,75 +167,74 @@ feature -- Encoding Negotiation
|
|||||||
|
|
||||||
feature -- Compression Negotiation
|
feature -- Compression Negotiation
|
||||||
|
|
||||||
encoding_preference (server_encoding_supported : LIST[STRING]; header: detachable READABLE_STRING_8) : COMPRESSION_VARIANT_RESULTS
|
encoding_preference (server_encoding_supported: LIST [STRING]; header: detachable READABLE_STRING_8): COMPRESSION_VARIANT_RESULTS
|
||||||
-- server_encoding_supported represent a list of encoding supported by the server.
|
-- server_encoding_supported represent a list of encoding supported by the server.
|
||||||
-- header represent the Accept-Encoding header, ie, the client preferences.
|
-- header represent the Accept-Encoding header, ie, the client preferences.
|
||||||
-- Return which Encoding to use in a response, if the server support
|
-- Return which Encoding to use in a response, if the server support
|
||||||
-- one Encoding, or empty in other case.
|
-- one Encoding, or empty in other case.
|
||||||
-- Representation: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
|
note
|
||||||
|
EIS: "name=encoding", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3", "protocol=uri"
|
||||||
local
|
local
|
||||||
compression_match : STRING
|
compression_match: STRING
|
||||||
do
|
do
|
||||||
create Result
|
create Result
|
||||||
if header = Void or else header.is_empty then
|
if header = Void or else header.is_empty then
|
||||||
-- the request has no Accept-Encoding header, ie the header is empty, in this case do not compress representations
|
-- the request has no Accept-Encoding header, ie the header is empty, in this case do not compress representations
|
||||||
Result.set_acceptable (TRUE)
|
Result.set_acceptable (TRUE)
|
||||||
Result.set_compression_type (encoding_default)
|
Result.set_compression_type (encoding_default)
|
||||||
else
|
else
|
||||||
-- select the best match, server support, client preferences
|
-- select the best match, server support, client preferences
|
||||||
compression_match := common.best_match (server_encoding_supported, header)
|
compression_match := common.best_match (server_encoding_supported, header)
|
||||||
if compression_match.is_empty then
|
if compression_match.is_empty then
|
||||||
-- The server does not support any of the compression types prefered by the client
|
-- The server does not support any of the compression types prefered by the client
|
||||||
Result.set_acceptable (False)
|
Result.set_acceptable (False)
|
||||||
Result.set_supported_variants (server_encoding_supported)
|
Result.set_supported_variants (server_encoding_supported)
|
||||||
else
|
else
|
||||||
-- Set the best match
|
-- Set the best match
|
||||||
Result.set_compression_type(compression_match)
|
Result.set_compression_type (compression_match)
|
||||||
Result.set_acceptable (True)
|
Result.set_acceptable (True)
|
||||||
Result.set_variant_header
|
Result.set_variant_header
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
feature -- Language Negotiation
|
feature -- Language Negotiation
|
||||||
|
|
||||||
language_preference (server_language_supported : LIST[STRING]; header: detachable READABLE_STRING_8) : LANGUAGE_VARIANT_RESULTS
|
language_preference (server_language_supported: LIST [STRING]; header: detachable READABLE_STRING_8): LANGUAGE_VARIANT_RESULTS
|
||||||
-- server_language_supported represent a list of languages supported by the server.
|
-- server_language_supported represent a list of languages supported by the server.
|
||||||
-- header represent the Accept-Language header, ie, the client preferences.
|
-- header represent the Accept-Language header, ie, the client preferences.
|
||||||
-- Return which Language to use in a response, if the server support
|
-- Return which Language to use in a response, if the server support
|
||||||
-- one Language, or empty in other case.
|
-- one Language, or empty in other case.
|
||||||
-- Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
|
note
|
||||||
|
EIS: "name=language", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4", "protocol=uri"
|
||||||
|
|
||||||
local
|
local
|
||||||
language_match: STRING
|
language_match: STRING
|
||||||
do
|
do
|
||||||
create Result
|
create Result
|
||||||
if header = Void or else header.is_empty then
|
if header = Void or else header.is_empty then
|
||||||
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
-- the request has no Accept header, ie the header is empty, in this case we use the default format
|
||||||
Result.set_acceptable (TRUE)
|
Result.set_acceptable (TRUE)
|
||||||
Result.set_language_type (language_default)
|
Result.set_language_type (language_default)
|
||||||
else
|
else
|
||||||
-- select the best match, server support, client preferences
|
-- select the best match, server support, client preferences
|
||||||
language_match := language.best_match (server_language_supported, header)
|
language_match := language.best_match (server_language_supported, header)
|
||||||
if language_match.is_empty then
|
if language_match.is_empty then
|
||||||
-- The server does not support any of the media types prefered by the client
|
-- The server does not support any of the media types prefered by the client
|
||||||
Result.set_acceptable (False)
|
Result.set_acceptable (False)
|
||||||
Result.set_supported_variants (server_language_supported)
|
Result.set_supported_variants (server_language_supported)
|
||||||
else
|
else
|
||||||
-- Set the best match
|
-- Set the best match
|
||||||
Result.set_language_type(language_match)
|
Result.set_language_type (language_match)
|
||||||
Result.set_acceptable (True)
|
Result.set_acceptable (True)
|
||||||
Result.set_variant_header
|
Result.set_variant_header
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Apache Conneg Algorithm
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -3,11 +3,13 @@ note
|
|||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
description : "Language Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4"
|
description: "Language Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4"
|
||||||
|
|
||||||
class
|
class
|
||||||
LANGUAGE_PARSE
|
LANGUAGE_PARSE
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
REFACTORING_HELPER
|
REFACTORING_HELPER
|
||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
@@ -36,23 +38,23 @@ feature -- Parser
|
|||||||
p := l_parts.at (i)
|
p := l_parts.at (i)
|
||||||
sub_parts := p.split ('=')
|
sub_parts := p.split ('=')
|
||||||
if sub_parts.count = 2 then
|
if sub_parts.count = 2 then
|
||||||
Result.put (trim (sub_parts[2]), trim (sub_parts[1]))
|
Result.put (trim (sub_parts [2]), trim (sub_parts [1]))
|
||||||
end
|
end
|
||||||
i := i + 1
|
i := i + 1
|
||||||
end
|
end
|
||||||
--Java URLConnection class sends an Accept header that includes a
|
--Java URLConnection class sends an Accept header that includes a
|
||||||
--single "*" - Turn it into a legal wildcard.
|
--single "*" - Turn it into a legal wildcard.
|
||||||
|
|
||||||
l_full_type := trim (l_parts[1])
|
l_full_type := trim (l_parts [1])
|
||||||
if l_full_type.same_string ("*") then
|
if l_full_type.same_string ("*") then
|
||||||
l_full_type := "*"
|
l_full_type := "*"
|
||||||
end
|
end
|
||||||
l_types := l_full_type.split ('-')
|
l_types := l_full_type.split ('-')
|
||||||
if l_types.count = 1 then
|
if l_types.count = 1 then
|
||||||
Result.set_type (trim (l_types[1]))
|
Result.set_type (trim (l_types [1]))
|
||||||
else
|
else
|
||||||
Result.set_type (trim (l_types[1]))
|
Result.set_type (trim (l_types [1]))
|
||||||
Result.set_sub_type (trim (l_types[2]))
|
Result.set_sub_type (trim (l_types [2]))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -67,12 +69,8 @@ feature -- Parser
|
|||||||
fixme ("Improve the code!!!")
|
fixme ("Improve the code!!!")
|
||||||
Result := parse_mime_type (a_range)
|
Result := parse_mime_type (a_range)
|
||||||
if attached Result.item ("q") as q then
|
if attached Result.item ("q") as q then
|
||||||
if
|
if q.is_double and then attached {REAL_64} q.to_double as r and then (r >= 0.0 and r <= 1.0) then
|
||||||
q.is_double and then
|
--| Keep current value
|
||||||
attached {REAL_64} q.to_double as r and then
|
|
||||||
(r >= 0.0 and r <= 1.0)
|
|
||||||
then
|
|
||||||
--| Keep current value
|
|
||||||
if q.same_string ("1") then
|
if q.same_string ("1") then
|
||||||
--| Use 1.0 formatting
|
--| Use 1.0 formatting
|
||||||
Result.put ("1.0", "q")
|
Result.put ("1.0", "q")
|
||||||
@@ -85,7 +83,6 @@ feature -- Parser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
fitness_and_quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [LANGUAGE_RESULTS]): FITNESS_AND_QUALITY
|
fitness_and_quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [LANGUAGE_RESULTS]): FITNESS_AND_QUALITY
|
||||||
-- Find the best match for a given mimeType against a list of media_ranges
|
-- Find the best match for a given mimeType against a list of media_ranges
|
||||||
-- that have already been parsed by parse_media_range. Returns a
|
-- that have already been parsed by parse_media_range. Returns a
|
||||||
@@ -116,22 +113,14 @@ feature -- Parser
|
|||||||
else
|
else
|
||||||
target_q := 1.0
|
target_q := 1.0
|
||||||
end
|
end
|
||||||
|
if attached target.type as l_target_type then
|
||||||
if
|
|
||||||
attached target.type as l_target_type
|
|
||||||
then
|
|
||||||
from
|
from
|
||||||
parsed_ranges.start
|
parsed_ranges.start
|
||||||
until
|
until
|
||||||
parsed_ranges.after
|
parsed_ranges.after
|
||||||
loop
|
loop
|
||||||
range := parsed_ranges.item_for_iteration
|
range := parsed_ranges.item_for_iteration
|
||||||
if
|
if (attached range.type as l_range_type and then (l_target_type.same_string (l_range_type) or l_range_type.same_string ("*") or l_target_type.same_string ("*"))) then
|
||||||
(
|
|
||||||
attached range.type as l_range_type and then
|
|
||||||
(l_target_type.same_string (l_range_type) or l_range_type.same_string ("*") or l_target_type.same_string ("*"))
|
|
||||||
)
|
|
||||||
then
|
|
||||||
from
|
from
|
||||||
param_matches := 0
|
param_matches := 0
|
||||||
keys := target.keys
|
keys := target.keys
|
||||||
@@ -140,33 +129,22 @@ feature -- Parser
|
|||||||
keys.after
|
keys.after
|
||||||
loop
|
loop
|
||||||
element := keys.item_for_iteration
|
element := keys.item_for_iteration
|
||||||
if
|
if not element.same_string ("q") and then range.has_key (element) and then (attached target.item (element) as t_item and attached range.item (element) as r_item) and then t_item.same_string (r_item) then
|
||||||
not element.same_string ("q") and then
|
|
||||||
range.has_key (element) and then
|
|
||||||
(attached target.item (element) as t_item and attached range.item (element) as r_item) and then
|
|
||||||
t_item.same_string (r_item)
|
|
||||||
then
|
|
||||||
param_matches := param_matches + 1
|
param_matches := param_matches + 1
|
||||||
end
|
end
|
||||||
keys.forth
|
keys.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
if l_range_type.same_string (l_target_type) then
|
if l_range_type.same_string (l_target_type) then
|
||||||
l_fitness := 100
|
l_fitness := 100
|
||||||
else
|
else
|
||||||
l_fitness := 0
|
l_fitness := 0
|
||||||
end
|
end
|
||||||
if (
|
if (attached range.sub_type as l_range_sub_type and then attached target.sub_type as l_target_sub_type and then (l_target_sub_type.same_string (l_range_sub_type) or l_range_sub_type.same_string ("*") or l_target_sub_type.same_string ("*"))) then
|
||||||
attached range.sub_type as l_range_sub_type and then attached target.sub_type as l_target_sub_type and then
|
|
||||||
(l_target_sub_type.same_string (l_range_sub_type) or l_range_sub_type.same_string ("*") or l_target_sub_type.same_string ("*"))
|
|
||||||
) then
|
|
||||||
if l_range_sub_type.same_string (l_target_sub_type) then
|
if l_range_sub_type.same_string (l_target_sub_type) then
|
||||||
l_fitness := l_fitness + 10
|
l_fitness := l_fitness + 10
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
l_fitness := l_fitness + param_matches
|
l_fitness := l_fitness + param_matches
|
||||||
|
|
||||||
if l_fitness > best_fitness then
|
if l_fitness > best_fitness then
|
||||||
best_fitness := l_fitness
|
best_fitness := l_fitness
|
||||||
element := range.item ("q")
|
element := range.item ("q")
|
||||||
@@ -197,9 +175,9 @@ feature -- Parser
|
|||||||
-- Returns the quality 'q' of a mime-type when compared against the
|
-- Returns the quality 'q' of a mime-type when compared against the
|
||||||
-- mediaRanges in ranges.
|
-- mediaRanges in ranges.
|
||||||
local
|
local
|
||||||
l_ranges : LIST [STRING]
|
l_ranges: LIST [STRING]
|
||||||
res : ARRAYED_LIST [LANGUAGE_RESULTS]
|
res: ARRAYED_LIST [LANGUAGE_RESULTS]
|
||||||
p_res : LANGUAGE_RESULTS
|
p_res: LANGUAGE_RESULTS
|
||||||
do
|
do
|
||||||
l_ranges := ranges.split (',')
|
l_ranges := ranges.split (',')
|
||||||
from
|
from
|
||||||
@@ -227,8 +205,7 @@ feature -- Parser
|
|||||||
do
|
do
|
||||||
l_res := header.split (',')
|
l_res := header.split (',')
|
||||||
create {ARRAYED_LIST [LANGUAGE_RESULTS]} l_header_results.make (l_res.count)
|
create {ARRAYED_LIST [LANGUAGE_RESULTS]} l_header_results.make (l_res.count)
|
||||||
|
fixme ("Extract method!!!")
|
||||||
fixme("Extract method!!!")
|
|
||||||
from
|
from
|
||||||
l_res.start
|
l_res.start
|
||||||
until
|
until
|
||||||
@@ -238,9 +215,7 @@ feature -- Parser
|
|||||||
l_header_results.force (p_res)
|
l_header_results.force (p_res)
|
||||||
l_res.forth
|
l_res.forth
|
||||||
end
|
end
|
||||||
|
|
||||||
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (supported.count)
|
create {ARRAYED_LIST [FITNESS_AND_QUALITY]} weighted_matches.make (supported.count)
|
||||||
|
|
||||||
from
|
from
|
||||||
supported.start
|
supported.start
|
||||||
until
|
until
|
||||||
@@ -274,12 +249,16 @@ feature -- Parser
|
|||||||
end
|
end
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
end
|
end
|
||||||
check weighted_matches.item = fitness_and_quality end
|
check
|
||||||
|
weighted_matches.item = fitness_and_quality
|
||||||
|
end
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
elseif first_one.is_equal (fitness_and_quality) then
|
elseif first_one.is_equal (fitness_and_quality) then
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
else
|
else
|
||||||
check first_one > fitness_and_quality end
|
check
|
||||||
|
first_one > fitness_and_quality
|
||||||
|
end
|
||||||
weighted_matches.remove
|
weighted_matches.remove
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -301,7 +280,7 @@ feature -- Parser
|
|||||||
loop
|
loop
|
||||||
fitness_and_quality := weighted_matches.item
|
fitness_and_quality := weighted_matches.item
|
||||||
if fitness_and_quality.mime_type.same_string (s) then
|
if fitness_and_quality.mime_type.same_string (s) then
|
||||||
--| Found
|
--| Found
|
||||||
else
|
else
|
||||||
fitness_and_quality := Void
|
fitness_and_quality := Void
|
||||||
weighted_matches.forth
|
weighted_matches.forth
|
||||||
@@ -337,7 +316,7 @@ feature {NONE} -- Implementation
|
|||||||
trim (a_string: STRING): STRING
|
trim (a_string: STRING): STRING
|
||||||
-- trim whitespace from the beginning and end of a string
|
-- trim whitespace from the beginning and end of a string
|
||||||
require
|
require
|
||||||
valid_argument : a_string /= Void
|
valid_argument: a_string /= Void
|
||||||
do
|
do
|
||||||
a_string.left_adjust
|
a_string.left_adjust
|
||||||
a_string.right_justify
|
a_string.right_justify
|
||||||
@@ -347,6 +326,7 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -6,7 +6,9 @@ note
|
|||||||
|
|
||||||
class
|
class
|
||||||
LANGUAGE_RESULTS
|
LANGUAGE_RESULTS
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
ANY
|
ANY
|
||||||
redefine
|
redefine
|
||||||
out
|
out
|
||||||
@@ -61,7 +63,7 @@ feature -- Access
|
|||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
set_type (a_type: STRING)
|
set_type (a_type: STRING)
|
||||||
-- Set type with `a_type'
|
-- Set type with `a_type'
|
||||||
do
|
do
|
||||||
type := a_type
|
type := a_type
|
||||||
if attached sub_type as st then
|
if attached sub_type as st then
|
||||||
@@ -74,7 +76,7 @@ feature -- Element change
|
|||||||
end
|
end
|
||||||
|
|
||||||
set_sub_type (a_sub_type: STRING)
|
set_sub_type (a_sub_type: STRING)
|
||||||
-- Set sub_type with `a_sub_type
|
-- Set sub_type with `a_sub_type
|
||||||
do
|
do
|
||||||
sub_type := a_sub_type
|
sub_type := a_sub_type
|
||||||
if attached type as t then
|
if attached type as t then
|
||||||
@@ -86,7 +88,7 @@ feature -- Element change
|
|||||||
sub_type_assigned: sub_type ~ a_sub_type
|
sub_type_assigned: sub_type ~ a_sub_type
|
||||||
end
|
end
|
||||||
|
|
||||||
put (new: STRING; key: STRING)
|
put (new: STRING; key: STRING)
|
||||||
-- Insert `new' with `key' if there is no other item
|
-- Insert `new' with `key' if there is no other item
|
||||||
-- associated with the same key. If present, replace
|
-- associated with the same key. If present, replace
|
||||||
-- the old value with `new'
|
-- the old value with `new'
|
||||||
@@ -114,7 +116,6 @@ feature -- Status Report
|
|||||||
Result.append_string (" '" + st + "',")
|
Result.append_string (" '" + st + "',")
|
||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
|
|
||||||
from
|
from
|
||||||
params.start
|
params.start
|
||||||
until
|
until
|
||||||
@@ -137,7 +138,10 @@ feature {NONE} -- Implementation
|
|||||||
params: HASH_TABLE [STRING, STRING]
|
params: HASH_TABLE [STRING, STRING]
|
||||||
--dictionary of all the parameters for the media range
|
--dictionary of all the parameters for the media range
|
||||||
|
|
||||||
;note
|
;
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {LANGUAGE_VARIANT_RESULTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
LANGUAGE_VARIANT_RESULTS
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
language_type: detachable STRING
|
||||||
|
|
||||||
|
|
||||||
|
variant_header: detachable STRING
|
||||||
|
|
||||||
|
|
||||||
|
supported_variants: detachable LIST [STRING]
|
||||||
|
|
||||||
|
|
||||||
|
is_acceptable: BOOLEAN
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_acceptable (acceptable: BOOLEAN)
|
||||||
|
-- Set `is_acceptable' with `acceptable'
|
||||||
|
do
|
||||||
|
is_acceptable := acceptable
|
||||||
|
ensure
|
||||||
|
is_acceptable_set: is_acceptable = acceptable
|
||||||
|
end
|
||||||
|
|
||||||
|
set_language_type (a_language_type: STRING)
|
||||||
|
-- Set `language_type' with `a_language_type'
|
||||||
|
do
|
||||||
|
language_type := a_language_type
|
||||||
|
ensure
|
||||||
|
language_type_set: language_type/= Void implies a_language_type = language_type
|
||||||
|
end
|
||||||
|
|
||||||
|
set_variant_header
|
||||||
|
-- Set variant header as 'Accept-Language'
|
||||||
|
do
|
||||||
|
variant_header := "Accept-Language"
|
||||||
|
ensure
|
||||||
|
variant_header_set: attached variant_header as l_variant_header implies l_variant_header.same_string ("Accept-Language")
|
||||||
|
end
|
||||||
|
|
||||||
|
set_supported_variants (a_supported: LIST [STRING])
|
||||||
|
-- Set `supported vairants' with `a_supported'
|
||||||
|
do
|
||||||
|
supported_variants := a_supported
|
||||||
|
ensure
|
||||||
|
set_supported_variants: supported_variants /= Void implies supported_variants = a_supported
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {MEDIA_TYPE_VARIANT_RESULTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
MEDIA_TYPE_VARIANT_RESULTS
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
media_type: detachable STRING
|
||||||
|
|
||||||
|
variant_header: detachable STRING
|
||||||
|
|
||||||
|
supported_variants: detachable LIST [STRING]
|
||||||
|
|
||||||
|
is_acceptable: BOOLEAN
|
||||||
|
|
||||||
|
|
||||||
|
feature -- Change Element
|
||||||
|
|
||||||
|
set_media_type (a_media_type: STRING)
|
||||||
|
-- Set `media_type' as `a_media_type'
|
||||||
|
do
|
||||||
|
media_type := a_media_type
|
||||||
|
ensure
|
||||||
|
media_type_set: media_type /= Void implies media_type = a_media_type
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
set_variant_header
|
||||||
|
-- Set variant header as `Accept'
|
||||||
|
do
|
||||||
|
variant_header := "Accept"
|
||||||
|
ensure
|
||||||
|
variant_header_set: attached variant_header as l_variant_header implies l_variant_header.same_string ("Accept")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
set_supported_variants (a_supported: LIST [STRING])
|
||||||
|
-- Set `supported_variants' with `a_supported'
|
||||||
|
do
|
||||||
|
supported_variants := a_supported
|
||||||
|
ensure
|
||||||
|
supported_variants_variants: supported_variants /= Void implies supported_variants = a_supported
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
set_acceptable (acceptable: BOOLEAN)
|
||||||
|
-- Set `is_acceptable' with `acceptable'
|
||||||
|
do
|
||||||
|
is_acceptable := acceptable
|
||||||
|
ensure
|
||||||
|
is_acceptable_set: is_acceptable = acceptable
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
author: ""
|
author: ""
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
description : "Accept Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1"
|
EIS: "name=Accept", "src=http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1", "protocol=uri"
|
||||||
class
|
class
|
||||||
MIME_PARSE
|
MIME_PARSE
|
||||||
|
|
||||||
@@ -12,47 +12,16 @@ inherit
|
|||||||
|
|
||||||
feature -- Parser
|
feature -- Parser
|
||||||
|
|
||||||
parse_mime_type (a_mime_type: STRING): PARSE_RESULTS
|
parse_mime_type (a_mime_type: STRING): HTTP_MEDIA_TYPE
|
||||||
-- Parses a mime-type into its component parts.
|
-- Parses a mime-type into its component parts.
|
||||||
-- For example, the media range 'application/xhtml;q=0.5' would get parsed
|
-- For example, the media range 'application/xhtml;q=0.5' would get parsed
|
||||||
-- into:
|
-- into:
|
||||||
-- ('application', 'xhtml', {'q', '0.5'})
|
-- ('application', 'xhtml', {'q', '0.5'})
|
||||||
local
|
|
||||||
l_parts: LIST [STRING]
|
|
||||||
p: STRING
|
|
||||||
sub_parts: LIST [STRING]
|
|
||||||
i: INTEGER
|
|
||||||
l_full_type: STRING
|
|
||||||
l_types: LIST [STRING]
|
|
||||||
do
|
do
|
||||||
fixme ("Improve code!!!")
|
create Result.make_from_string (a_mime_type)
|
||||||
create Result.make
|
|
||||||
l_parts := a_mime_type.split (';')
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
until
|
|
||||||
i > l_parts.count
|
|
||||||
loop
|
|
||||||
p := l_parts.at (i)
|
|
||||||
sub_parts := p.split ('=')
|
|
||||||
if sub_parts.count = 2 then
|
|
||||||
Result.put (trim (sub_parts[2]), trim (sub_parts[1]))
|
|
||||||
end
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
--Java URLConnection class sends an Accept header that includes a
|
|
||||||
--single "*" - Turn it into a legal wildcard.
|
|
||||||
|
|
||||||
l_full_type := trim (l_parts[1])
|
|
||||||
if l_full_type.same_string ("*") then
|
|
||||||
l_full_type := "*/*"
|
|
||||||
end
|
|
||||||
l_types := l_full_type.split ('/')
|
|
||||||
Result.set_type (trim (l_types[1]))
|
|
||||||
Result.set_sub_type (trim (l_types[2]))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
parse_media_range (a_range: STRING): PARSE_RESULTS
|
parse_media_range (a_range: STRING): HTTP_MEDIA_TYPE
|
||||||
-- Media-ranges are mime-types with wild-cards and a 'q' quality parameter.
|
-- Media-ranges are mime-types with wild-cards and a 'q' quality parameter.
|
||||||
-- For example, the media range 'application/*;q=0.5' would get parsed into:
|
-- For example, the media range 'application/*;q=0.5' would get parsed into:
|
||||||
-- ('application', '*', {'q', '0.5'})
|
-- ('application', '*', {'q', '0.5'})
|
||||||
@@ -62,7 +31,7 @@ feature -- Parser
|
|||||||
do
|
do
|
||||||
fixme ("Improve the code!!!")
|
fixme ("Improve the code!!!")
|
||||||
Result := parse_mime_type (a_range)
|
Result := parse_mime_type (a_range)
|
||||||
if attached Result.item ("q") as q then
|
if attached Result.parameter ("q") as q then
|
||||||
if
|
if
|
||||||
q.is_double and then
|
q.is_double and then
|
||||||
attached {REAL_64} q.to_double as r and then
|
attached {REAL_64} q.to_double as r and then
|
||||||
@@ -71,18 +40,18 @@ feature -- Parser
|
|||||||
--| Keep current value
|
--| Keep current value
|
||||||
if q.same_string ("1") then
|
if q.same_string ("1") then
|
||||||
--| Use 1.0 formatting
|
--| Use 1.0 formatting
|
||||||
Result.put ("1.0", "q")
|
Result.add_parameter ("q", "1.0")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result.put ("1.0", "q")
|
Result.add_parameter ("q", "1.0")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
Result.put ("1.0", "q")
|
Result.add_parameter ("q", "1.0")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
fitness_and_quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [PARSE_RESULTS]): FITNESS_AND_QUALITY
|
fitness_and_quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [HTTP_MEDIA_TYPE]): FITNESS_AND_QUALITY
|
||||||
-- Find the best match for a given mimeType against a list of media_ranges
|
-- Find the best match for a given mimeType against a list of media_ranges
|
||||||
-- that have already been parsed by parse_media_range. Returns a
|
-- that have already been parsed by parse_media_range. Returns a
|
||||||
-- tuple of the fitness value and the value of the 'q' quality parameter of
|
-- tuple of the fitness value and the value of the 'q' quality parameter of
|
||||||
@@ -92,17 +61,16 @@ feature -- Parser
|
|||||||
best_fitness: INTEGER
|
best_fitness: INTEGER
|
||||||
target_q: REAL_64
|
target_q: REAL_64
|
||||||
best_fit_q: REAL_64
|
best_fit_q: REAL_64
|
||||||
target: PARSE_RESULTS
|
target: HTTP_MEDIA_TYPE
|
||||||
range: PARSE_RESULTS
|
range: HTTP_MEDIA_TYPE
|
||||||
keys: LIST [STRING]
|
|
||||||
param_matches: INTEGER
|
param_matches: INTEGER
|
||||||
element: detachable STRING
|
element: detachable READABLE_STRING_8
|
||||||
l_fitness: INTEGER
|
l_fitness: INTEGER
|
||||||
do
|
do
|
||||||
best_fitness := -1
|
best_fitness := -1
|
||||||
best_fit_q := 0.0
|
best_fit_q := 0.0
|
||||||
target := parse_media_range (a_mime_type)
|
target := parse_media_range (a_mime_type)
|
||||||
if attached target.item ("q") as q and then q.is_double then
|
if attached target.parameter ("q") as q and then q.is_double then
|
||||||
target_q := q.to_double
|
target_q := q.to_double
|
||||||
if target_q < 0.0 then
|
if target_q < 0.0 then
|
||||||
target_q := 0.0
|
target_q := 0.0
|
||||||
@@ -115,7 +83,7 @@ feature -- Parser
|
|||||||
|
|
||||||
if
|
if
|
||||||
attached target.type as l_target_type and
|
attached target.type as l_target_type and
|
||||||
attached target.sub_type as l_target_sub_type
|
attached target.subtype as l_target_sub_type
|
||||||
then
|
then
|
||||||
from
|
from
|
||||||
parsed_ranges.start
|
parsed_ranges.start
|
||||||
@@ -129,29 +97,29 @@ feature -- Parser
|
|||||||
(l_target_type.same_string (l_range_type) or l_range_type.same_string ("*") or l_target_type.same_string ("*"))
|
(l_target_type.same_string (l_range_type) or l_range_type.same_string ("*") or l_target_type.same_string ("*"))
|
||||||
) and
|
) and
|
||||||
(
|
(
|
||||||
attached range.sub_type as l_range_sub_type and then
|
attached range.subtype as l_range_sub_type and then
|
||||||
(l_target_sub_type.same_string (l_range_sub_type) or l_range_sub_type.same_string ("*") or l_target_sub_type.same_string ("*"))
|
(l_target_sub_type.same_string (l_range_sub_type) or l_range_sub_type.same_string ("*") or l_target_sub_type.same_string ("*"))
|
||||||
)
|
)
|
||||||
then
|
then
|
||||||
from
|
if attached target.parameters as l_keys then
|
||||||
param_matches := 0
|
from
|
||||||
keys := target.keys
|
param_matches := 0
|
||||||
keys.start
|
l_keys.start
|
||||||
until
|
until
|
||||||
keys.after
|
l_keys.after
|
||||||
loop
|
loop
|
||||||
element := keys.item_for_iteration
|
element := l_keys.key_for_iteration
|
||||||
if
|
if
|
||||||
not element.same_string ("q") and then
|
not element.same_string ("q") and then
|
||||||
range.has_key (element) and then
|
range.has_parameter (element) and then
|
||||||
(attached target.item (element) as t_item and attached range.item (element) as r_item) and then
|
(attached target.parameter (element) as t_item and attached range.parameter (element) as r_item) and then
|
||||||
t_item.same_string (r_item)
|
t_item.same_string (r_item)
|
||||||
then
|
then
|
||||||
param_matches := param_matches + 1
|
param_matches := param_matches + 1
|
||||||
|
end
|
||||||
|
l_keys.forth
|
||||||
end
|
end
|
||||||
keys.forth
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if l_range_type.same_string (l_target_type) then
|
if l_range_type.same_string (l_target_type) then
|
||||||
l_fitness := 100
|
l_fitness := 100
|
||||||
else
|
else
|
||||||
@@ -166,7 +134,7 @@ feature -- Parser
|
|||||||
|
|
||||||
if l_fitness > best_fitness then
|
if l_fitness > best_fitness then
|
||||||
best_fitness := l_fitness
|
best_fitness := l_fitness
|
||||||
element := range.item ("q")
|
element := range.parameter ("q")
|
||||||
if element /= Void then
|
if element /= Void then
|
||||||
best_fit_q := element.to_double.min (target_q)
|
best_fit_q := element.to_double.min (target_q)
|
||||||
else
|
else
|
||||||
@@ -180,7 +148,7 @@ feature -- Parser
|
|||||||
create Result.make (best_fitness, best_fit_q)
|
create Result.make (best_fitness, best_fit_q)
|
||||||
end
|
end
|
||||||
|
|
||||||
quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [PARSE_RESULTS]): REAL_64
|
quality_parsed (a_mime_type: STRING; parsed_ranges: LIST [HTTP_MEDIA_TYPE]): REAL_64
|
||||||
-- Find the best match for a given mime-type against a list of ranges that
|
-- Find the best match for a given mime-type against a list of ranges that
|
||||||
-- have already been parsed by parseMediaRange(). Returns the 'q' quality
|
-- have already been parsed by parseMediaRange(). Returns the 'q' quality
|
||||||
-- parameter of the best match, 0 if no match was found. This function
|
-- parameter of the best match, 0 if no match was found. This function
|
||||||
@@ -195,8 +163,8 @@ feature -- Parser
|
|||||||
-- mediaRanges in ranges.
|
-- mediaRanges in ranges.
|
||||||
local
|
local
|
||||||
l_ranges : LIST [STRING]
|
l_ranges : LIST [STRING]
|
||||||
res : ARRAYED_LIST [PARSE_RESULTS]
|
res : ARRAYED_LIST [HTTP_MEDIA_TYPE]
|
||||||
p_res : PARSE_RESULTS
|
p_res : HTTP_MEDIA_TYPE
|
||||||
do
|
do
|
||||||
l_ranges := ranges.split (',')
|
l_ranges := ranges.split (',')
|
||||||
from
|
from
|
||||||
@@ -215,15 +183,15 @@ feature -- Parser
|
|||||||
best_match (supported: LIST [STRING]; header: STRING): STRING
|
best_match (supported: LIST [STRING]; header: STRING): STRING
|
||||||
-- Choose the mime-type with the highest fitness score and quality ('q') from a list of candidates.
|
-- Choose the mime-type with the highest fitness score and quality ('q') from a list of candidates.
|
||||||
local
|
local
|
||||||
l_header_results: LIST [PARSE_RESULTS]
|
l_header_results: LIST [HTTP_MEDIA_TYPE]
|
||||||
weighted_matches: LIST [FITNESS_AND_QUALITY]
|
weighted_matches: LIST [FITNESS_AND_QUALITY]
|
||||||
l_res: LIST [STRING]
|
l_res: LIST [STRING]
|
||||||
p_res: PARSE_RESULTS
|
p_res: HTTP_MEDIA_TYPE
|
||||||
fitness_and_quality, first_one: detachable FITNESS_AND_QUALITY
|
fitness_and_quality, first_one: detachable FITNESS_AND_QUALITY
|
||||||
s: STRING
|
s: STRING
|
||||||
do
|
do
|
||||||
l_res := header.split (',')
|
l_res := header.split (',')
|
||||||
create {ARRAYED_LIST [PARSE_RESULTS]} l_header_results.make (l_res.count)
|
create {ARRAYED_LIST [HTTP_MEDIA_TYPE]} l_header_results.make (l_res.count)
|
||||||
|
|
||||||
fixme("Extract method!!!")
|
fixme("Extract method!!!")
|
||||||
from
|
from
|
||||||
@@ -290,7 +258,7 @@ feature -- Parser
|
|||||||
until
|
until
|
||||||
l_header_results.after or fitness_and_quality /= Void
|
l_header_results.after or fitness_and_quality /= Void
|
||||||
loop
|
loop
|
||||||
s := l_header_results.item.mime_type
|
s := l_header_results.item.simple_type
|
||||||
from
|
from
|
||||||
weighted_matches.start
|
weighted_matches.start
|
||||||
until
|
until
|
||||||
@@ -344,6 +312,6 @@ feature {NONE} -- Implementation
|
|||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
end
|
end
|
||||||
@@ -8,6 +8,7 @@ class
|
|||||||
PARSE_RESULTS
|
PARSE_RESULTS
|
||||||
|
|
||||||
inherit
|
inherit
|
||||||
|
|
||||||
ANY
|
ANY
|
||||||
redefine
|
redefine
|
||||||
out
|
out
|
||||||
@@ -62,7 +63,7 @@ feature -- Access
|
|||||||
feature -- Element change
|
feature -- Element change
|
||||||
|
|
||||||
set_type (a_type: STRING)
|
set_type (a_type: STRING)
|
||||||
-- Set type with `a_type'
|
-- Set type with `a_type'
|
||||||
do
|
do
|
||||||
type := a_type
|
type := a_type
|
||||||
if attached sub_type as st then
|
if attached sub_type as st then
|
||||||
@@ -75,7 +76,7 @@ feature -- Element change
|
|||||||
end
|
end
|
||||||
|
|
||||||
set_sub_type (a_sub_type: STRING)
|
set_sub_type (a_sub_type: STRING)
|
||||||
-- Set sub_type with `a_sub_type
|
-- Set sub_type with `a_sub_type
|
||||||
do
|
do
|
||||||
sub_type := a_sub_type
|
sub_type := a_sub_type
|
||||||
if attached type as t then
|
if attached type as t then
|
||||||
@@ -87,7 +88,7 @@ feature -- Element change
|
|||||||
sub_type_assigned: sub_type ~ a_sub_type
|
sub_type_assigned: sub_type ~ a_sub_type
|
||||||
end
|
end
|
||||||
|
|
||||||
put (new: STRING; key: STRING)
|
put (new: STRING; key: STRING)
|
||||||
-- Insert `new' with `key' if there is no other item
|
-- Insert `new' with `key' if there is no other item
|
||||||
-- associated with the same key. If present, replace
|
-- associated with the same key. If present, replace
|
||||||
-- the old value with `new'
|
-- the old value with `new'
|
||||||
@@ -115,7 +116,6 @@ feature -- Status Report
|
|||||||
Result.append_string (" '" + st + "',")
|
Result.append_string (" '" + st + "',")
|
||||||
end
|
end
|
||||||
Result.append_string (" {")
|
Result.append_string (" {")
|
||||||
|
|
||||||
from
|
from
|
||||||
params.start
|
params.start
|
||||||
until
|
until
|
||||||
@@ -138,7 +138,10 @@ feature {NONE} -- Implementation
|
|||||||
params: HASH_TABLE [STRING, STRING]
|
params: HASH_TABLE [STRING, STRING]
|
||||||
--dictionary of all the parameters for the media range
|
--dictionary of all the parameters for the media range
|
||||||
|
|
||||||
;note
|
;
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
note
|
note
|
||||||
description: "Summary description for {SHARED_MIME}."
|
description: "Summary description for {SHARED_CONNEG}."
|
||||||
date: "$Date$"
|
date: "$Date$"
|
||||||
revision: "$Revision$"
|
revision: "$Revision$"
|
||||||
|
|
||||||
@@ -8,23 +8,24 @@ class
|
|||||||
|
|
||||||
feature
|
feature
|
||||||
|
|
||||||
mime: MIME_PARSE
|
Mime: MIME_PARSE
|
||||||
once
|
once
|
||||||
create Result
|
create Result
|
||||||
end
|
end
|
||||||
|
|
||||||
common: COMMON_ACCEPT_HEADER_PARSER
|
Common: COMMON_ACCEPT_HEADER_PARSER
|
||||||
-- Charset and Encoding
|
-- Charset and Encoding
|
||||||
once
|
once
|
||||||
create Result
|
create Result
|
||||||
end
|
end
|
||||||
|
|
||||||
language: LANGUAGE_PARSE
|
Language: LANGUAGE_PARSE
|
||||||
once
|
once
|
||||||
create Result
|
create Result
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others"
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {VARIANT_RESULTS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
VARIANT_RESULTS
|
||||||
|
|
||||||
|
feature -- Mime, Language, Charset and Encoding Results
|
||||||
|
|
||||||
|
mime_result: detachable STRING
|
||||||
|
|
||||||
|
set_mime_result (a_mime: STRING)
|
||||||
|
-- set the mime_result with `a_mime'
|
||||||
|
do
|
||||||
|
mime_result := a_mime
|
||||||
|
ensure
|
||||||
|
set_mime_result: a_mime = mime_result
|
||||||
|
end
|
||||||
|
|
||||||
|
language_result: detachable STRING
|
||||||
|
|
||||||
|
set_language_result (a_language: STRING)
|
||||||
|
-- set the language_result with `a_language'
|
||||||
|
do
|
||||||
|
language_result := a_language
|
||||||
|
ensure
|
||||||
|
set_language: a_language = language_result
|
||||||
|
end
|
||||||
|
|
||||||
|
charset_result: detachable STRING
|
||||||
|
|
||||||
|
set_charset_result (a_charset: STRING)
|
||||||
|
-- set the charset_result with `a_charset'
|
||||||
|
do
|
||||||
|
charset_result := a_charset
|
||||||
|
ensure
|
||||||
|
set_charset: a_charset = charset_result
|
||||||
|
end
|
||||||
|
|
||||||
|
encoding_result: detachable STRING
|
||||||
|
|
||||||
|
set_encoding_default (an_encoding: STRING)
|
||||||
|
do
|
||||||
|
encoding_result := an_encoding
|
||||||
|
ensure
|
||||||
|
set_encoding: an_encoding = encoding_result
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2013, Javier Velilla, Jocelyn Fiat, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
|
||||||
|
end
|
||||||
@@ -28,15 +28,15 @@ feature -- Test routines
|
|||||||
|
|
||||||
test_parse_media_range
|
test_parse_media_range
|
||||||
do
|
do
|
||||||
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml;q=1").out.same_string("('application', 'xml', {'q':'1.0',})") )
|
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml;q=1").format.same_string("('application', 'xml', {'q':'1.0',})") )
|
||||||
|
|
||||||
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml").out.same_string("('application', 'xml', {'q':'1.0',})") )
|
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml").format.same_string("('application', 'xml', {'q':'1.0',})") )
|
||||||
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml;q=").out.same_string("('application', 'xml', {'q':'1.0',})") )
|
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml;q=").format.same_string("('application', 'xml', {'q':'1.0',})") )
|
||||||
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml ; q=").out.same_string("('application', 'xml', {'q':'1.0',})") )
|
assert ("Expected ('application', 'xml', {'q':'1',})", parser.parse_media_range("application/xml ; q=").format.same_string("('application', 'xml', {'q':'1.0',})") )
|
||||||
assert ("Expected ('application', 'xml', {'q':'1','b':'other',})", parser.parse_media_range("application/xml ; q=1;b=other").out.same_string("('application', 'xml', {'q':'1.0','b':'other',})") )
|
assert ("Expected ('application', 'xml', {'q':'1','b':'other',})", parser.parse_media_range("application/xml ; q=1;b=other").format.same_string("('application', 'xml', {'q':'1.0','b':'other',})") )
|
||||||
assert ("Expected ('application', 'xml', {'q':'1','b':'other',})", parser.parse_media_range("application/xml ; q=2;b=other").out.same_string("('application', 'xml', {'q':'1.0','b':'other',})") )
|
assert ("Expected ('application', 'xml', {'q':'1','b':'other',})", parser.parse_media_range("application/xml ; q=2;b=other").format.same_string("('application', 'xml', {'q':'1.0','b':'other',})") )
|
||||||
-- Accept header that includes *
|
-- Accept header that includes *
|
||||||
assert ("Expected ('*', '*', {'q':'.2',})", parser.parse_media_range(" *; q=.2").out.same_string("('*', '*', {'q':'.2',})"))
|
assert ("Expected ('*', '*', {'q':'.2',})", parser.parse_media_range(" *; q=.2").format.same_string("('*', '*', {'q':'.2',})"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -97,9 +97,9 @@ feature {NONE} -- Initialization
|
|||||||
-- Extract type and subtype
|
-- Extract type and subtype
|
||||||
p := t.index_of ('/', 1)
|
p := t.index_of ('/', 1)
|
||||||
if p = 0 then
|
if p = 0 then
|
||||||
has_error := True
|
--| Accept *; should be */*
|
||||||
type := t
|
type := t
|
||||||
subtype := ""
|
subtype := "*"
|
||||||
else
|
else
|
||||||
subtype := t.substring (p + 1, t.count)
|
subtype := t.substring (p + 1, t.count)
|
||||||
type := t
|
type := t
|
||||||
@@ -368,6 +368,30 @@ feature -- Status report
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
format : STRING
|
||||||
|
-- Representation of the current object
|
||||||
|
do
|
||||||
|
create Result.make_from_string ("(")
|
||||||
|
if attached type as t then
|
||||||
|
Result.append_string ("'" + t + "',")
|
||||||
|
end
|
||||||
|
if attached subtype as st then
|
||||||
|
Result.append_string (" '" + st + "',")
|
||||||
|
end
|
||||||
|
Result.append_string (" {")
|
||||||
|
if attached parameters as l_params then
|
||||||
|
from
|
||||||
|
l_params.start
|
||||||
|
until
|
||||||
|
l_params.after
|
||||||
|
loop
|
||||||
|
Result.append ("'" + l_params.key_for_iteration + "':'" + l_params.item_for_iteration + "',");
|
||||||
|
l_params.forth
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Result.append ("})")
|
||||||
|
end
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
type_and_subtype_not_empty: not has_error implies not type.is_empty and not subtype.is_empty
|
type_and_subtype_not_empty: not has_error implies not type.is_empty and not subtype.is_empty
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user