1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "io/FileStream.h"
18
19#include "android-base/file.h"
20#include "android-base/macros.h"
21#include "android-base/test_utils.h"
22
23#include "test/Test.h"
24
25using ::android::StringPiece;
26using ::testing::Eq;
27using ::testing::NotNull;
28using ::testing::StrEq;
29
30namespace aapt {
31namespace io {
32
33TEST(FileInputStreamTest, NextAndBackup) {
34  std::string input = "this is a cool string";
35  TemporaryFile file;
36  ASSERT_THAT(TEMP_FAILURE_RETRY(write(file.fd, input.c_str(), input.size())), Eq(21));
37  lseek64(file.fd, 0, SEEK_SET);
38
39  // Use a small buffer size so that we can call Next() a few times.
40  FileInputStream in(file.release(), 10u);
41  ASSERT_FALSE(in.HadError());
42  EXPECT_THAT(in.ByteCount(), Eq(0u));
43
44  const char* buffer;
45  size_t size;
46  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError();
47  ASSERT_THAT(size, Eq(10u));
48  ASSERT_THAT(buffer, NotNull());
49  EXPECT_THAT(in.ByteCount(), Eq(10u));
50  EXPECT_THAT(StringPiece(buffer, size), Eq("this is a "));
51
52  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
53  ASSERT_THAT(size, Eq(10u));
54  ASSERT_THAT(buffer, NotNull());
55  EXPECT_THAT(in.ByteCount(), Eq(20u));
56  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
57
58  in.BackUp(5u);
59  EXPECT_THAT(in.ByteCount(), Eq(15u));
60
61  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
62  ASSERT_THAT(size, Eq(5u));
63  ASSERT_THAT(buffer, NotNull());
64  ASSERT_THAT(in.ByteCount(), Eq(20u));
65  EXPECT_THAT(StringPiece(buffer, size), Eq("strin"));
66
67  // Backup 1 more than possible. Should clamp.
68  in.BackUp(11u);
69  EXPECT_THAT(in.ByteCount(), Eq(10u));
70
71  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
72  ASSERT_THAT(size, Eq(10u));
73  ASSERT_THAT(buffer, NotNull());
74  ASSERT_THAT(in.ByteCount(), Eq(20u));
75  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
76
77  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
78  ASSERT_THAT(size, Eq(1u));
79  ASSERT_THAT(buffer, NotNull());
80  ASSERT_THAT(in.ByteCount(), Eq(21u));
81  EXPECT_THAT(StringPiece(buffer, size), Eq("g"));
82
83  EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
84  EXPECT_FALSE(in.HadError());
85}
86
87TEST(FileOutputStreamTest, NextAndBackup) {
88  const std::string input = "this is a cool string";
89
90  TemporaryFile file;
91
92  FileOutputStream out(file.fd, 10u);
93  ASSERT_FALSE(out.HadError());
94  EXPECT_THAT(out.ByteCount(), Eq(0u));
95
96  char* buffer;
97  size_t size;
98  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
99  ASSERT_THAT(size, Eq(10u));
100  ASSERT_THAT(buffer, NotNull());
101  EXPECT_THAT(out.ByteCount(), Eq(10u));
102  memcpy(buffer, input.c_str(), size);
103
104  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
105  ASSERT_THAT(size, Eq(10u));
106  ASSERT_THAT(buffer, NotNull());
107  EXPECT_THAT(out.ByteCount(), Eq(20u));
108  memcpy(buffer, input.c_str() + 10u, size);
109
110  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
111  ASSERT_THAT(size, Eq(10u));
112  ASSERT_THAT(buffer, NotNull());
113  EXPECT_THAT(out.ByteCount(), Eq(30u));
114  buffer[0] = input[20u];
115  out.BackUp(size - 1);
116  EXPECT_THAT(out.ByteCount(), Eq(21u));
117
118  ASSERT_TRUE(out.Flush());
119
120  lseek64(file.fd, 0, SEEK_SET);
121
122  std::string actual;
123  ASSERT_TRUE(android::base::ReadFdToString(file.fd, &actual));
124  EXPECT_THAT(actual, StrEq(input));
125}
126
127}  // namespace io
128}  // namespace aapt
129