15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "remoting/base/util.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/libyuv/include/libyuv/convert_from_argb.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kWidth = 32 ; 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHeight = 24 ; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBytesPerPixel = 4; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kYStride = kWidth; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kUvStride = kWidth / 2; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kRgbStride = kWidth * kBytesPerPixel; 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const uint32 kFillColor = 0xffffff; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class YuvToRgbTester { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) YuvToRgbTester() { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yuv_buffer_size_ = (kYStride + kUvStride) * kHeight; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yuv_buffer_.reset(new uint8[yuv_buffer_size_]); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) yplane_ = yuv_buffer_.get(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uplane_ = yplane_ + (kYStride * kHeight); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vplane_ = uplane_ + (kUvStride * kHeight / 2); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_buffer_size_ = kWidth * kHeight * kBytesPerPixel; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_buffer_.reset(new uint8[rgb_buffer_size_]); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetYuvBuffer(); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetRgbBuffer(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~YuvToRgbTester() {} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetYuvBuffer() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(yuv_buffer_.get(), 0, yuv_buffer_size_); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetRgbBuffer() { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(rgb_buffer_.get(), 0, rgb_buffer_size_); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void FillRgbBuffer(const webrtc::DesktopRect& rect) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* ptr = reinterpret_cast<uint32*>( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_buffer_.get() + (rect.top() * kRgbStride) + 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (rect.left() * kBytesPerPixel)); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width = rect.width(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int height = rect.height(); height > 0; --height) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::fill(ptr, ptr + width, kFillColor); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr += kRgbStride / kBytesPerPixel; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the the desination buffer is filled within expected bounds. 60d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void CheckRgbBuffer(const webrtc::DesktopRect& rect) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* ptr = reinterpret_cast<uint32*>(rgb_buffer_.get()); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int y = 0; y < kHeight; ++y) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (y < rect.top() || rect.bottom() <= y) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The whole line should be intact. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ((ptrdiff_t)kWidth, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::count(ptr, ptr + kWidth, 0u)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The space before the painted rectangle should be intact. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ((ptrdiff_t)rect.left(), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::count(ptr, ptr + rect.left(), 0u)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All pixels of the target rectangle should be touched. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ptr + rect.right(), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::find(ptr + rect.left(), ptr + rect.right(), 0u)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The space after the painted rectangle should be intact. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ((ptrdiff_t)kWidth - rect.right(), 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::count(ptr + rect.right(), ptr + kWidth, 0u)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ptr += kRgbStride / kBytesPerPixel; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void RunTest(const webrtc::DesktopSize dest_size, 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const webrtc::DesktopRect& rect) { 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ASSERT_TRUE( 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DoesRectContain(webrtc::DesktopRect::MakeSize(dest_size), rect)); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset buffers. 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetYuvBuffer(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetRgbBuffer(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillRgbBuffer(rect); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RGB -> YUV 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) libyuv::ARGBToI420(rgb_buffer_.get(), 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kRgbStride, 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) yplane_, 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kYStride, 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) uplane_, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kUvStride, 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) vplane_, 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kUvStride, 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kWidth, 104cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) kHeight); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset RGB buffer and do opposite conversion. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetRgbBuffer(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConvertAndScaleYUVToRGB32Rect(yplane_, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uplane_, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vplane_, 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kYStride, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kUvStride, 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopSize(kWidth, kHeight), 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect::MakeWH(kWidth, kHeight), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rgb_buffer_.get(), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kRgbStride, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_size, 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect::MakeSize(dest_size), 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rect); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if it worked out. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckRgbBuffer(rect); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestBasicConversion() { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whole buffer. 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) RunTest(webrtc::DesktopSize(kWidth, kHeight), 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect::MakeWH(kWidth, kHeight)); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t yuv_buffer_size_; 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<uint8[]> yuv_buffer_; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* yplane_; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* uplane_; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* vplane_; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t rgb_buffer_size_; 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<uint8[]> rgb_buffer_; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(YuvToRgbTester); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(YuvToRgbTest, BasicConversion) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) YuvToRgbTester tester; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester.TestBasicConversion(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(YuvToRgbTest, Clipping) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) YuvToRgbTester tester; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopSize dest_size = webrtc::DesktopSize(kWidth, kHeight); 153d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect rect = 154d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect::MakeLTRB(0, 0, kWidth - 1, kHeight - 1); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(fbarchard): Allow top/left clipping to odd boundary. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 16; ++i) { 157d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB( 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.left() + ((i & 1) ? 2 : 0), 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.top() + ((i & 2) ? 2 : 0), 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.right() - ((i & 4) ? 1 : 0), 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.bottom() - ((i & 8) ? 1 : 0)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester.RunTest(dest_size, dest_rect); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(YuvToRgbTest, ClippingAndScaling) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) YuvToRgbTester tester; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopSize dest_size = 171d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopSize(kWidth - 10, kHeight - 10); 172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect rect = 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) webrtc::DesktopRect::MakeLTRB(6, 6, kWidth - 11, kHeight - 11); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 16; ++i) { 175d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::DesktopRect dest_rect = webrtc::DesktopRect::MakeLTRB( 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.left() + ((i & 1) ? 2 : 0), 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.top() + ((i & 2) ? 2 : 0), 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.right() - ((i & 4) ? 1 : 0), 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rect.bottom() - ((i & 8) ? 1 : 0)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester.RunTest(dest_size, dest_rect); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ReplaceLfByCrLfTest, Basic) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("ab", ReplaceLfByCrLf("ab")); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\r\nab", ReplaceLfByCrLf("\nab")); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\r\nab\r\n", ReplaceLfByCrLf("\nab\n")); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\r\nab\r\ncd", ReplaceLfByCrLf("\nab\ncd")); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\r\nab\r\ncd\r\n", ReplaceLfByCrLf("\nab\ncd\n")); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\r\n\r\nab\r\n\r\ncd\r\n\r\n", 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReplaceLfByCrLf("\n\nab\n\ncd\n\n")); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ReplaceLfByCrLfTest, Speed) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kLineSize = 128; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string line(kLineSize, 'a'); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line[kLineSize - 1] = '\n'; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a 10M string. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kLineNum = 10 * 1024 * 1024 / kLineSize; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string buffer; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.resize(kLineNum * kLineSize); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kLineNum; ++i) { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&buffer[i * kLineSize], &line[0], kLineSize); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert the string. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = ReplaceLfByCrLf(buffer); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the converted string. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<size_t>((kLineSize + 1) * kLineNum), buffer.size()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* p = &buffer[0]; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kLineNum; ++i) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(&line[0], p, kLineSize - 1)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += kLineSize - 1; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('\r', *p++); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('\n', *p++); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ReplaceCrLfByLfTest, Basic) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("ab", ReplaceCrLfByLf("ab")); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\nab", ReplaceCrLfByLf("\r\nab")); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\nab\n", ReplaceCrLfByLf("\r\nab\r\n")); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\nab\ncd", ReplaceCrLfByLf("\r\nab\r\ncd")); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\nab\ncd\n", ReplaceCrLfByLf("\r\nab\r\ncd\n")); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\n\nab\n\ncd\n\n", 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReplaceCrLfByLf("\r\n\r\nab\r\n\r\ncd\r\n\r\n")); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("\rab\rcd\r", ReplaceCrLfByLf("\rab\rcd\r")); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ReplaceCrLfByLfTest, Speed) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kLineSize = 128; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string line(kLineSize, 'a'); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line[kLineSize - 2] = '\r'; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) line[kLineSize - 1] = '\n'; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a 10M string. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int kLineNum = 10 * 1024 * 1024 / kLineSize; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string buffer; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer.resize(kLineNum * kLineSize); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kLineNum; ++i) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&buffer[i * kLineSize], &line[0], kLineSize); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Convert the string. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer = ReplaceCrLfByLf(buffer); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the converted string. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<size_t>((kLineSize - 1) * kLineNum), buffer.size()); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* p = &buffer[0]; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kLineNum; ++i) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(&line[0], p, kLineSize - 2)); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p += kLineSize - 2; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ('\n', *p++); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(StringIsUtf8Test, Basic) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("", 0)); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\0", 1)); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("abc", 3)); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\xc0\x80", 2)); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\xe0\x80\x80", 3)); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\xf0\x80\x80\x80", 4)); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\xf8\x80\x80\x80\x80", 5)); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(StringIsUtf8("\xfc\x80\x80\x80\x80\x80", 6)); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Not enough continuation characters 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xc0", 1)); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xe0\x80", 2)); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xf0\x80\x80", 3)); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xf8\x80\x80\x80", 4)); 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xfc\x80\x80\x80\x80", 5)); 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // One more continuation character than needed 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xc0\x80\x80", 3)); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xe0\x80\x80\x80", 4)); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xf0\x80\x80\x80\x80", 5)); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xf8\x80\x80\x80\x80\x80", 6)); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xfc\x80\x80\x80\x80\x80\x80", 7)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invalid first byte 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xfe\x80\x80\x80\x80\x80\x80", 7)); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xff\x80\x80\x80\x80\x80\x80", 7)); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Invalid continuation byte 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xc0\x00", 2)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xc0\x40", 2)); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(StringIsUtf8("\xc0\xc0", 2)); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 289