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.
26 private errordomain Rygel.TestError {
30 private class Rygel.HTTPTranscodeHandler : GLib.Object {}
32 private abstract class Rygel.MediaItem : GLib.Object {
33 public int64 size = -1;
35 public bool is_live_stream () {
40 private class Rygel.AudioItem : MediaItem {
41 public int64 duration = 2048;
44 private class Rygel.Thumbnail : GLib.Object {}
45 private class Rygel.Subtitle : GLib.Object {}
47 private class Rygel.HTTPGet : GLib.Object {
48 public const string ITEM_URI = "http://DoesntMatterWhatThisIs";
50 public Soup.Message msg;
51 public MediaItem item;
52 public Thumbnail thumbnail;
53 public Subtitle subtitle;
55 public HTTPTranscodeHandler handler;
57 public HTTPGet (Thumbnail? thumbnail, Subtitle? subtitle) {
58 this.msg = new Soup.Message ("HTTP", ITEM_URI);
59 this.item = new AudioItem ();
60 this.handler = new HTTPTranscodeHandler ();
61 this.thumbnail = thumbnail;
62 this.subtitle = subtitle;
65 public HTTPGet.seek_start (int64 start,
68 this (thumbnail, subtitle);
70 this.add_headers (start, -1);
73 public HTTPGet.seek_stop (int64 stop,
76 this (thumbnail, subtitle);
78 this.add_headers (0, stop);
81 public HTTPGet.seek_start_stop (int64 start,
85 this (thumbnail, subtitle);
87 this.add_headers (start, stop);
90 public HTTPGet.seek_hhmmss (string start,
94 this (thumbnail, subtitle);
96 this.add_headers_hhmmss (start, stop);
99 private void add_headers (int64 start, int64 stop) requires (start >= 0) {
100 var stop_str = (stop > 0)? stop.to_string (): "";
101 var range = "npt=" + start.to_string () + "-" + stop_str;
102 this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
105 private void add_headers_hhmmss (string start, string stop) {
106 var range = "npt=" + start + "-" + stop;
107 this.msg.request_headers.append ("TimeSeekRange.dlna.org", range);
111 private class Rygel.HTTPTimeSeekTest : GLib.Object {
112 private Regex range_regex;
113 private bool test_hhmmss;
115 public static int main (string[] args) {
117 var test = new HTTPTimeSeekTest ();
120 } catch (TestError.SKIP error) {
122 } catch (Error error) {
123 critical ("%s", error.message);
131 public void run () throws HTTPSeekError {
132 var thumbnails = new Thumbnail[] { null, new Thumbnail () };
133 var subtitles = new Subtitle[] { null, new Subtitle () };
135 foreach (var thumbnail in thumbnails) {
136 foreach (var subtitle in subtitles) {
137 this.test_hhmmss = false;
138 this.test_no_seek (thumbnail, subtitle);
139 this.test_start_only_seek (thumbnail, subtitle);
140 this.test_stop_only_seek (thumbnail, subtitle);
141 this.test_start_stop_seek (thumbnail, subtitle);
142 this.test_hhmmss = true;
143 this.test_start_only_seek (thumbnail, subtitle);
144 this.test_stop_only_seek (thumbnail, subtitle);
145 this.test_start_stop_seek (thumbnail, subtitle);
150 private HTTPTimeSeekTest () {
151 var expression = "npt=[0-9]+\\.[0-9][0-9][0-9]-" +
152 "[0-9]+\\.[0-9][0-9][0-9]/" +
153 "[0-9]+\\.[0-9][0-9][0-9]";
155 this.range_regex = new Regex (expression, RegexCompileFlags.CASELESS);
158 private void test_no_seek (Thumbnail? thumbnail,
159 Subtitle? subtitle) throws HTTPSeekError {
160 var request = new HTTPGet (thumbnail, subtitle);
161 var audio_item = request.item as AudioItem;
162 this.test_seek (request, 0, audio_item.duration * SECOND - MSECOND);
165 private void test_start_only_seek (Thumbnail? thumbnail,
167 throws HTTPSeekError {
168 HTTPGet request = null;
169 if (this.test_hhmmss) {
170 request = new HTTPGet.seek_hhmmss ("00:02:08.000", "", thumbnail, subtitle);
172 request = new HTTPGet.seek_start (128, thumbnail, subtitle);
175 var audio_item = request.item as AudioItem;
176 this.test_seek (request,
178 audio_item.duration * SECOND - MSECOND);
181 private void test_stop_only_seek (Thumbnail? thumbnail,
183 throws HTTPSeekError {
184 HTTPGet request = null;
185 if (this.test_hhmmss) {
186 request = new HTTPGet.seek_hhmmss ("00:00:00.000",
191 request = new HTTPGet.seek_stop (128, thumbnail, subtitle);
194 this.test_seek (request, 0, 128 * SECOND);
197 private void test_start_stop_seek (Thumbnail? thumbnail,
199 throws HTTPSeekError {
200 HTTPGet request = null;
201 if (this.test_hhmmss) {
202 request = new HTTPGet.seek_hhmmss ("00:02:08.000",
207 request = new HTTPGet.seek_start_stop (128,
213 this.test_seek (request, 128 * SECOND, 256 * SECOND);
216 private void test_seek (HTTPGet request,
218 int64 stop) throws HTTPSeekError {
219 assert (HTTPTimeSeek.needed (request));
221 var seek = new HTTPTimeSeek (request);
222 seek.add_response_headers ();
224 assert (seek != null);
225 assert (seek.start == start);
226 assert (seek.stop == stop);
227 assert (seek.length == seek.stop + MSECOND - seek.start);
229 var audio_item = request.item as AudioItem;
230 assert (seek.total_length == audio_item.duration * SECOND);
232 var header = request.msg.response_headers.get_one
233 ("TimeSeekRange.dlna.org");
234 assert (header != null);
235 assert (this.range_regex.match (header));