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 "androidfw/FileStream.h"
18 #include "androidfw/StringPiece.h"
19 
20 #include "android-base/file.h"
21 #include "android-base/macros.h"
22 
23 #include "gmock/gmock.h"
24 #include "gtest/gtest.h"
25 
26 using ::android::StringPiece;
27 using ::testing::Eq;
28 using ::testing::NotNull;
29 using ::testing::StrEq;
30 
31 namespace android {
32 
TEST(FileInputStreamTest,NextAndBackup)33 TEST(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 void* buffer;
45   size_t size;
46   ASSERT_TRUE(in.Next(&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(reinterpret_cast<const char*>(buffer), size), Eq("this is a "));
51 
52   ASSERT_TRUE(in.Next(&buffer, &size));
53   ASSERT_THAT(size, Eq(10u));
54   ASSERT_THAT(buffer, NotNull());
55   EXPECT_THAT(in.ByteCount(), Eq(20u));
56   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
57 
58   in.BackUp(5u);
59   EXPECT_THAT(in.ByteCount(), Eq(15u));
60 
61   ASSERT_TRUE(in.Next(&buffer, &size));
62   ASSERT_THAT(size, Eq(5u));
63   ASSERT_THAT(buffer, NotNull());
64   ASSERT_THAT(in.ByteCount(), Eq(20u));
65   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(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(&buffer, &size));
72   ASSERT_THAT(size, Eq(10u));
73   ASSERT_THAT(buffer, NotNull());
74   ASSERT_THAT(in.ByteCount(), Eq(20u));
75   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("cool strin"));
76 
77   ASSERT_TRUE(in.Next(&buffer, &size));
78   ASSERT_THAT(size, Eq(1u));
79   ASSERT_THAT(buffer, NotNull());
80   ASSERT_THAT(in.ByteCount(), Eq(21u));
81   EXPECT_THAT(StringPiece(reinterpret_cast<const char*>(buffer), size), Eq("g"));
82 
83   EXPECT_FALSE(in.Next(&buffer, &size));
84   EXPECT_FALSE(in.HadError());
85 }
86 
TEST(FileOutputStreamTest,NextAndBackup)87 TEST(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   void* buffer;
97   size_t size;
98   ASSERT_TRUE(out.Next(&buffer, &size));
99   ASSERT_THAT(size, Eq(10u));
100   ASSERT_THAT(buffer, NotNull());
101   EXPECT_THAT(out.ByteCount(), Eq(10u));
102   memcpy(reinterpret_cast<char*>(buffer), input.c_str(), size);
103 
104   ASSERT_TRUE(out.Next(&buffer, &size));
105   ASSERT_THAT(size, Eq(10u));
106   ASSERT_THAT(buffer, NotNull());
107   EXPECT_THAT(out.ByteCount(), Eq(20u));
108   memcpy(reinterpret_cast<char*>(buffer), input.c_str() + 10u, size);
109 
110   ASSERT_TRUE(out.Next(&buffer, &size));
111   ASSERT_THAT(size, Eq(10u));
112   ASSERT_THAT(buffer, NotNull());
113   EXPECT_THAT(out.ByteCount(), Eq(30u));
114   reinterpret_cast<char*>(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 android
128