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