248 lines
5.1 KiB
Plaintext
248 lines
5.1 KiB
Plaintext
note
|
|
description: "Summary description for {WGI_CHUNKED_INPUT_STREAM}."
|
|
date: "$Date$"
|
|
revision: "$Revision$"
|
|
|
|
class
|
|
WGI_CHUNKED_INPUT_STREAM
|
|
|
|
inherit
|
|
WGI_INPUT_STREAM
|
|
|
|
create
|
|
make
|
|
|
|
feature {NONE} -- Implementation
|
|
|
|
make (an_input: like input)
|
|
do
|
|
create last_string.make_empty
|
|
create last_chunk.make_empty
|
|
last_chunk_size := 0
|
|
index := 0
|
|
chunk_lower := 0
|
|
chunk_upper := 0
|
|
create tmp_hex_chunk_size.make_empty
|
|
input := an_input
|
|
end
|
|
|
|
feature -- Input
|
|
|
|
read_character
|
|
-- Read the next character in input stream.
|
|
-- Make the result available in `last_character'
|
|
do
|
|
index := index + 1
|
|
if index > chunk_upper then
|
|
read_chunk
|
|
if last_chunk = Void then
|
|
read_trailer
|
|
end
|
|
end
|
|
last_character := last_chunk.item (index)
|
|
end
|
|
|
|
read_string (nb: INTEGER)
|
|
-- Read the next `nb' characters and
|
|
-- make the string result available in `last_string'
|
|
local
|
|
i: like index
|
|
do
|
|
last_string.wipe_out
|
|
if last_chunk_size = 0 then
|
|
read_chunk
|
|
end
|
|
from
|
|
index := index + 1
|
|
i := index
|
|
until
|
|
i - index + 1 = nb or last_chunk_size = 0
|
|
loop
|
|
if i + nb - 1 <= chunk_upper then
|
|
last_string.append (last_chunk.substring (i, i + nb - 1))
|
|
i := i + nb - 1
|
|
else
|
|
-- Need to read new chunk
|
|
-- first get all available data from current chunk
|
|
if i <= chunk_upper then
|
|
last_string.append (last_chunk.substring (i, chunk_upper))
|
|
i := chunk_upper
|
|
end
|
|
-- then continue
|
|
read_chunk
|
|
end
|
|
end
|
|
if last_chunk_size = 0 then
|
|
read_trailer
|
|
end
|
|
index := i
|
|
end
|
|
|
|
feature -- Access
|
|
|
|
last_string: STRING_8
|
|
-- Last string read.
|
|
--
|
|
-- Note: this query *might* return the same object.
|
|
-- Therefore a clone should be used if the result
|
|
-- is to be kept beyond the next call to this feature.
|
|
-- However `last_string' is not shared between file objects.)
|
|
|
|
last_character: CHARACTER_8
|
|
-- Last item read.
|
|
|
|
feature -- Status report
|
|
|
|
is_open_read: BOOLEAN
|
|
-- Can items be read from input stream?
|
|
do
|
|
Result := input.is_open_read
|
|
end
|
|
|
|
end_of_input: BOOLEAN
|
|
-- Has the end of input stream been reached?
|
|
do
|
|
Result := input.end_of_input
|
|
end
|
|
|
|
feature {NONE} -- Parser
|
|
|
|
index, chunk_lower, chunk_upper: INTEGER
|
|
last_chunk_size: INTEGER
|
|
last_chunk: STRING_8
|
|
|
|
tmp_hex_chunk_size: STRING_8
|
|
|
|
read_chunk
|
|
do
|
|
chunk_lower := chunk_upper + 1
|
|
last_chunk.wipe_out
|
|
last_chunk_size := 0
|
|
read_chunk_size
|
|
if last_chunk_size > 0 then
|
|
chunk_upper := chunk_upper + last_chunk_size
|
|
read_chunk_data
|
|
end
|
|
ensure
|
|
attached last_chunk as l_last_chunk implies l_last_chunk.count = chunk_upper - chunk_lower
|
|
end
|
|
|
|
read_chunk_data
|
|
require
|
|
last_chunk.is_empty
|
|
last_chunk_size > 0
|
|
local
|
|
l_input: like input
|
|
do
|
|
l_input := input
|
|
l_input.read_string (last_chunk_size)
|
|
last_chunk := l_input.last_string
|
|
ensure
|
|
last_chunk_attached: attached last_chunk as el_last_chunk
|
|
last_chunk_size_ok: el_last_chunk.count = last_chunk_size
|
|
end
|
|
|
|
read_chunk_size
|
|
require
|
|
tmp_hex_chunk_size_is_empty: tmp_hex_chunk_size.is_empty
|
|
local
|
|
eol : BOOLEAN
|
|
c: CHARACTER
|
|
hex : HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
|
l_input: like input
|
|
do
|
|
l_input := input
|
|
from
|
|
l_input.read_character
|
|
until
|
|
eol
|
|
loop
|
|
c := l_input.last_character
|
|
inspect c
|
|
when '%R' then
|
|
-- We are in the end of the line, we need to read the next character to start the next line.
|
|
eol := True
|
|
l_input.read_character
|
|
when ';' then
|
|
-- We are in an extension chunk data
|
|
read_extension_chunk
|
|
else
|
|
tmp_hex_chunk_size.append_character (c)
|
|
l_input.read_character
|
|
end
|
|
end
|
|
if tmp_hex_chunk_size.same_string ("0") then
|
|
last_chunk_size := 0
|
|
else
|
|
create hex.make
|
|
hex.parse_string_with_type (tmp_hex_chunk_size, hex.type_integer)
|
|
if hex.parse_successful then
|
|
last_chunk_size := hex.parsed_integer
|
|
else
|
|
last_chunk_size := 0 -- ERROR ...
|
|
end
|
|
end
|
|
tmp_hex_chunk_size.wipe_out
|
|
end
|
|
|
|
read_extension_chunk
|
|
local
|
|
l_input: like input
|
|
do
|
|
l_input := input
|
|
debug
|
|
print (" Reading extension chunk ")
|
|
end
|
|
from
|
|
l_input.read_character
|
|
until
|
|
l_input.last_character = '%R'
|
|
loop
|
|
debug
|
|
print (l_input.last_character)
|
|
end
|
|
l_input.read_character
|
|
end
|
|
end
|
|
|
|
read_trailer
|
|
local
|
|
l_input: like input
|
|
do
|
|
l_input := input
|
|
if not l_input.end_of_input then
|
|
debug
|
|
print (" Reading trailer ")
|
|
end
|
|
from
|
|
l_input.read_character
|
|
until
|
|
l_input.last_character = '%R'
|
|
loop
|
|
debug
|
|
print (l_input.last_character)
|
|
end
|
|
l_input.read_character
|
|
end
|
|
-- read the LF
|
|
l_input.read_character
|
|
end
|
|
end
|
|
|
|
feature {NONE} -- Implementation
|
|
|
|
input: WGI_INPUT_STREAM
|
|
-- Input Stream
|
|
|
|
;note
|
|
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
|
source: "[
|
|
Eiffel Software
|
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
|
Telephone 805-685-1006, Fax 805-685-6869
|
|
Website http://www.eiffel.com
|
|
Customer support http://support.eiffel.com
|
|
]"
|
|
end
|