First integration of the new GW_ design more centralized on connector, and does not require specific feature on GW_APPLICATION depending on the connector.
So this is really more flexible this way, and much easier to write application supporting CGI, FCGI, Nino and so on .. as demonstrated in hello_world This is a first version, more will come later, mainly migrating from Eiffel Web Reloaded to this Eiffel Web Framework project.
This commit is contained in:
218
library/text/encoder/src/base64.e
Normal file
218
library/text/encoder/src/base64.e
Normal file
@@ -0,0 +1,218 @@
|
||||
note
|
||||
description: "Summary description for {BASE64}."
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
BASE64
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_8, STRING_8]
|
||||
redefine
|
||||
valid_encoded_string
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: STRING = "base64"
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
valid_encoded_string (v: STRING): BOOLEAN
|
||||
do
|
||||
Result := Precursor (v) and then
|
||||
(v.is_empty or v.count >= 4)
|
||||
end
|
||||
|
||||
feature -- base64 encoder
|
||||
|
||||
encoded_string (s: STRING): STRING_8
|
||||
-- base64 encoded value of `s'.
|
||||
local
|
||||
i,n: INTEGER
|
||||
c: INTEGER
|
||||
f: SPECIAL [BOOLEAN]
|
||||
base64chars: STRING_8
|
||||
do
|
||||
has_error := False
|
||||
base64chars := character_map
|
||||
from
|
||||
n := s.count
|
||||
i := (8 * n) \\ 6
|
||||
if i > 0 then
|
||||
create f.make_filled (False, 8 * n + (6 - i))
|
||||
else
|
||||
create f.make_filled (False, 8 * n)
|
||||
end
|
||||
i := 0
|
||||
until
|
||||
i > n - 1
|
||||
loop
|
||||
c := s.item (i + 1).code
|
||||
f[8 * i + 0] := c.bit_test(7)
|
||||
f[8 * i + 1] := c.bit_test(6)
|
||||
f[8 * i + 2] := c.bit_test(5)
|
||||
f[8 * i + 3] := c.bit_test(4)
|
||||
f[8 * i + 4] := c.bit_test(3)
|
||||
f[8 * i + 5] := c.bit_test(2)
|
||||
f[8 * i + 6] := c.bit_test(1)
|
||||
f[8 * i + 7] := c.bit_test(0)
|
||||
i := i + 1
|
||||
end
|
||||
from
|
||||
i := 0
|
||||
n := f.count
|
||||
create Result.make (n // 6)
|
||||
until
|
||||
i > n - 1
|
||||
loop
|
||||
c := 0
|
||||
if f[i + 0] then c := c + 0x20 end
|
||||
if f[i + 1] then c := c + 0x10 end
|
||||
if f[i + 2] then c := c + 0x8 end
|
||||
if f[i + 3] then c := c + 0x4 end
|
||||
if f[i + 4] then c := c + 0x2 end
|
||||
if f[i + 5] then c := c + 0x1 end
|
||||
Result.extend (base64chars.item (c + 1))
|
||||
i := i + 6
|
||||
end
|
||||
|
||||
i := s.count \\ 3
|
||||
if i > 0 then
|
||||
from until i > 2 loop
|
||||
Result.extend ('=')
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING): STRING
|
||||
-- base64 decoded value of `s'.
|
||||
local
|
||||
byte_count: INTEGER
|
||||
pos, n: INTEGER
|
||||
byte1, byte2, byte3, byte4, tmp1, tmp2: INTEGER
|
||||
done: BOOLEAN
|
||||
base64chars: STRING_8
|
||||
c: CHARACTER
|
||||
do
|
||||
has_error := False
|
||||
base64chars := character_map
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
|
||||
from
|
||||
pos := 0
|
||||
invariant
|
||||
n = v.count
|
||||
until
|
||||
(pos >= n) or done
|
||||
loop
|
||||
byte_count := 0
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
byte1 := base64chars.index_of (v[pos], 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
byte2 := base64chars.index_of (v[pos], 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
c := v[pos]
|
||||
if c /= '=' then
|
||||
byte3 := base64chars.index_of (c, 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
end
|
||||
|
||||
pos := next_encoded_character_position (v, pos)
|
||||
if pos <= n then
|
||||
c := v[pos]
|
||||
if c /= '=' then
|
||||
byte4 := base64chars.index_of (c, 1) - 1
|
||||
byte_count := byte_count + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- pos := pos + byte_count
|
||||
|
||||
done := byte_count < 4
|
||||
|
||||
if byte_count > 1 then
|
||||
tmp1 := byte1.bit_shift_left (2) & 0xff
|
||||
tmp2 := byte2.bit_shift_right (4) & 0x03
|
||||
Result.extend ((tmp1 | tmp2).to_character_8)
|
||||
if byte_count > 2 then
|
||||
tmp1 := byte2.bit_shift_left (4) & 0xff
|
||||
tmp2 := byte3.bit_shift_right (2) & 0x0f
|
||||
Result.extend ((tmp1 | tmp2).to_character_8)
|
||||
if byte_count > 3 then
|
||||
Result.extend(
|
||||
((byte4 | byte3.bit_shift_left(6))& 0xff).to_character_8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
next_encoded_character_position (v: STRING; from_pos: INTEGER): INTEGER
|
||||
-- Next encoded character position from `v' starting after `from_pos' index.
|
||||
-- Result over `v.count' denodes no remaining decodable position
|
||||
--| Mainly to handle base64 encoded text on multiple line
|
||||
--| thus we just skip %N, %R and eventually all blanks
|
||||
require
|
||||
v_attached: v /= Void
|
||||
valid_from_pos: v.valid_index (from_pos + 1)
|
||||
local
|
||||
n: INTEGER
|
||||
l_map: like character_map
|
||||
do
|
||||
l_map := character_map
|
||||
from
|
||||
Result := from_pos + 1
|
||||
n := v.count
|
||||
until
|
||||
in_character_map (v[Result]) or Result > n
|
||||
loop
|
||||
Result := Result + 1
|
||||
end
|
||||
ensure
|
||||
result_after_from_pos: Result > from_pos
|
||||
end
|
||||
|
||||
in_character_map (c: CHARACTER): BOOLEAN
|
||||
-- Is a character map element?
|
||||
do
|
||||
inspect c
|
||||
when 'A' .. 'Z', 'a' .. 'z', '0'..'9', '+', '/', '=' then
|
||||
Result := True
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Constants
|
||||
|
||||
character_map: STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2011, 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
|
||||
Reference in New Issue
Block a user