1 /* 2 * Copyright (C) 2013, Opera Software ASA. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "core/html/track/vtt/BufferedLineReader.h" 33 34 #include "wtf/text/CString.h" 35 #include "wtf/text/WTFString.h" 36 #include "wtf/unicode/CharacterNames.h" 37 38 #include <gtest/gtest.h> 39 40 using blink::BufferedLineReader; 41 42 namespace { 43 44 TEST(BufferedLineReader, Constructor) 45 { 46 BufferedLineReader reader; 47 ASSERT_FALSE(reader.isAtEndOfStream()); 48 String line; 49 ASSERT_FALSE(reader.getLine(line)); 50 } 51 52 TEST(BufferedLineReader, EOSNoInput) 53 { 54 BufferedLineReader reader; 55 String line; 56 ASSERT_FALSE(reader.getLine(line)); 57 reader.setEndOfStream(); 58 // No input observed, so still no line. 59 ASSERT_FALSE(reader.getLine(line)); 60 } 61 62 TEST(BufferedLineReader, EOSInput) 63 { 64 BufferedLineReader reader; 65 reader.append("A"); 66 reader.setEndOfStream(); 67 String line; 68 ASSERT_TRUE(reader.getLine(line)); 69 ASSERT_EQ(line, "A"); 70 } 71 72 TEST(BufferedLineReader, EOSMultipleReads_1) 73 { 74 BufferedLineReader reader; 75 reader.append("A"); 76 reader.setEndOfStream(); 77 String line; 78 ASSERT_TRUE(reader.getLine(line)); 79 ASSERT_EQ(line, "A"); 80 // No more lines returned. 81 ASSERT_FALSE(reader.getLine(line)); 82 ASSERT_FALSE(reader.getLine(line)); 83 } 84 85 TEST(BufferedLineReader, EOSMultipleReads_2) 86 { 87 BufferedLineReader reader; 88 reader.append("A\n"); 89 reader.setEndOfStream(); 90 String line; 91 ASSERT_TRUE(reader.getLine(line)); 92 ASSERT_EQ(line, "A"); 93 // No more lines returned. 94 ASSERT_FALSE(reader.getLine(line)); 95 ASSERT_FALSE(reader.getLine(line)); 96 } 97 98 TEST(BufferedLineReader, LineEndingCR) 99 { 100 BufferedLineReader reader; 101 reader.append("X\rY"); 102 reader.setEndOfStream(); 103 String line; 104 ASSERT_TRUE(reader.getLine(line)); 105 ASSERT_EQ(line, "X"); 106 ASSERT_TRUE(reader.getLine(line)); 107 ASSERT_EQ(line, "Y"); 108 } 109 110 TEST(BufferedLineReader, LineEndingCR_EOS) 111 { 112 BufferedLineReader reader; 113 reader.append("X\r"); 114 reader.setEndOfStream(); 115 String line; 116 ASSERT_TRUE(reader.getLine(line)); 117 ASSERT_EQ(line, "X"); 118 ASSERT_FALSE(reader.getLine(line)); 119 } 120 121 TEST(BufferedLineReader, LineEndingLF) 122 { 123 BufferedLineReader reader; 124 reader.append("X\nY"); 125 reader.setEndOfStream(); 126 String line; 127 ASSERT_TRUE(reader.getLine(line)); 128 ASSERT_EQ(line, "X"); 129 ASSERT_TRUE(reader.getLine(line)); 130 ASSERT_EQ(line, "Y"); 131 } 132 133 TEST(BufferedLineReader, LineEndingLF_EOS) 134 { 135 BufferedLineReader reader; 136 reader.append("X\n"); 137 reader.setEndOfStream(); 138 String line; 139 ASSERT_TRUE(reader.getLine(line)); 140 ASSERT_EQ(line, "X"); 141 ASSERT_FALSE(reader.getLine(line)); 142 } 143 144 TEST(BufferedLineReader, LineEndingCRLF) 145 { 146 BufferedLineReader reader; 147 reader.append("X\r\nY"); 148 reader.setEndOfStream(); 149 String line; 150 ASSERT_TRUE(reader.getLine(line)); 151 ASSERT_EQ(line, "X"); 152 ASSERT_TRUE(reader.getLine(line)); 153 ASSERT_EQ(line, "Y"); 154 } 155 156 TEST(BufferedLineReader, LineEndingCRLF_EOS) 157 { 158 BufferedLineReader reader; 159 reader.append("X\r\n"); 160 reader.setEndOfStream(); 161 String line; 162 ASSERT_TRUE(reader.getLine(line)); 163 ASSERT_EQ(line, "X"); 164 ASSERT_FALSE(reader.getLine(line)); 165 } 166 167 enum LineBreakType { 168 Cr, 169 Lf, 170 CrLf 171 }; 172 173 String LineBreakString(LineBreakType type) 174 { 175 static const char breakStrings[] = "\r\n"; 176 return String(type == Lf ? breakStrings + 1 : breakStrings, type == CrLf ? 2 : 1); 177 } 178 179 String MakeTestData(const char** lines, const LineBreakType* breaks, int count) 180 { 181 StringBuilder builder; 182 for (int i = 0; i < count; ++i) { 183 builder.append(lines[i]); 184 builder.append(LineBreakString(breaks[i])); 185 } 186 return builder.toString(); 187 } 188 189 const size_t blockSizes[] = { 64, 32, 16, 8, 4, 2, 1, 3, 5, 7, 9, 11, 13, 17, 19, 23 }; 190 191 TEST(BufferedLineReader, BufferSizes) 192 { 193 const char* lines[] = { 194 "aaaaaaaaaaaaaaaa", 195 "bbbbbbbbbb", 196 "ccccccccccccc", 197 "", 198 "dddddd", 199 "", 200 "eeeeeeeeee" 201 }; 202 const LineBreakType breaks[] = { Lf, Lf, Lf, Lf, Lf, Lf, Lf }; 203 const size_t numTestLines = WTF_ARRAY_LENGTH(lines); 204 COMPILE_ASSERT(numTestLines == WTF_ARRAY_LENGTH(breaks), DifferentLengths_lines_and_breaks); 205 String data = MakeTestData(lines, breaks, numTestLines); 206 207 for (size_t k = 0; k < WTF_ARRAY_LENGTH(blockSizes); ++k) { 208 size_t lineCount = 0; 209 BufferedLineReader reader; 210 size_t blockSize = blockSizes[k]; 211 for (size_t i = 0; i < data.length(); i += blockSize) { 212 reader.append(data.substring(i, blockSize)); 213 214 String line; 215 while (reader.getLine(line)) { 216 ASSERT_LT(lineCount, numTestLines); 217 ASSERT_EQ(line, lines[lineCount++]); 218 } 219 } 220 ASSERT_EQ(lineCount, numTestLines); 221 } 222 } 223 224 TEST(BufferedLineReader, BufferSizesMixedEndings) 225 { 226 const char* lines[] = { 227 "aaaaaaaaaaaaaaaa", 228 "bbbbbbbbbb", 229 "ccccccccccccc", 230 "", 231 "dddddd", 232 "eeeeeeeeee", 233 "fffffffffffffffffff" 234 }; 235 const LineBreakType breaks[] = { Cr, Lf, CrLf, Cr, Lf, CrLf, Lf }; 236 const size_t numTestLines = WTF_ARRAY_LENGTH(lines); 237 COMPILE_ASSERT(numTestLines == WTF_ARRAY_LENGTH(breaks), DifferentLengths_lines_and_breaks); 238 String data = MakeTestData(lines, breaks, numTestLines); 239 240 for (size_t k = 0; k < WTF_ARRAY_LENGTH(blockSizes); ++k) { 241 size_t lineCount = 0; 242 BufferedLineReader reader; 243 size_t blockSize = blockSizes[k]; 244 for (size_t i = 0; i < data.length(); i += blockSize) { 245 reader.append(data.substring(i, blockSize)); 246 247 String line; 248 while (reader.getLine(line)) { 249 ASSERT_LT(lineCount, numTestLines); 250 ASSERT_EQ(line, lines[lineCount++]); 251 } 252 } 253 ASSERT_EQ(lineCount, numTestLines); 254 } 255 } 256 257 TEST(BufferedLineReader, BufferBoundaryInCRLF_1) 258 { 259 BufferedLineReader reader; 260 reader.append("X\r"); 261 String line; 262 ASSERT_TRUE(reader.getLine(line)); 263 ASSERT_EQ(line, "X"); 264 reader.append("\n"); 265 ASSERT_FALSE(reader.getLine(line)); 266 } 267 268 TEST(BufferedLineReader, BufferBoundaryInCRLF_2) 269 { 270 BufferedLineReader reader; 271 reader.append("X\r"); 272 String line; 273 ASSERT_TRUE(reader.getLine(line)); 274 ASSERT_EQ(line, "X"); 275 ASSERT_FALSE(reader.getLine(line)); 276 reader.append("\n"); 277 ASSERT_FALSE(reader.getLine(line)); 278 reader.append("Y\n"); 279 ASSERT_TRUE(reader.getLine(line)); 280 ASSERT_EQ(line, "Y"); 281 } 282 283 TEST(BufferedLineReader, NormalizedNUL) 284 { 285 BufferedLineReader reader; 286 reader.append(String("X\0Y\n", 4)); 287 String line; 288 ASSERT_TRUE(reader.getLine(line)); 289 ASSERT_EQ(line[1], WTF::Unicode::replacementCharacter); 290 } 291 292 } // namespace 293