• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include <algorithm>
6 
7 #include "include/cef_stream.h"
8 #include "tests/gtest/include/gtest/gtest.h"
9 
VerifyStreamReadBehavior(CefRefPtr<CefStreamReader> stream,const std::string & contents)10 static void VerifyStreamReadBehavior(CefRefPtr<CefStreamReader> stream,
11                                      const std::string& contents) {
12   int contentSize = static_cast<int>(contents.size());
13   const char* contentStr = contents.c_str();
14 
15   // Move to the beginning of the stream
16   ASSERT_EQ(0, stream->Seek(0, SEEK_SET));
17   ASSERT_EQ(0, stream->Tell());
18 
19   // Move to the end of the stream
20   ASSERT_EQ(0, stream->Seek(0, SEEK_END));
21   ASSERT_EQ(contentSize, stream->Tell());
22 
23   // Move to the beginning of the stream
24   ASSERT_EQ(0, stream->Seek(-contentSize, SEEK_CUR));
25   ASSERT_EQ(0, stream->Tell());
26 
27   // Read 10 characters at a time and verify the result
28   char buff[10];
29   int res, read, offset = 0;
30   do {
31     read = std::min(static_cast<int>(sizeof(buff)), contentSize - offset);
32     res = static_cast<int>(stream->Read(buff, 1, read));
33     ASSERT_EQ(read, res);
34     ASSERT_TRUE(!memcmp(contentStr + offset, buff, res));
35     offset += res;
36   } while (offset < contentSize);
37 
38   // Read past the end of the file
39   stream->Read(buff, 1, 1);
40   ASSERT_TRUE(stream->Eof());
41 }
42 
VerifyStreamWriteBehavior(CefRefPtr<CefStreamWriter> stream,const std::string & contents)43 static void VerifyStreamWriteBehavior(CefRefPtr<CefStreamWriter> stream,
44                                       const std::string& contents) {
45   int contentSize = static_cast<int>(contents.size());
46   const char* contentStr = contents.c_str();
47 
48   // Write 10 characters at a time and verify the result
49   int res, write, offset = 0;
50   do {
51     write = std::min(10, contentSize - offset);
52     res = static_cast<int>(stream->Write(contentStr + offset, 1, write));
53     ASSERT_EQ(write, res);
54     offset += res;
55     ASSERT_EQ(offset, stream->Tell());
56   } while (offset < contentSize);
57 
58   // Move to the beginning of the stream
59   ASSERT_EQ(0, stream->Seek(-contentSize, SEEK_CUR));
60   ASSERT_EQ(0, stream->Tell());
61 
62   // Move to the end of the stream
63   ASSERT_EQ(0, stream->Seek(0, SEEK_END));
64   ASSERT_EQ(contentSize, stream->Tell());
65 
66   // Move to the beginning of the stream
67   ASSERT_EQ(0, stream->Seek(0, SEEK_SET));
68   ASSERT_EQ(0, stream->Tell());
69 }
70 
TEST(StreamTest,ReadFile)71 TEST(StreamTest, ReadFile) {
72   const char* fileName = "StreamTest.VerifyReadFile.txt";
73   CefString fileNameStr = "StreamTest.VerifyReadFile.txt";
74   std::string contents = "This is my test\ncontents for the file";
75 
76   // Create the file
77   FILE* f = nullptr;
78 #ifdef _WIN32
79   fopen_s(&f, fileName, "wb");
80 #else
81   f = fopen(fileName, "wb");
82 #endif
83   ASSERT_TRUE(f != nullptr);
84   ASSERT_EQ((size_t)1, fwrite(contents.c_str(), contents.size(), 1, f));
85   fclose(f);
86 
87   // Test the stream
88   CefRefPtr<CefStreamReader> stream(
89       CefStreamReader::CreateForFile(fileNameStr));
90   ASSERT_TRUE(stream.get() != nullptr);
91   ASSERT_TRUE(stream->MayBlock());
92   VerifyStreamReadBehavior(stream, contents);
93 
94   // Release the file pointer
95   stream = nullptr;
96 
97 // Delete the file
98 #ifdef _WIN32
99   ASSERT_EQ(0, _unlink(fileName));
100 #else
101   ASSERT_EQ(0, unlink(fileName));
102 #endif
103 }
104 
TEST(StreamTest,ReadData)105 TEST(StreamTest, ReadData) {
106   std::string contents = "This is my test\ncontents for the file";
107 
108   // Test the stream
109   CefRefPtr<CefStreamReader> stream(CefStreamReader::CreateForData(
110       static_cast<void*>(const_cast<char*>(contents.c_str())),
111       contents.size()));
112   ASSERT_TRUE(stream.get() != nullptr);
113   ASSERT_FALSE(stream->MayBlock());
114   VerifyStreamReadBehavior(stream, contents);
115 }
116 
TEST(StreamTest,WriteFile)117 TEST(StreamTest, WriteFile) {
118   const char* fileName = "StreamTest.VerifyWriteFile.txt";
119   CefString fileNameStr = "StreamTest.VerifyWriteFile.txt";
120   std::string contents = "This is my test\ncontents for the file";
121 
122   // Test the stream
123   CefRefPtr<CefStreamWriter> stream(
124       CefStreamWriter::CreateForFile(fileNameStr));
125   ASSERT_TRUE(stream.get() != nullptr);
126   ASSERT_TRUE(stream->MayBlock());
127   VerifyStreamWriteBehavior(stream, contents);
128 
129   // Release the file pointer
130   stream = nullptr;
131 
132   // Read the file that was written
133   FILE* f = nullptr;
134   char* buff = new char[contents.size()];
135 #ifdef _WIN32
136   fopen_s(&f, fileName, "rb");
137 #else
138   f = fopen(fileName, "rb");
139 #endif
140   ASSERT_TRUE(f != nullptr);
141   ASSERT_EQ((size_t)1, fread(buff, contents.size(), 1, f));
142 
143   // Read past the end of the file
144   fgetc(f);
145   ASSERT_TRUE(feof(f));
146   fclose(f);
147 
148   // Verify the file contents
149   ASSERT_TRUE(!memcmp(contents.c_str(), buff, contents.size()));
150   delete[] buff;
151 
152 // Delete the file
153 #ifdef _WIN32
154   ASSERT_EQ(0, _unlink(fileName));
155 #else
156   ASSERT_EQ(0, unlink(fileName));
157 #endif
158 }
159 
160 bool g_ReadHandlerTesterDeleted = false;
161 
162 class ReadHandlerTester : public CefReadHandler {
163  public:
ReadHandlerTester()164   ReadHandlerTester()
165       : read_called_(false),
166         read_ptr_(nullptr),
167         read_size_(0),
168         read_n_(0),
169         seek_called_(false),
170         seek_offset_(0),
171         seek_whence_(0),
172         tell_called_(false),
173         eof_called_(false) {}
~ReadHandlerTester()174   ~ReadHandlerTester() override { g_ReadHandlerTesterDeleted = true; }
175 
Read(void * ptr,size_t size,size_t n)176   size_t Read(void* ptr, size_t size, size_t n) override {
177     read_called_ = true;
178     read_ptr_ = ptr;
179     read_size_ = size;
180     read_n_ = n;
181     return 10;
182   }
183 
Seek(int64 offset,int whence)184   int Seek(int64 offset, int whence) override {
185     seek_called_ = true;
186     seek_offset_ = offset;
187     seek_whence_ = whence;
188     return 10;
189   }
190 
Tell()191   int64 Tell() override {
192     tell_called_ = true;
193     return 10;
194   }
195 
Eof()196   int Eof() override {
197     eof_called_ = true;
198     return 10;
199   }
200 
MayBlock()201   bool MayBlock() override { return false; }
202 
203   bool read_called_;
204   const void* read_ptr_;
205   size_t read_size_;
206   size_t read_n_;
207 
208   bool seek_called_;
209   int64 seek_offset_;
210   int seek_whence_;
211 
212   bool tell_called_;
213 
214   bool eof_called_;
215 
216   IMPLEMENT_REFCOUNTING(ReadHandlerTester);
217 };
218 
TEST(StreamTest,ReadHandler)219 TEST(StreamTest, ReadHandler) {
220   ReadHandlerTester* handler = new ReadHandlerTester();
221   ASSERT_TRUE(handler != nullptr);
222 
223   CefRefPtr<CefStreamReader> stream(CefStreamReader::CreateForHandler(handler));
224   ASSERT_TRUE(stream.get() != nullptr);
225   ASSERT_FALSE(stream->MayBlock());
226 
227   // CefReadHandler Read
228   const char* read_ptr = "My data";
229   size_t read_size = sizeof(read_ptr);
230   size_t read_n = 1;
231   size_t read_res = stream->Read(
232       static_cast<void*>(const_cast<char*>(read_ptr)), read_size, read_n);
233   ASSERT_TRUE(handler->read_called_);
234   ASSERT_EQ((size_t)10, read_res);
235   ASSERT_EQ(read_ptr, handler->read_ptr_);
236   ASSERT_EQ(read_size, handler->read_size_);
237   ASSERT_EQ(read_n, handler->read_n_);
238 
239   // CefReadHandler Seek
240   int64 seek_offset = 10;
241   int seek_whence = SEEK_CUR;
242   int seek_res = stream->Seek(seek_offset, seek_whence);
243   ASSERT_TRUE(handler->seek_called_);
244   ASSERT_EQ(10, seek_res);
245   ASSERT_EQ(seek_offset, handler->seek_offset_);
246   ASSERT_EQ(seek_whence, handler->seek_whence_);
247 
248   // CefReadHandler Tell
249   int64 tell_res = stream->Tell();
250   ASSERT_TRUE(handler->tell_called_);
251   ASSERT_EQ(10, tell_res);
252 
253   // CefReadHandler Eof
254   int eof_res = stream->Eof();
255   ASSERT_TRUE(handler->eof_called_);
256   ASSERT_EQ(10, eof_res);
257 
258   // Delete the stream
259   stream = nullptr;
260 
261   // Verify that the handler object was deleted
262   ASSERT_TRUE(g_ReadHandlerTesterDeleted);
263 }
264 
265 bool g_WriteHandlerTesterDeleted = false;
266 
267 class WriteHandlerTester : public CefWriteHandler {
268  public:
WriteHandlerTester()269   WriteHandlerTester()
270       : write_called_(false),
271         write_ptr_(nullptr),
272         write_size_(0),
273         write_n_(0),
274         seek_called_(false),
275         seek_offset_(0),
276         seek_whence_(0),
277         tell_called_(false),
278         flush_called_(false) {}
~WriteHandlerTester()279   ~WriteHandlerTester() override { g_WriteHandlerTesterDeleted = true; }
280 
Write(const void * ptr,size_t size,size_t n)281   size_t Write(const void* ptr, size_t size, size_t n) override {
282     write_called_ = true;
283     write_ptr_ = ptr;
284     write_size_ = size;
285     write_n_ = n;
286     return 10;
287   }
288 
Seek(int64 offset,int whence)289   int Seek(int64 offset, int whence) override {
290     seek_called_ = true;
291     seek_offset_ = offset;
292     seek_whence_ = whence;
293     return 10;
294   }
295 
Tell()296   int64 Tell() override {
297     tell_called_ = true;
298     return 10;
299   }
300 
Flush()301   int Flush() override {
302     flush_called_ = true;
303     return 10;
304   }
305 
MayBlock()306   bool MayBlock() override { return false; }
307 
308   bool write_called_;
309   const void* write_ptr_;
310   size_t write_size_;
311   size_t write_n_;
312 
313   bool seek_called_;
314   int64 seek_offset_;
315   int seek_whence_;
316 
317   bool tell_called_;
318 
319   bool flush_called_;
320 
321   IMPLEMENT_REFCOUNTING(WriteHandlerTester);
322 };
323 
TEST(StreamTest,WriteHandler)324 TEST(StreamTest, WriteHandler) {
325   WriteHandlerTester* handler = new WriteHandlerTester();
326   ASSERT_TRUE(handler != nullptr);
327 
328   CefRefPtr<CefStreamWriter> stream(CefStreamWriter::CreateForHandler(handler));
329   ASSERT_TRUE(stream.get() != nullptr);
330   ASSERT_FALSE(stream->MayBlock());
331 
332   // CefWriteHandler Write
333   const char* write_ptr = "My data";
334   size_t write_size = sizeof(write_ptr);
335   size_t write_n = 1;
336   size_t write_res = stream->Write(write_ptr, write_size, write_n);
337   ASSERT_TRUE(handler->write_called_);
338   ASSERT_EQ((size_t)10, write_res);
339   ASSERT_EQ(write_ptr, handler->write_ptr_);
340   ASSERT_EQ(write_size, handler->write_size_);
341   ASSERT_EQ(write_n, handler->write_n_);
342 
343   // CefWriteHandler Seek
344   int64 seek_offset = 10;
345   int seek_whence = SEEK_CUR;
346   int seek_res = stream->Seek(seek_offset, seek_whence);
347   ASSERT_TRUE(handler->seek_called_);
348   ASSERT_EQ(10, seek_res);
349   ASSERT_EQ(seek_offset, handler->seek_offset_);
350   ASSERT_EQ(seek_whence, handler->seek_whence_);
351 
352   // CefWriteHandler Tell
353   int64 tell_res = stream->Tell();
354   ASSERT_TRUE(handler->tell_called_);
355   ASSERT_EQ(10, tell_res);
356 
357   // CefWriteHandler Flush
358   int flush_res = stream->Flush();
359   ASSERT_TRUE(handler->flush_called_);
360   ASSERT_EQ(10, flush_res);
361 
362   // Delete the stream
363   stream = nullptr;
364 
365   // Verify that the handler object was deleted
366   ASSERT_TRUE(g_WriteHandlerTesterDeleted);
367 }
368