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 
22 #include "test/Test.h"
23 
24 using ::android::StringPiece;
25 using ::testing::Eq;
26 using ::testing::NotNull;
27 using ::testing::StrEq;
28 
29 namespace aapt {
30 namespace io {
31 
TEST(FileInputStreamTest,NextAndBackup)32 TEST(FileInputStreamTest, NextAndBackup) {
33   std::string input = "this is a cool string";
34   TemporaryFile file;
35   ASSERT_THAT(TEMP_FAILURE_RETRY(write(file.fd, input.c_str(), input.size())), Eq(21));
36   lseek64(file.fd, 0, SEEK_SET);
37 
38   // Use a small buffer size so that we can call Next() a few times.
39   FileInputStream in(file.release(), 10u);
40   ASSERT_FALSE(in.HadError());
41   EXPECT_THAT(in.ByteCount(), Eq(0u));
42 
43   const void* buffer;
44   size_t size;
45   ASSERT_TRUE(in.Next(&buffer, &size)) << in.GetError();
46   ASSERT_THAT(size, Eq(10u));
47   ASSERT_THAT(buffer, NotNull());
48   EXPECT_THAT(in.ByteCount(), Eq(10u));
49   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("this is a "));
50 
51   ASSERT_TRUE(in.Next(&buffer, &size));
52   ASSERT_THAT(size, Eq(10u));
53   ASSERT_THAT(buffer, NotNull());
54   EXPECT_THAT(in.ByteCount(), Eq(20u));
55   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
56 
57   in.BackUp(5u);
58   EXPECT_THAT(in.ByteCount(), Eq(15u));
59 
60   ASSERT_TRUE(in.Next(&buffer, &size));
61   ASSERT_THAT(size, Eq(5u));
62   ASSERT_THAT(buffer, NotNull());
63   ASSERT_THAT(in.ByteCount(), Eq(20u));
64   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("strin"));
65 
66   // Backup 1 more than possible. Should clamp.
67   in.BackUp(11u);
68   EXPECT_THAT(in.ByteCount(), Eq(10u));
69 
70   ASSERT_TRUE(in.Next(&buffer, &size));
71   ASSERT_THAT(size, Eq(10u));
72   ASSERT_THAT(buffer, NotNull());
73   ASSERT_THAT(in.ByteCount(), Eq(20u));
74   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
75 
76   ASSERT_TRUE(in.Next(&buffer, &size));
77   ASSERT_THAT(size, Eq(1u));
78   ASSERT_THAT(buffer, NotNull());
79   ASSERT_THAT(in.ByteCount(), Eq(21u));
80   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g"));
81 
82   EXPECT_FALSE(in.Next(&buffer, &size));
83   EXPECT_FALSE(in.HadError());
84 }
85 
TEST(FileOutputStreamTest,NextAndBackup)86 TEST(FileOutputStreamTest, NextAndBackup) {
87   const std::string input = "this is a cool string";
88 
89   TemporaryFile file;
90 
91   FileOutputStream out(file.fd, 10u);
92   ASSERT_FALSE(out.HadError());
93   EXPECT_THAT(out.ByteCount(), Eq(0u));
94 
95   void* buffer;
96   size_t size;
97   ASSERT_TRUE(out.Next(&buffer, &size));
98   ASSERT_THAT(size, Eq(10u));
99   ASSERT_THAT(buffer, NotNull());
100   EXPECT_THAT(out.ByteCount(), Eq(10u));
101   memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size);
102 
103   ASSERT_TRUE(out.Next(&buffer, &size));
104   ASSERT_THAT(size, Eq(10u));
105   ASSERT_THAT(buffer, NotNull());
106   EXPECT_THAT(out.ByteCount(), Eq(20u));
107   memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size);
108 
109   ASSERT_TRUE(out.Next(&buffer, &size));
110   ASSERT_THAT(size, Eq(10u));
111   ASSERT_THAT(buffer, NotNull());
112   EXPECT_THAT(out.ByteCount(), Eq(30u));
113   reinterpret_cast<char*>(buffer)[0] = input[20u];
114   out.BackUp(size - 1);
115   EXPECT_THAT(out.ByteCount(), Eq(21u));
116 
117   ASSERT_TRUE(out.Flush());
118 
119   lseek64(file.fd, 0, SEEK_SET);
120 
121   std::string actual;
122   ASSERT_TRUE(android::base::ReadFdToString(file.fd, &actual));
123   EXPECT_THAT(actual, StrEq(input));
124 }
125 
126 }  // namespace io
127 }  // namespace aapt
128