@@ -61,110 +61,190 @@ feature -- Access
6161 item : STRING
6262 -- Contents with escaped entities if any
6363
64+ feature -- Conversion
65+
6466 unescaped_string_ 8 : STRING_ 8
65- -- Unescaped string from `item'
67+ -- Unescaped string from `item'.
68+ -- | note: valid only if `item' does not encode any unicode character.
69+ local
70+ s : like item
71+ do
72+ s := item
73+ create Result .make (s .count )
74+ unescape_to_string_ 8 (Result )
75+ end
76+
77+ unescaped_string_ 32 : STRING_ 32
78+ -- Unescaped string 32 from `item'
79+ -- | some encoders uses UTF-8 , and not the recommended pure json encoding
80+ -- | thus, let's support the UTF-8 encoding during decoding.
81+ local
82+ s : READABLE_STRING_ 8
83+ do
84+ s := item
85+ create Result .make (s .count )
86+ unescape_to_string_ 32 (Result )
87+ end
88+
89+ representation : STRING
90+ -- String representation of `item' with escaped entities if any
91+ do
92+ create Result .make (item .count + 2 )
93+ Result .append_character ('%" ')
94+ Result.append (item)
95+ Result.append_character ('%" ')
96+ end
97+
98+ unescape_to_string_ 8 (a_output : STRING_ 8 )
99+ -- Unescape string `item' into `a_output'.
100+ -- | note: valid only if `item' does not encode any unicode character.
66101 local
67102 s : like item
68103 i , n : INTEGER
69104 c : CHARACTER
70105 do
71106 s := item
72107 n := s .count
73- create Result .make (n )
74108 from i := 1 until i > n loop
75109 c := s [i ]
76110 if c = '\' then
77111 if i < n then
78112 inspect s [i +1 ]
79113 when '\' then
80- Result .append_character ('\')
114+ a_output .append_character ('\')
81115 i := i + 2
82116 when '%" ' then
83- Result.append_character ('%" ')
117+ a_output.append_character ('%" ')
118+ i := i + 2
119+ when 'b ' then
120+ a_output .append_character ('%B ')
121+ i := i + 2
122+ when 'f ' then
123+ a_output .append_character ('%F ')
84124 i := i + 2
85125 when 'n ' then
86- Result .append_character ('%N ')
126+ a_output .append_character ('%N ')
87127 i := i + 2
88128 when 'r ' then
89- Result .append_character ('%R ')
129+ a_output .append_character ('%R ')
130+ i := i + 2
131+ when 't ' then
132+ a_output .append_character ('%T ')
90133 i := i + 2
91134 when 'u ' then
92135 -- | Leave Unicode \uXXXX unescaped
93- Result .append_character ('\')
136+ a_output .append_character ('\')
94137 i := i + 1
95138 else
96- Result .append_character ('\')
139+ a_output .append_character ('\')
97140 i := i + 1
98141 end
99142 else
100- Result .append_character ('\')
143+ a_output .append_character ('\')
101144 i := i + 1
102145 end
103146 else
104- Result .append_character (c )
147+ a_output .append_character (c )
105148 i := i + 1
106149 end
107150 end
108151 end
109152
110- unescaped_string_ 32 : STRING_ 32
111- -- Unescaped string 32 from `item'
153+ unescape_to_string_ 32 (a_output : STRING_ 32 )
154+ -- Unescape string `item' into `a_output' string 32.
155+ -- | some encoders uses UTF-8 , and not the recommended pure json encoding
156+ -- | thus, let's support the UTF-8 encoding during decoding.
112157 local
113- s : like item
158+ s : READABLE_STRING_ 8
114159 i , n : INTEGER
115- c : CHARACTER
116- hex : STRING
160+ c : NATURAL_ 32
161+ ch : CHARACTER_ 8
162+ hex : READABLE_STRING_ 8
117163 do
118164 s := item
119165 n := s .count
120- create Result .make (n )
121166 from i := 1 until i > n loop
122- c := s [ i ]
123- if c = '\' then
167+ ch := s . item ( i )
168+ if ch = '\' then
124169 if i < n then
125170 inspect s [i +1 ]
126171 when '\' then
127- Result .append_character ('\')
172+ a_output .append_character ('\')
128173 i := i + 2
129174 when '%" ' then
130- Result.append_character ('%" ')
175+ a_output.append_character ('%" ')
176+ i := i + 2
177+ when 'b ' then
178+ a_output .append_character ('%B ')
179+ i := i + 2
180+ when 'f ' then
181+ a_output .append_character ('%F ')
131182 i := i + 2
132183 when 'n ' then
133- Result .append_character ('%N ')
184+ a_output .append_character ('%N ')
134185 i := i + 2
135186 when 'r ' then
136- Result .append_character ('%R ')
187+ a_output .append_character ('%R ')
188+ i := i + 2
189+ when 't ' then
190+ a_output .append_character ('%T ')
137191 i := i + 2
138192 when 'u ' then
139- hex := s .substring (i + 2 , i + 2 + 4 - 1 )
193+ hex := s .substring (i + 2 , i + 5 ) -- i+2 , i+2+4-1
140194 if hex .count = 4 then
141- Result .append_code (hexadecimal_to_natural_ 32 (hex ))
195+ a_output .append_code (hexadecimal_to_natural_ 32 (hex ))
142196 end
143- i := i + 2 + 4
197+ i := i + 6 -- i +2 + 4
144198 else
145- Result .append_character ('\')
199+ a_output .append_character ('\')
146200 i := i + 1
147201 end
148202 else
149- Result .append_character ('\')
203+ a_output .append_character ('\')
150204 i := i + 1
151205 end
152206 else
153- Result .append_character (c .to_character_ 32 )
207+ c := ch .natural_ 32 _code
208+ if c <= 0 x 7 F then
209+ -- 0xxxxxxx
210+ check ch = c .to_character_ 32 end
211+ a_output .append_character (ch )
212+ elseif c <= 0 xDF then
213+ -- 110xxxxx 10xxxxxx
214+ i := i + 1
215+ if i <= n then
216+ a_output .append_code (
217+ ((c & 0 x 1 F ) |<< 6 ) |
218+ (s .code (i ) & 0 x 3 F )
219+ )
220+ end
221+ elseif c <= 0 xEF then
222+ -- 1110xxxx 10xxxxxx 10xxxxxx
223+ i := i + 2
224+ if i <= n then
225+ a_output .append_code (
226+ ((c & 0 xF ) |<< 12 ) |
227+ ((s .code (i - 1 ) & 0 x 3 F ) |<< 6 ) |
228+ (s .code (i ) & 0 x 3 F )
229+ )
230+ end
231+ elseif c <= 0 xF 7 then
232+ -- 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
233+ i := i + 3
234+ if i <= n then
235+ a_output .append_code (
236+ ((c & 0 x 7 ) |<< 18 ) |
237+ ((s .code (i - 2 ) & 0 x 3 F ) |<< 12 ) |
238+ ((s .code (i - 1 ) & 0 x 3 F ) |<< 6 ) |
239+ (s .code (i ) & 0 x 3 F )
240+ )
241+ end
242+ end
154243 i := i + 1
155244 end
156245 end
157246 end
158247
159- representation : STRING
160- -- String representation of `item' with escaped entities if any
161- do
162- create Result .make (item .count + 2 )
163- Result .append_character ('%" ')
164- Result.append (item)
165- Result.append_character ('%" ')
166- end
167-
168248feature -- Visitor pattern
169249
170250 accept (a_visitor : JSON_VISITOR )
@@ -213,8 +293,18 @@ feature {NONE} -- Implementation
213293
214294 is_hexadecimal (s : READABLE_STRING_ 8 ): BOOLEAN
215295 -- Is `s' an hexadecimal value?
296+ local
297+ i : INTEGER
216298 do
217- Result := across s as scur all scur .item .is_hexa_digit end
299+ from
300+ Result := True
301+ i := 1
302+ until
303+ i > s .count or not Result
304+ loop
305+ Result := s [i ].is_hexa_digit
306+ i := i + 1
307+ end
218308 end
219309
220310 hexadecimal_to_natural_ 32 (s : READABLE_STRING_ 8 ): NATURAL_ 32
@@ -264,8 +354,11 @@ feature {NONE} -- Implementation
264354 inspect c
265355 when '%" ' then Result.append_string (" \%" " )
266356 when '\' then Result .append_string (" \\ " )
267- when '%R ' then Result .append_string (" \r " )
357+ when '%B ' then Result .append_string (" \b " )
358+ when '%F ' then Result .append_string (" \f " )
268359 when '%N ' then Result .append_string (" \n " )
360+ when '%R ' then Result .append_string (" \r " )
361+ when '%T ' then Result .append_string (" \t " )
269362 else
270363 Result .extend (c )
271364 end
@@ -292,8 +385,11 @@ feature {NONE} -- Implementation
292385 inspect c
293386 when '%" ' then Result.append_string (" \%" " )
294387 when '\' then Result .append_string (" \\ " )
295- when '%R ' then Result .append_string (" \r " )
388+ when '%B ' then Result .append_string (" \b " )
389+ when '%F ' then Result .append_string (" \f " )
296390 when '%N ' then Result .append_string (" \n " )
391+ when '%R ' then Result .append_string (" \r " )
392+ when '%T ' then Result .append_string (" \t " )
297393 else
298394 Result .extend (c )
299395 end
0 commit comments