2 * Copyright (C) 2010 Nokia Corporation.
4 * Author: Zeeshan Ali (Khattak) <zeeshan.ali@nokia.com>
5 * <zeeshanak@gnome.org>
7 * This file is part of Rygel.
9 * Rygel is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * Rygel is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 private errordomain Rygel.TestError {
28 private class Rygel.HTTPTranscodeHandler : GLib.Object {}
30 public class Rygel.MediaObject : GLib.Object {
31 public int64 size = -1;
34 public class Rygel.MediaContainer : MediaObject {
37 private abstract class Rygel.MediaItem : MediaObject {
38 public bool is_live_stream () {
43 private class Rygel.AudioItem : MediaItem {
44 public int64 duration = 2048;
47 private class Rygel.Thumbnail : GLib.Object {}
48 private class Rygel.Subtitle : GLib.Object {}
50 private class Rygel.HTTPGet : GLib.Object {
51 public const string ITEM_URI = "http://DoesntMatterWhatThisIs";
53 public Soup.Message msg;
54 public MediaObject object;
55 public Thumbnail thumbnail;
56 public Subtitle subtitle;
58 public HTTPTranscodeHandler handler;
60 public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
61 this.msg = new Soup.Message ("HTTP", ITEM_URI);
62 this.object = new AudioItem ();
63 this.handler = new HTTPTranscodeHandler ();
64 this.thumbnail = thumbnail;
65 this.subtitle = subtitle;
68 public HTTPGet.seek_start (int64 start,
71 this (thumbnail, subtitle);
73 this.add_headers (start, -1);
76 public HTTPGet.seek_stop (int64 stop,
79 this (thumbnail, subtitle);
81 this.add_headers (0, stop);
84 public HTTPGet.seek_start_stop (int64 start,
88 this (thumbnail, subtitle);
90 this.add_headers (start, stop);
93 public HTTPGet.seek_strings (string start,
97 this (thumbnail, subtitle);
99 this.add_string_headers (start, stop);
102 private void add_headers (int64 start, int64 stop) requires (start >= 0) {
103 var stop_str = (stop > 0)? stop.to_string (): "";
104 var range = "npt=" + start.to_string () + "-" + stop_str;
105 this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
108 private void add_string_headers (string start, string stop) {
109 var range = "npt=" + start + "-" + stop;
110 this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
114 private class Rygel.HTTPTimeSeekTest : GLib.Object {
115 private Regex range_regex;
118 TEST_SECONDS_PARSING,
122 private TestType test_type;
124 public static int main (string[] args) {
126 var test = new HTTPTimeSeekTest ();
129 /* TODO: Nothing throws this exception. Should it?
130 } catch (TestError.SKIP error) {
133 } catch (Error error) {
134 critical ("%s", error.message);
142 public void run () throws HTTPSeekError {
143 var thumbnails = new Thumbnail[] { null, new Thumbnail () };
144 var subtitles = new Subtitle[] { null, new Subtitle () };
146 foreach (var thumbnail in thumbnails) {
147 foreach (var subtitle in subtitles) {
148 this.test_type = TestType.TEST_SECONDS_PARSING;
149 this.test_no_seek (thumbnail, subtitle);
150 this.test_start_only_seek (thumbnail, subtitle);
151 this.test_stop_only_seek (thumbnail, subtitle);
152 this.test_start_stop_seek (thumbnail, subtitle);
153 this.test_type = TestType.TEST_HHMMSS_PARSING;
154 this.test_start_only_seek (thumbnail, subtitle);
155 this.test_stop_only_seek (thumbnail, subtitle);
156 this.test_start_stop_seek (thumbnail, subtitle);
157 this.test_type = TestType.TEST_MIXED_PARSING;
158 this.test_start_stop_seek (thumbnail, subtitle);
163 private HTTPTimeSeekTest () {
164 var expression = "npt=[0-9]+\\.[0-9][0-9][0-9]-" +
165 "[0-9]+\\.[0-9][0-9][0-9]/" +
166 "[0-9]+\\.[0-9][0-9][0-9]";
169 this.range_regex = new Regex (expression, RegexCompileFlags.CASELESS);
170 } catch (RegexError error) {
171 // This means that it is not a regular expression
172 assert_not_reached ();
176 private void test_no_seek (Thumbnail? thumbnail,
177 Subtitle? subtitle) throws HTTPSeekError {
178 var request = new HTTPGet (thumbnail, subtitle);
179 var audio_item = request.object as AudioItem;
180 this.test_seek (request,
182 audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
185 private void test_start_only_seek (Thumbnail? thumbnail,
187 throws HTTPSeekError {
188 HTTPGet request = null;
190 switch (this.test_type) {
191 case TestType.TEST_SECONDS_PARSING:
192 request = new HTTPGet.seek_start (128, thumbnail, subtitle);
196 case TestType.TEST_HHMMSS_PARSING:
197 request = new HTTPGet.seek_strings ("00:02:08.000", "", thumbnail, subtitle);
202 var audio_item = request.object as AudioItem;
203 this.test_seek (request,
204 128 * TimeSpan.SECOND,
205 audio_item.duration * TimeSpan.SECOND - TimeSpan.MILLISECOND);
208 private void test_stop_only_seek (Thumbnail? thumbnail,
210 throws HTTPSeekError {
211 HTTPGet request = null;
213 switch (this.test_type) {
214 case TestType.TEST_SECONDS_PARSING:
215 request = new HTTPGet.seek_stop (128, thumbnail, subtitle);
219 case TestType.TEST_HHMMSS_PARSING:
220 request = new HTTPGet.seek_strings ("00:00:00.000",
228 this.test_seek (request, 0, 128 * TimeSpan.SECOND);
231 private void test_start_stop_seek (Thumbnail? thumbnail,
233 throws HTTPSeekError {
234 HTTPGet request = null;
236 switch (this.test_type) {
237 case TestType.TEST_SECONDS_PARSING:
238 request = new HTTPGet.seek_start_stop (128,
245 case TestType.TEST_HHMMSS_PARSING:
246 request = new HTTPGet.seek_strings ("00:02:08.000",
253 case TestType.TEST_MIXED_PARSING:
254 request = new HTTPGet.seek_strings ("00:02:08.000",
263 this.test_seek (request, 128 * TimeSpan.SECOND, 256 * TimeSpan.SECOND);
266 private void test_seek (HTTPGet request,
268 int64 stop) throws HTTPSeekError {
269 assert (HTTPTimeSeek.needed (request));
271 var seek = new HTTPTimeSeek (request);
272 seek.add_response_headers ();
274 assert (seek != null);
275 assert (seek.start == start);
276 assert (seek.stop == stop);
277 assert (seek.length == seek.stop + TimeSpan.MILLISECOND - seek.start);
279 var audio_item = request.object as AudioItem;
280 assert (seek.total_length == audio_item.duration * TimeSpan.SECOND);
282 var header = request.msg.response_headers.get_one
283 ("TimeSeekRange.dlna.org");
284 assert (header != null);
285 assert (this.range_regex.match (header));
287 /* TODO: This is just here to avoid a warning about
288 * requested() not being used.
289 * How should this really be tested?
290 * Sometimes the result here is true, and sometimes it is false.
292 /* bool result = */ HTTPTimeSeek.requested(request);