1b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Protocol Buffers - Google's data interchange format
2b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Copyright 2008 Google Inc.  All rights reserved.
3b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// https://developers.google.com/protocol-buffers/
4b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//
5b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Redistribution and use in source and binary forms, with or without
6b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// modification, are permitted provided that the following conditions are
7b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// met:
8b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//
9b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//     * Redistributions of source code must retain the above copyright
10b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// notice, this list of conditions and the following disclaimer.
11b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//     * Redistributions in binary form must reproduce the above
12b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// copyright notice, this list of conditions and the following disclaimer
13b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// in the documentation and/or other materials provided with the
14b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// distribution.
15b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//     * Neither the name of Google Inc. nor the names of its
16b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// contributors may be used to endorse or promote products derived from
17b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// this software without specific prior written permission.
18b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer//
19b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
31b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/bytestream.h>
32b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
33b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <stdio.h>
34b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <string.h>
35b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <algorithm>
36b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
37b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/testing/googletest.h>
38b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <gtest/gtest.h>
39b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
40b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace google {
41b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace protobuf {
42b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace strings {
43b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace {
44b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
45b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// We use this class instead of ArrayByteSource to simulate a ByteSource that
46b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// contains multiple fragments.  ArrayByteSource returns the entire array in
47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// one fragment.
48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerclass MockByteSource : public ByteSource {
49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer public:
50b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MockByteSource(StringPiece data, int block_size)
51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    : data_(data), block_size_(block_size) {}
52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  size_t Available() const { return data_.size(); }
54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece Peek() {
55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    return data_.substr(0, block_size_);
56b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
57b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  void Skip(size_t n) { data_.remove_prefix(n); }
58b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
59b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer private:
60b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece data_;
61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  int block_size_;
62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerTEST(ByteSourceTest, CopyTo) {
65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece data("Hello world!");
66b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MockByteSource source(data, 3);
67b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string str;
68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringByteSink sink(&str);
69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  source.CopyTo(&sink, data.size());
71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ(data, str);
72b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
73b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
74b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerTEST(ByteSourceTest, CopySubstringTo) {
75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece data("Hello world!");
76b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MockByteSource source(data, 3);
77b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  source.Skip(1);
78b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string str;
79b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringByteSink sink(&str);
80b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
81b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  source.CopyTo(&sink, data.size() - 2);
82b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ(data.substr(1, data.size() - 2), str);
83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ("!", source.Peek());
84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerTEST(ByteSourceTest, LimitByteSource) {
87b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece data("Hello world!");
88b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MockByteSource source(data, 3);
89b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  LimitByteSource limit_source(&source, 6);
90b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ(6, limit_source.Available());
91b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  limit_source.Skip(1);
92b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ(5, limit_source.Available());
93b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
94b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  {
95b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    string str;
96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    StringByteSink sink(&str);
97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    limit_source.CopyTo(&sink, limit_source.Available());
98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    EXPECT_EQ("ello ", str);
99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    EXPECT_EQ(0, limit_source.Available());
100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    EXPECT_EQ(6, source.Available());
101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  {
104b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    string str;
105b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    StringByteSink sink(&str);
106b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    source.CopyTo(&sink, source.Available());
107b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    EXPECT_EQ("world!", str);
108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer    EXPECT_EQ(0, source.Available());
109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  }
110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerTEST(ByteSourceTest, CopyToStringByteSink) {
113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringPiece data("Hello world!");
114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  MockByteSource source(data, 3);
115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string str;
116b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  StringByteSink sink(&str);
117b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  source.CopyTo(&sink, data.size());
118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_EQ(data, str);
119b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
120b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
121b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Verify that ByteSink is subclassable and Flush() overridable.
122b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerclass FlushingByteSink : public StringByteSink {
123b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer public:
124b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  explicit FlushingByteSink(string* dest) : StringByteSink(dest) {}
125b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  virtual void Flush() { Append("z", 1); }
126b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer private:
127b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FlushingByteSink);
128b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer};
129b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
130b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Write and Flush via the ByteSink superclass interface.
131b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid WriteAndFlush(ByteSink* s) {
132b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  s->Append("abc", 3);
133b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  s->Flush();
134b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
135b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
136b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerTEST(ByteSinkTest, Flush) {
137b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  string str;
138b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  FlushingByteSink f_sink(&str);
139b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  WriteAndFlush(&f_sink);
140b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer  EXPECT_STREQ("abcz", str.c_str());
141b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}
142b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer
143b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}  // namespace
144b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}  // namespace strings
145b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}  // namespace protobuf
146b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer}  // namespace google
147