|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 const Ci = Components.interfaces; |
|
6 const Cr = Components.results; |
|
7 const CC = Components.Constructor; |
|
8 const Cc = Components.classes; |
|
9 |
|
10 // The string we use as data. |
|
11 const data = "0123456789"; |
|
12 // Number of streams in the multiplex stream. |
|
13 const count = 10; |
|
14 |
|
15 function test_multiplex_streams() { |
|
16 var MultiplexStream = CC("@mozilla.org/io/multiplex-input-stream;1", |
|
17 "nsIMultiplexInputStream"); |
|
18 do_check_eq(1, 1); |
|
19 |
|
20 var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1", |
|
21 "nsIBinaryInputStream"); |
|
22 var BinaryOutputStream = Components.Constructor("@mozilla.org/binaryoutputstream;1", |
|
23 "nsIBinaryOutputStream", |
|
24 "setOutputStream"); |
|
25 var multiplex = new MultiplexStream(); |
|
26 for (var i = 0; i < count; ++i) { |
|
27 let s = Cc["@mozilla.org/io/string-input-stream;1"] |
|
28 .createInstance(Ci.nsIStringInputStream); |
|
29 s.setData(data, data.length); |
|
30 |
|
31 multiplex.appendStream(s); |
|
32 } |
|
33 var seekable = multiplex.QueryInterface(Ci.nsISeekableStream); |
|
34 var sis = Cc["@mozilla.org/scriptableinputstream;1"] |
|
35 .createInstance(Ci.nsIScriptableInputStream); |
|
36 sis.init(seekable); |
|
37 // Read some data. |
|
38 var readData = sis.read(20); |
|
39 do_check_eq(readData, data + data); |
|
40 // -- Tests for NS_SEEK_SET |
|
41 // Seek to a non-zero, non-stream-boundary offset. |
|
42 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 2); |
|
43 do_check_eq(seekable.tell(), 2); |
|
44 do_check_eq(seekable.available(), 98); |
|
45 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 9); |
|
46 do_check_eq(seekable.tell(), 9); |
|
47 do_check_eq(seekable.available(), 91); |
|
48 // Seek across stream boundary. |
|
49 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 35); |
|
50 do_check_eq(seekable.tell(), 35); |
|
51 do_check_eq(seekable.available(), 65); |
|
52 readData = sis.read(5); |
|
53 do_check_eq(readData, data.slice(5)); |
|
54 do_check_eq(seekable.available(), 60); |
|
55 // Seek at stream boundaries. |
|
56 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 40); |
|
57 do_check_eq(seekable.tell(), 40); |
|
58 do_check_eq(seekable.available(), 60); |
|
59 readData = sis.read(10); |
|
60 do_check_eq(readData, data); |
|
61 do_check_eq(seekable.tell(), 50); |
|
62 do_check_eq(seekable.available(), 50); |
|
63 // Rewind and read across streams. |
|
64 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 39); |
|
65 do_check_eq(seekable.tell(), 39); |
|
66 do_check_eq(seekable.available(), 61); |
|
67 readData = sis.read(11); |
|
68 do_check_eq(readData, data.slice(9) + data); |
|
69 do_check_eq(seekable.tell(), 50); |
|
70 do_check_eq(seekable.available(), 50); |
|
71 // Rewind to the beginning. |
|
72 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); |
|
73 do_check_eq(seekable.tell(), 0); |
|
74 do_check_eq(seekable.available(), 100); |
|
75 // Seek to some random location |
|
76 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 50); |
|
77 // -- Tests for NS_SEEK_CUR |
|
78 // Positive seek. |
|
79 seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, 15); |
|
80 do_check_eq(seekable.tell(), 65); |
|
81 do_check_eq(seekable.available(), 35); |
|
82 readData = sis.read(10); |
|
83 do_check_eq(readData, data.slice(5) + data.slice(0, 5)); |
|
84 do_check_eq(seekable.tell(), 75); |
|
85 do_check_eq(seekable.available(), 25); |
|
86 // Negative seek. |
|
87 seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -15); |
|
88 do_check_eq(seekable.tell(), 60); |
|
89 do_check_eq(seekable.available(), 40); |
|
90 readData = sis.read(10); |
|
91 do_check_eq(readData, data); |
|
92 do_check_eq(seekable.tell(), 70); |
|
93 do_check_eq(seekable.available(), 30); |
|
94 |
|
95 // -- Tests for NS_SEEK_END |
|
96 // Normal read. |
|
97 seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, -5); |
|
98 do_check_eq(seekable.tell(), data.length * count - 5); |
|
99 readData = sis.read(5); |
|
100 do_check_eq(readData, data.slice(5)); |
|
101 do_check_eq(seekable.tell(), data.length * count); |
|
102 // Read across streams. |
|
103 seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, -15); |
|
104 do_check_eq(seekable.tell(), data.length * count - 15); |
|
105 readData = sis.read(15); |
|
106 do_check_eq(readData, data.slice(5) + data); |
|
107 do_check_eq(seekable.tell(), data.length * count); |
|
108 |
|
109 // -- Try to do various edge cases |
|
110 // Forward seek from the end, should throw. |
|
111 var caught = false; |
|
112 try { |
|
113 seekable.seek(Ci.nsISeekableStream.NS_SEEK_END, 15); |
|
114 } catch(e) { |
|
115 caught = true; |
|
116 } |
|
117 do_check_eq(caught, true); |
|
118 do_check_eq(seekable.tell(), data.length * count); |
|
119 // Backward seek from the beginning, should be clamped. |
|
120 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); |
|
121 do_check_eq(seekable.tell(), 0); |
|
122 seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -15); |
|
123 do_check_eq(seekable.tell(), 0); |
|
124 // Seek too far: should be clamped. |
|
125 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 0); |
|
126 do_check_eq(seekable.tell(), 0); |
|
127 seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, 3 * data.length * count); |
|
128 do_check_eq(seekable.tell(), 100); |
|
129 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, data.length * count); |
|
130 do_check_eq(seekable.tell(), 100); |
|
131 seekable.seek(Ci.nsISeekableStream.NS_SEEK_CUR, -2 * data.length * count); |
|
132 do_check_eq(seekable.tell(), 0); |
|
133 } |
|
134 |
|
135 function test_multiplex_bug797871() { |
|
136 |
|
137 var data = "1234567890123456789012345678901234567890"; |
|
138 |
|
139 var MultiplexStream = CC("@mozilla.org/io/multiplex-input-stream;1", |
|
140 "nsIMultiplexInputStream"); |
|
141 do_check_eq(1, 1); |
|
142 |
|
143 var BinaryInputStream = Components.Constructor("@mozilla.org/binaryinputstream;1", |
|
144 "nsIBinaryInputStream"); |
|
145 var BinaryOutputStream = Components.Constructor("@mozilla.org/binaryoutputstream;1", |
|
146 "nsIBinaryOutputStream", |
|
147 "setOutputStream"); |
|
148 var multiplex = new MultiplexStream(); |
|
149 let s = Cc["@mozilla.org/io/string-input-stream;1"] |
|
150 .createInstance(Ci.nsIStringInputStream); |
|
151 s.setData(data, data.length); |
|
152 |
|
153 multiplex.appendStream(s); |
|
154 |
|
155 var seekable = multiplex.QueryInterface(Ci.nsISeekableStream); |
|
156 var sis = Cc["@mozilla.org/scriptableinputstream;1"] |
|
157 .createInstance(Ci.nsIScriptableInputStream); |
|
158 sis.init(seekable); |
|
159 |
|
160 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 8); |
|
161 do_check_eq(seekable.tell(), 8); |
|
162 readData = sis.read(2); |
|
163 do_check_eq(seekable.tell(), 10); |
|
164 |
|
165 seekable.seek(Ci.nsISeekableStream.NS_SEEK_SET, 20); |
|
166 do_check_eq(seekable.tell(), 20); |
|
167 } |
|
168 |
|
169 function run_test() { |
|
170 test_multiplex_streams(); |
|
171 test_multiplex_bug797871(); |
|
172 } |
|
173 |