PageRenderTime 19ms CodeModel.GetById 9ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/src/lib/io/filter/base64_input_stream.e

http://github.com/tybor/Liberty
Specman e | 201 lines | 154 code | 21 blank | 26 comment | 9 complexity | 3863600f80e1a4c02ea555e81c664601 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class BASE64_INPUT_STREAM
  5   --
  6   -- A Base64 decoder. Plug it onto a Base64-encoded stream.
  7   --
  8
  9inherit
 10   FILTER_INPUT_STREAM
 11      redefine can_unread_character, end_of_input
 12      end
 13
 14create {ANY}
 15   connect_to
 16
 17feature {ANY}
 18   can_unread_character: BOOLEAN
 19      do
 20         Result := flags.bit_test(can_unread_character_flag)
 21      end
 22
 23   end_of_input: BOOLEAN
 24      do
 25         Result := end_of_base64 or else Precursor
 26      end
 27
 28feature {}
 29   local_can_disconnect: BOOLEAN True
 30
 31feature {FILTER_INPUT_STREAM}
 32   filtered_read_character
 33      local
 34         c: INTEGER
 35      do
 36         if has_unread_character then
 37            set_has_unread_character(False)
 38            swap_unread_buffer
 39         else
 40            unread_buffer := filtered_last_character
 41            from
 42               stream.filtered_read_character
 43            until
 44               stream.end_of_input or else stream.filtered_last_character /= '%N'
 45            loop
 46               stream.filtered_read_character
 47            end
 48            if not stream.end_of_input then
 49               c := b2t(stream.filtered_last_character)
 50               inspect
 51                  state
 52               when 0 then
 53                  accu := c |<< 2
 54                  stream.filtered_read_character
 55                  if not stream.end_of_input then
 56                     c := b2t(stream.filtered_last_character)
 57                     accu := accu | (c |>> 4)
 58                     filtered_last_character := accu.to_character
 59                     accu := c & 15 |<< 4
 60                     state := 1
 61                  end
 62               when 1 then
 63                  accu := accu | (c |>> 2)
 64                  filtered_last_character := accu.to_character
 65                  accu := c & 3 |<< 6
 66                  state := 2
 67               when 2 then
 68                  accu := accu | c
 69                  filtered_last_character := accu.to_character
 70                  state := 0
 71               end
 72            end
 73         end
 74         set_can_unread_character(not end_of_input)
 75      end
 76
 77   filtered_unread_character
 78      do
 79         set_has_unread_character(True)
 80         set_can_unread_character(False)
 81         swap_unread_buffer
 82      end
 83
 84   filtered_last_character: CHARACTER
 85
 86feature {}
 87   state: INTEGER
 88
 89   accu: INTEGER
 90
 91   unread_buffer: CHARACTER
 92
 93   swap_unread_buffer
 94      local
 95         tmp_buffer: CHARACTER
 96      do
 97         tmp_buffer := unread_buffer
 98         unread_buffer := filtered_last_character
 99         filtered_last_character := tmp_buffer
100      ensure
101         unread_buffer = old filtered_last_character
102         filtered_last_character = old unread_buffer
103      end
104
105   set_can_unread_character (value: BOOLEAN)
106      do
107         if value then
108            flags := flags.bit_set(can_unread_character_flag)
109         else
110            flags := flags.bit_reset(can_unread_character_flag)
111         end
112      ensure
113         can_unread_character = value
114      end
115
116   has_unread_character: BOOLEAN
117      do
118         Result := flags.bit_test(has_unread_character_flag)
119      end
120
121   set_has_unread_character (value: BOOLEAN)
122      do
123         if value then
124            flags := flags.bit_set(has_unread_character_flag)
125         else
126            flags := flags.bit_reset(has_unread_character_flag)
127         end
128      ensure
129         has_unread_character = value
130      end
131
132   end_of_base64: BOOLEAN
133      do
134         Result := flags.bit_test(end_of_base64_flag)
135      end
136
137   set_end_of_base64 (value: BOOLEAN)
138      do
139         if value then
140            flags := flags.bit_set(end_of_base64_flag)
141         else
142            flags := flags.bit_reset(end_of_base64_flag)
143         end
144      ensure
145         end_of_base64 = value
146      end
147
148   flags: INTEGER
149   can_unread_character_flag: INTEGER_8 0
150   has_unread_character_flag: INTEGER_8 1
151   end_of_base64_flag:        INTEGER_8 2
152
153feature {}
154   alphabet: STRING "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
155
156   b2t (c: CHARACTER): INTEGER
157      require
158         c = '=' or else alphabet.has(c)
159      do
160         inspect
161            c
162         when '=' then
163            set_end_of_base64(True)
164         when 'A' .. 'Z' then
165            Result := c.code - 'A'.code
166         when 'a' .. 'z' then
167            Result := c.code - ('a'.code - 26)
168         when '0' .. '9' then
169            Result := c.code - ('0'.code - 52)
170         when '+' then
171            Result := 62
172         when '/' then
173            Result := 63
174         end
175      ensure
176         Result >= 0 and then Result < 64
177         c /= '=' implies alphabet.item(Result + 1) = c
178         c = '=' implies Result = 0
179      end
180
181end -- class BASE64_INPUT_STREAM
182--
183-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
184--
185-- Permission is hereby granted, free of charge, to any person obtaining a copy
186-- of this software and associated documentation files (the "Software"), to deal
187-- in the Software without restriction, including without limitation the rights
188-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
189-- copies of the Software, and to permit persons to whom the Software is
190-- furnished to do so, subject to the following conditions:
191--
192-- The above copyright notice and this permission notice shall be included in
193-- all copies or substantial portions of the Software.
194--
195-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
196-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
197-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
198-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
199-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
200-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
201-- THE SOFTWARE.