1efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski/*
2efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * Copyright (C) 2017 The Android Open Source Project
3efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski *
4efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * you may not use this file except in compliance with the License.
6efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * You may obtain a copy of the License at
7efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski *
8efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski *
10efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * Unless required by applicable law or agreed to in writing, software
11efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * See the License for the specific language governing permissions and
14efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski * limitations under the License.
15efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski */
16efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
17004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski#include "io/FileStream.h"
18efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
19a693c4a32ebed4e96dcc1cf6a706e8ebbb004db2Adam Lesinski#include "android-base/file.h"
20efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski#include "android-base/macros.h"
21efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski#include "android-base/test_utils.h"
22efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
23efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski#include "test/Test.h"
24efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
25efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskiusing ::android::StringPiece;
26efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskiusing ::testing::Eq;
27efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskiusing ::testing::NotNull;
28efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskiusing ::testing::StrEq;
29efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
30efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskinamespace aapt {
31efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinskinamespace io {
32efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
33efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam LesinskiTEST(FileInputStreamTest, NextAndBackup) {
34efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  std::string input = "this is a cool string";
35efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  TemporaryFile file;
36efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(TEMP_FAILURE_RETRY(write(file.fd, input.c_str(), input.size())), Eq(21));
37efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  lseek64(file.fd, 0, SEEK_SET);
38efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
39efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  // Use a small buffer size so that we can call Next() a few times.
40004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  FileInputStream in(file.release(), 10u);
41efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_FALSE(in.HadError());
42efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(in.ByteCount(), Eq(0u));
43efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
44efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  const char* buffer;
45efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  size_t size;
46efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size)) << in.GetError();
47efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(size, Eq(10u));
48efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(buffer, NotNull());
49efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(in.ByteCount(), Eq(10u));
50efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(StringPiece(buffer, size), Eq("this is a "));
51efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
52efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
53efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(size, Eq(10u));
54efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(buffer, NotNull());
55efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(in.ByteCount(), Eq(20u));
56efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
57efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
58efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  in.BackUp(5u);
59efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(in.ByteCount(), Eq(15u));
60efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
61efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
62efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(size, Eq(5u));
63efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(buffer, NotNull());
64efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(in.ByteCount(), Eq(20u));
65efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(StringPiece(buffer, size), Eq("strin"));
66efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
67efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  // Backup 1 more than possible. Should clamp.
68efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  in.BackUp(11u);
69efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(in.ByteCount(), Eq(10u));
70efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
71efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
72efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(size, Eq(10u));
73efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(buffer, NotNull());
74efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(in.ByteCount(), Eq(20u));
75efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(StringPiece(buffer, size), Eq("cool strin"));
76efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
77efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_TRUE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
78efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(size, Eq(1u));
79efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(buffer, NotNull());
80efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  ASSERT_THAT(in.ByteCount(), Eq(21u));
81efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_THAT(StringPiece(buffer, size), Eq("g"));
82efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
83efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_FALSE(in.Next(reinterpret_cast<const void**>(&buffer), &size));
84efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski  EXPECT_FALSE(in.HadError());
85efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski}
86efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski
87004511660671511ae88e0e837a6f92db28eadaefAdam LesinskiTEST(FileOutputStreamTest, NextAndBackup) {
88004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  const std::string input = "this is a cool string";
89004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
90004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  TemporaryFile file;
91004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
9293190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  FileOutputStream out(file.fd, 10u);
93004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_FALSE(out.HadError());
94004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(out.ByteCount(), Eq(0u));
95004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
96004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  char* buffer;
97004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  size_t size;
98004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
99004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(size, Eq(10u));
100004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(buffer, NotNull());
101004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(out.ByteCount(), Eq(10u));
102004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  memcpy(buffer, input.c_str(), size);
103004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
104004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
105004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(size, Eq(10u));
106004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(buffer, NotNull());
107004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(out.ByteCount(), Eq(20u));
108004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  memcpy(buffer, input.c_str() + 10u, size);
109004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
110004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_TRUE(out.Next(reinterpret_cast<void**>(&buffer), &size));
111004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(size, Eq(10u));
112004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_THAT(buffer, NotNull());
113004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(out.ByteCount(), Eq(30u));
114004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  buffer[0] = input[20u];
115004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  out.BackUp(size - 1);
116004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(out.ByteCount(), Eq(21u));
117004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
118004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  ASSERT_TRUE(out.Flush());
119004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
12093190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  lseek64(file.fd, 0, SEEK_SET);
121004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
122004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  std::string actual;
12393190b79d11d874199cfe7258526a48cfc8399fcAdam Lesinski  ASSERT_TRUE(android::base::ReadFdToString(file.fd, &actual));
124004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski  EXPECT_THAT(actual, StrEq(input));
125004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski}
126004511660671511ae88e0e837a6f92db28eadaefAdam Lesinski
127efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski}  // namespace io
128efeb7af13be4446ce4a511a2ca707691e9a67c1eAdam Lesinski}  // namespace aapt
129