/[eiffelstudio]/branches/eth/eve/Src/contrib/library/network/protocol/http/src/http_media_type.e
ViewVC logotype

Contents of /branches/eth/eve/Src/contrib/library/network/protocol/http/src/http_media_type.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 92964 - (show annotations)
Fri Sep 20 05:41:23 2013 UTC (6 years ago) by jasonw
File size: 9164 byte(s)
<<Merged from trunk#92963.>>
1 note
2 description: "[
3 This class is to represent a media type
4
5 the Internet Media Type of the attached entity if the type
6 was provided via a "Content-type" field in the wgi_request header,
7 or if the server can determine it in the absence of a supplied
8 "Content-type" field. The syntax is the same as for the HTTP
9 "Content-Type" header field.
10
11 CONTENT_TYPE = "" | media-type
12 media-type = type "/" subtype *( ";" parameter)
13 type = token
14 subtype = token
15 parameter = attribute "=" value
16 attribute = token
17 value = token | quoted-string
18
19 The type, subtype, and parameter attribute names are not
20 case-sensitive. Parameter values MAY be case sensitive. Media
21 types and their use in HTTP are described in section 3.7 of
22 the HTTP/1.1 specification [8].
23
24 Example:
25
26 application/x-www-form-urlencoded
27 application/x-www-form-urlencoded; charset=UTF8
28
29 ]"
30 date: "$Date$"
31 revision: "$Revision$"
32 EIS: "name=Wikipedia/Media Type", "protocol=URI", "src=http://en.wikipedia.org/wiki/Internet_media_type"
33 EIS: "name=RFC2046", "protocol=URI", "src=http://tools.ietf.org/html/rfc2046"
34
35 class
36 HTTP_MEDIA_TYPE
37
38 inherit
39 DEBUG_OUTPUT
40
41 create
42 make,
43 make_from_string
44
45 feature {NONE} -- Initialization
46
47 make (a_type, a_subtype: READABLE_STRING_8)
48 -- Create Current based on `a_type/a_subtype'
49 require
50 not a_type.is_empty
51 not a_subtype.is_empty
52 do
53 type := a_type
54 subtype := a_subtype
55 ensure
56 has_no_error: not has_error
57 end
58
59 make_from_string (s: READABLE_STRING_8)
60 -- Create Current from `s'
61 -- if `s' does not respect the expected syntax, has_error is True
62 local
63 t: STRING_8
64 i,n: INTEGER
65 p: INTEGER
66 cl: CELL [INTEGER]
67 do
68 -- Ignore starting space (should not be any)
69 from
70 i := 1
71 n := s.count
72 until
73 i > n or not s[i].is_space
74 loop
75 i := i + 1
76 end
77 if i < n then
78 -- Look for semi colon as parameter separation
79 p := s.index_of (';', i)
80 if p > 0 then
81 t := s.substring (i, p - 1)
82 from
83 create cl.put (p)
84 i := p + 1
85 until
86 i >= n
87 loop
88 add_parameter_from_string (s, i, cl)
89 i := cl.item
90 end
91 else
92 t := s.substring (i, n)
93 end
94 -- Remove eventual trailing space
95 t.right_adjust
96
97 -- Extract type and subtype
98 p := t.index_of ('/', 1)
99 if p = 0 then
100 t.right_adjust
101 type := t
102 if t.same_string ("*") then
103 -- Flexible parser allowing "*" even if this is not really a valid media-type
104 -- let's interpret it as "*/*"
105 subtype := "*"
106 else
107 has_error := True
108 subtype := "*"
109 end
110 else
111 subtype := t.substring (p + 1, t.count)
112 type := t
113 t.keep_head (p - 1)
114 end
115 else
116 has_error := True
117 type := ""
118 subtype := type
119 end
120 ensure
121 not has_error implies (create {HTTP_CONTENT_TYPE}.make_from_string (string)).same_string (string)
122 end
123
124 feature -- Status report
125
126 has_error: BOOLEAN
127 -- Current has error?
128 --| Mainly in relation with `make_from_string'
129
130 feature -- Access
131
132 type: READABLE_STRING_8
133 -- Main type
134
135 subtype: READABLE_STRING_8
136 -- Sub type
137
138 has_parameter (a_name: READABLE_STRING_8): BOOLEAN
139 -- Has Current a parameter?
140 do
141 if attached parameters as plst then
142 Result := plst.has (a_name)
143 end
144 end
145
146 parameter (a_name: READABLE_STRING_8): detachable READABLE_STRING_8
147 -- Value for eventual parameter named `a_name'.
148 do
149 if attached parameters as plst then
150 Result := plst.item (a_name)
151 end
152 end
153
154 parameters: detachable HASH_TABLE [READABLE_STRING_8, READABLE_STRING_8]
155 -- Parameters
156
157 feature -- Conversion
158
159 string: READABLE_STRING_8
160 -- String representation of type/subtype; attribute=value
161 local
162 res: like internal_string
163 do
164 res := internal_string
165 if res = Void then
166 create res.make_from_string (simple_type)
167 if attached parameters as plst then
168 across
169 plst as p
170 loop
171 res.append_character (';')
172 res.append_character (' ')
173 res.append (p.key)
174 res.append_character ('=')
175 res.append_character ('%"')
176 res.append (p.item)
177 res.append_character ('%"')
178 end
179 end
180 internal_string := res
181 end
182 Result := res
183 end
184
185 simple_type: READABLE_STRING_8
186 -- String representation of type/subtype
187 local
188 res: like internal_simple_type
189 s: like subtype
190 do
191 res := internal_simple_type
192 if res = Void then
193 create res.make_from_string (type)
194 s := subtype
195 if not s.is_empty then
196 check has_error: has_error end
197 -- Just in case not is_valid, we keep in `type' the original string
198 res.append_character ('/')
199 res.append (s)
200 end
201 internal_simple_type := res
202 end
203 Result := res
204 end
205
206 feature -- Status report
207
208 same_as (other: HTTP_CONTENT_TYPE): BOOLEAN
209 -- Current has same type/subtype and parameters as `other'?
210 local
211 plst,oplst: like parameters
212 do
213 Result := other.type.same_string (other.type) and then
214 other.subtype.same_string (other.subtype)
215 if Result then
216 plst := parameters
217 oplst := other.parameters
218 if plst = oplst then
219 elseif plst = Void then
220 Result := False -- since oplst /= Void
221 elseif oplst /= Void and then plst.count = oplst.count then
222 across
223 plst as p
224 until
225 not Result
226 loop
227 Result := attached oplst.item (p.key) as op_value and then p.item.same_string (op_value)
228 end
229 else
230 Result := False
231 end
232 end
233 end
234
235 same_simple_type (s: READABLE_STRING_8): BOOLEAN
236 -- Current has same type/subtype string representation as `s'?
237 do
238 Result := simple_type.same_string (s)
239 end
240
241 same_string (s: READABLE_STRING_8): BOOLEAN
242 -- Current has same string representation as `s'?
243 do
244 Result := string.same_string (s)
245 end
246
247 feature -- Element change
248
249 add_parameter (a_name: READABLE_STRING_8; a_value: READABLE_STRING_8)
250 -- Set parameter for `a_name' to `a_value'
251 local
252 plst: like parameters
253 do
254 plst := parameters
255 if plst = Void then
256 create plst.make (1)
257 parameters := plst
258 end
259 plst.force (a_value, a_name)
260 internal_string := Void
261 end
262
263 remove_parameter (a_name: READABLE_STRING_8)
264 -- Remove parameter named `a_name'
265 do
266 if attached parameters as plst then
267 plst.prune (a_name)
268 if plst.is_empty then
269 parameters := Void
270 end
271 end
272 internal_string := Void
273 end
274
275 feature {NONE} -- Implementation
276
277 add_parameter_from_string (s: READABLE_STRING_8; start_index: INTEGER; out_end_index: CELL [INTEGER])
278 -- Add parameter from string " attribute=value "
279 -- and put in `out_end_index' the index after found parameter.
280 local
281 n: INTEGER
282 pn,pv: STRING_8
283 i: INTEGER
284 p, q: INTEGER
285 err: BOOLEAN
286 do
287 n := s.count
288 -- Skip spaces
289 from
290 i := start_index
291 until
292 i > n or not s[i].is_space
293 loop
294 i := i + 1
295 end
296 if s[i] = ';' then
297 -- empty parameter
298 out_end_index.replace (i + 1)
299 elseif i < n then
300 p := s.index_of ('=', i)
301 if p > 0 then
302 pn := s.substring (i, p - 1)
303 if p >= n then
304 pv := ""
305 out_end_index.replace (n + 1)
306 else
307 if s[p+1] = '%"' then
308 q := s.index_of ('%"', p + 2)
309 if q > 0 then
310 pv := s.substring (p + 2, q - 1)
311 from
312 i := q + 1
313 until
314 i > n or not s[i].is_space
315 loop
316 i := i + 1
317 end
318 if s[i] = ';' then
319 i := i + 1
320 end
321 out_end_index.replace (i)
322 else
323 err := True
324 pv := ""
325 -- missing closing double quote.
326 end
327 else
328 q := s.index_of (';', p + 1)
329 if q = 0 then
330 q := n + 1
331 end
332 pv := s.substring (p + 1, q - 1)
333 out_end_index.replace (q + 1)
334 end
335 pv.right_adjust
336 if not err then
337 add_parameter (pn, pv)
338 end
339 end
340 else
341 -- expecting: attribute "=" value
342 err := True
343 end
344 end
345 if err then
346 out_end_index.replace (n + 1)
347 end
348 has_error := has_error or err
349 ensure
350 entry_processed: out_end_index.item > start_index
351 end
352
353 feature {NONE} -- Internal
354
355 internal_string: detachable STRING_8
356
357 internal_simple_type: detachable STRING_8
358
359 feature -- Status report
360
361 debug_output: STRING
362 -- String that should be displayed in debugger to represent `Current'.
363 do
364 if type /= Void and subtype /= Void then
365 Result := type + "/" + subtype
366 if attached parameters as plst then
367 across
368 plst as p
369 loop
370 Result.append ("; " + p.key + "=" + "%"" + p.item + "%"")
371 end
372 end
373 else
374 Result := ""
375 end
376 end
377
378 invariant
379 type_and_subtype_not_empty: not has_error implies not type.is_empty and not subtype.is_empty
380
381 note
382 copyright: "2011-2013, Jocelyn Fiat, Eiffel Software and others"
383 license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
384 source: "[
385 Eiffel Software
386 5949 Hollister Ave., Goleta, CA 93117 USA
387 Telephone 805-685-1006, Fax 805-685-6869
388 Website http://www.eiffel.com
389 Customer support http://support.eiffel.com
390 ]"
391 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23