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