1// Copyright (c) 2009 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "courgette/streams.h" 6 7#include <vector> 8 9#include "testing/gtest/include/gtest/gtest.h" 10 11TEST(StreamsTest, SimpleWriteRead) { 12 const unsigned int kValue1 = 12345; 13 courgette::SinkStream sink; 14 15 EXPECT_TRUE(sink.WriteVarint32(kValue1)); 16 17 const uint8* sink_buffer = sink.Buffer(); 18 size_t length = sink.Length(); 19 20 courgette::SourceStream source; 21 source.Init(sink_buffer, length); 22 23 unsigned int value; 24 bool can_read = source.ReadVarint32(&value); 25 EXPECT_TRUE(can_read); 26 EXPECT_EQ(kValue1, value); 27 EXPECT_EQ(0U, source.Remaining()); 28} 29 30TEST(StreamsTest, SimpleWriteRead2) { 31 courgette::SinkStream sink; 32 33 EXPECT_TRUE(sink.Write("Hello", 5)); 34 35 const uint8* sink_buffer = sink.Buffer(); 36 size_t sink_length = sink.Length(); 37 38 courgette::SourceStream source; 39 source.Init(sink_buffer, sink_length); 40 41 char text[10] = {0}; 42 bool can_read = source.Read(text, 5); 43 EXPECT_TRUE(can_read); 44 EXPECT_EQ(0, memcmp("Hello", text, 5)); 45 EXPECT_EQ(0U, source.Remaining()); 46} 47 48TEST(StreamsTest, StreamSetWriteRead) { 49 courgette::SinkStreamSet out; 50 out.Init(4); 51 52 const unsigned int kValue1 = 12345; 53 54 EXPECT_TRUE(out.stream(3)->WriteVarint32(kValue1)); 55 56 courgette::SinkStream collected; 57 58 EXPECT_TRUE(out.CopyTo(&collected)); 59 60 const uint8* collected_buffer = collected.Buffer(); 61 size_t collected_length = collected.Length(); 62 63 courgette::SourceStreamSet in; 64 bool can_init = in.Init(collected_buffer, collected_length); 65 EXPECT_TRUE(can_init); 66 67 uint32 value; 68 bool can_read = in.stream(3)->ReadVarint32(&value); 69 EXPECT_TRUE(can_read); 70 EXPECT_EQ(kValue1, value); 71 EXPECT_EQ(0U, in.stream(3)->Remaining()); 72 EXPECT_EQ(0U, in.stream(2)->Remaining()); 73} 74 75TEST(StreamsTest, StreamSetWriteRead2) { 76 const size_t kNumberOfStreams = 4; 77 const unsigned int kEnd = ~0U; 78 79 courgette::SinkStreamSet out; 80 out.Init(kNumberOfStreams); 81 82 static const unsigned int data[] = { 83 3, 123, 3, 1000, 0, 100, 2, 100, 0, 999999, 84 0, 0, 0, 0, 1, 2, 1, 3, 1, 5, 0, 66, 85 // varint32 edge case values: 86 1, 127, 1, 128, 1, 129, 1, 16383, 1, 16384, 87 kEnd 88 }; 89 90 for (size_t i = 0; data[i] != kEnd; i += 2) { 91 size_t id = data[i]; 92 size_t datum = data[i + 1]; 93 EXPECT_TRUE(out.stream(id)->WriteVarint32(datum)); 94 } 95 96 courgette::SinkStream collected; 97 98 EXPECT_TRUE(out.CopyTo(&collected)); 99 100 courgette::SourceStreamSet in; 101 bool can_init = in.Init(collected.Buffer(), collected.Length()); 102 EXPECT_TRUE(can_init); 103 104 for (size_t i = 0; data[i] != kEnd; i += 2) { 105 size_t id = data[i]; 106 size_t datum = data[i + 1]; 107 uint32 value = 77; 108 bool can_read = in.stream(id)->ReadVarint32(&value); 109 EXPECT_TRUE(can_read); 110 EXPECT_EQ(datum, value); 111 } 112 113 for (size_t i = 0; i < kNumberOfStreams; ++i) { 114 EXPECT_EQ(0U, in.stream(i)->Remaining()); 115 } 116} 117 118TEST(StreamsTest, SignedVarint32) { 119 courgette::SinkStream out; 120 121 static const int32 data[] = { 122 0, 64, 128, 8192, 16384, 123 1 << 20, 1 << 21, 1 << 22, 124 1 << 27, 1 << 28, 125 0x7fffffff, -0x7fffffff 126 }; 127 128 std::vector<int32> values; 129 for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); ++i) { 130 int32 basis = data[i]; 131 for (int delta = -4; delta <= 4; ++delta) { 132 EXPECT_TRUE(out.WriteVarint32Signed(basis + delta)); 133 values.push_back(basis + delta); 134 EXPECT_TRUE(out.WriteVarint32Signed(-basis + delta)); 135 values.push_back(-basis + delta); 136 } 137 } 138 139 courgette::SourceStream in; 140 in.Init(out); 141 142 for (size_t i = 0; i < values.size(); ++i) { 143 int written_value = values[i]; 144 int32 datum; 145 bool can_read = in.ReadVarint32Signed(&datum); 146 EXPECT_TRUE(can_read); 147 EXPECT_EQ(written_value, datum); 148 } 149 150 EXPECT_TRUE(in.Empty()); 151} 152 153TEST(StreamsTest, StreamSetReadWrite) { 154 courgette::SinkStreamSet out; 155 156 { // Local scope for temporary stream sets. 157 courgette::SinkStreamSet subset1; 158 EXPECT_TRUE(subset1.stream(3)->WriteVarint32(30000)); 159 EXPECT_TRUE(subset1.stream(5)->WriteVarint32(50000)); 160 EXPECT_TRUE(out.WriteSet(&subset1)); 161 162 courgette::SinkStreamSet subset2; 163 EXPECT_TRUE(subset2.stream(2)->WriteVarint32(20000)); 164 EXPECT_TRUE(subset2.stream(6)->WriteVarint32(60000)); 165 EXPECT_TRUE(out.WriteSet(&subset2)); 166 } 167 168 courgette::SinkStream collected; 169 EXPECT_TRUE(out.CopyTo(&collected)); 170 courgette::SourceStreamSet in; 171 bool can_init_in = in.Init(collected.Buffer(), collected.Length()); 172 EXPECT_TRUE(can_init_in); 173 174 courgette::SourceStreamSet subset1; 175 bool can_read_1 = in.ReadSet(&subset1); 176 EXPECT_TRUE(can_read_1); 177 EXPECT_FALSE(in.Empty()); 178 179 courgette::SourceStreamSet subset2; 180 bool can_read_2 = in.ReadSet(&subset2); 181 EXPECT_TRUE(can_read_2); 182 EXPECT_TRUE(in.Empty()); 183 184 courgette::SourceStreamSet subset3; 185 bool can_read_3 = in.ReadSet(&subset3); 186 EXPECT_FALSE(can_read_3); 187 188 EXPECT_FALSE(subset1.Empty()); 189 EXPECT_FALSE(subset1.Empty()); 190 191 uint32 datum; 192 EXPECT_TRUE(subset1.stream(3)->ReadVarint32(&datum)); 193 EXPECT_EQ(30000U, datum); 194 EXPECT_TRUE(subset1.stream(5)->ReadVarint32(&datum)); 195 EXPECT_EQ(50000U, datum); 196 EXPECT_TRUE(subset1.Empty()); 197 198 EXPECT_TRUE(subset2.stream(2)->ReadVarint32(&datum)); 199 EXPECT_EQ(20000U, datum); 200 EXPECT_TRUE(subset2.stream(6)->ReadVarint32(&datum)); 201 EXPECT_EQ(60000U, datum); 202 EXPECT_TRUE(subset2.Empty()); 203} 204