Added JSON_ENCODER
This commit is contained in:
180
library/text/encoder/src/json_encoder.e
Normal file
180
library/text/encoder/src/json_encoder.e
Normal file
@@ -0,0 +1,180 @@
|
||||
note
|
||||
description: "[
|
||||
Summary description for {JSON_ENCODER}.
|
||||
|
||||
see: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
|
||||
]"
|
||||
legal: "See notice at end of class."
|
||||
status: "See notice at end of class."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
JSON_ENCODER
|
||||
|
||||
inherit
|
||||
ENCODER [STRING_32, STRING_8]
|
||||
|
||||
PLATFORM
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
name: READABLE_STRING_8
|
||||
do
|
||||
create {IMMUTABLE_STRING_8} Result.make_from_string ("JSON-encoded")
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
has_error: BOOLEAN
|
||||
|
||||
feature -- Encoder
|
||||
|
||||
encoded_string (s: STRING_32): STRING_8
|
||||
-- JSON-encoded value of `s'.
|
||||
local
|
||||
i, j, n: INTEGER
|
||||
uc: CHARACTER_32
|
||||
c: CHARACTER_8
|
||||
h: STRING_8
|
||||
do
|
||||
has_error := False
|
||||
create Result.make (s.count + s.count // 10)
|
||||
n := s.count
|
||||
from i := 1 until i > n loop
|
||||
uc := s.item (i)
|
||||
if uc.is_character_8 then
|
||||
c := uc.to_character_8
|
||||
inspect c
|
||||
when '%"' then Result.append_string ("\%"")
|
||||
when '\' then Result.append_string ("\\")
|
||||
when '%R' then Result.append_string ("\r")
|
||||
when '%N' then Result.append_string ("\n")
|
||||
else
|
||||
Result.extend (c)
|
||||
end
|
||||
else
|
||||
Result.append ("\u")
|
||||
h := uc.code.to_hex_string
|
||||
from
|
||||
j := 1
|
||||
until
|
||||
j <= h.count and then h.item (j) /= '0'
|
||||
loop
|
||||
j := j + 1
|
||||
end
|
||||
h := h.substring (j, h.count)
|
||||
from
|
||||
until
|
||||
h.count >= 4
|
||||
loop
|
||||
h.prepend_integer (0)
|
||||
end
|
||||
check h.count = 4 end
|
||||
Result.append (h)
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Decoder
|
||||
|
||||
decoded_string (v: STRING_8): STRING_32
|
||||
-- The XML-encoded equivalent of the given string
|
||||
local
|
||||
i, n: INTEGER
|
||||
c: CHARACTER
|
||||
cl_i: CELL [INTEGER]
|
||||
hex: STRING
|
||||
hexconv: detachable HEXADECIMAL_STRING_TO_INTEGER_CONVERTER
|
||||
do
|
||||
has_error := False
|
||||
n := v.count
|
||||
create Result.make (n)
|
||||
create cl_i.put (0)
|
||||
from i := 1 until i > n loop
|
||||
c := v.item (i)
|
||||
if c = '\' then
|
||||
if i < n then
|
||||
inspect v.item (i+1)
|
||||
when '\' then
|
||||
Result.append_character ('\')
|
||||
i := i + 2
|
||||
when '%"' then
|
||||
Result.append_character ('%"')
|
||||
i := i + 2
|
||||
when 'n' then
|
||||
Result.append_character ('%N')
|
||||
i := i + 2
|
||||
when 'r' then
|
||||
Result.append_character ('%R')
|
||||
i := i + 2
|
||||
when 'u' then
|
||||
hex := v.substring (i+2, i+2+4 - 1)
|
||||
if hex.count = 4 then
|
||||
Result.append_code (hex_to_natural_32 (hex))
|
||||
-- Result.append_string ("\u" + hex) --hex.to_integer_32)
|
||||
end
|
||||
i := i + 2 + 4
|
||||
else
|
||||
Result.append_character ('\')
|
||||
i := i + 1
|
||||
end
|
||||
else
|
||||
Result.append_character ('\')
|
||||
i := i + 1
|
||||
end
|
||||
else
|
||||
Result.append_character (c.to_character_32)
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
hex_to_natural_32 (s: STRING): NATURAL_32
|
||||
-- Hexadecimal string `s' converted to NATURAL_32 value
|
||||
require
|
||||
s_not_void: s /= Void
|
||||
local
|
||||
i, nb: INTEGER
|
||||
char: CHARACTER
|
||||
do
|
||||
nb := s.count
|
||||
|
||||
if nb >= 2 and then s.item (2) = 'x' then
|
||||
i := 3
|
||||
else
|
||||
i := 1
|
||||
end
|
||||
|
||||
from
|
||||
until
|
||||
i > nb
|
||||
loop
|
||||
Result := Result * 16
|
||||
char := s.item (i)
|
||||
if char >= '0' and then char <= '9' then
|
||||
Result := Result + (char |-| '0').to_natural_32
|
||||
else
|
||||
Result := Result + (char.lower |-| 'a' + 10).to_natural_32
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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
|
||||
47
library/text/encoder/tests/test_json_encoder.e
Normal file
47
library/text/encoder/tests/test_json_encoder.e
Normal file
@@ -0,0 +1,47 @@
|
||||
note
|
||||
description: "[
|
||||
Eiffel tests that can be executed by testing tool.
|
||||
]"
|
||||
author: "EiffelStudio test wizard"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
testing: "type/manual"
|
||||
|
||||
class
|
||||
TEST_JSON_ENCODER
|
||||
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
|
||||
feature -- Test routines
|
||||
|
||||
test_json_encoded_encoder
|
||||
note
|
||||
testing: "json-encoded"
|
||||
do
|
||||
test_json_encoded_encoding ({STRING_32}"il était une fois %"Ni & Hao%" (你好) \a\b\c")
|
||||
end
|
||||
|
||||
test_json_encoded_encoding (s: STRING_32)
|
||||
local
|
||||
u: STRING_32
|
||||
e: STRING_8
|
||||
b: JSON_ENCODER
|
||||
do
|
||||
create b
|
||||
e := b.encoded_string (s)
|
||||
u := b.decoded_string (e)
|
||||
assert ("decoded encoded string is same", u ~ s)
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2012, 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