mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2024-12-14 02:24:03 +01:00
122397acfc
Changes to the CEF public API: - Add base::Bind, base::Callback, base::Lock, base::WeakPtr, scoped_refptr, scoped_ptr and supporting types. - Add include/wrapper/cef_closure_task.h helpers for converting a base::Closure to a CefTask. - Change CefRefPtr to extend scoped_refptr. -- Change CefBase method signatures to match RefCountedThreadSafeBase. - Change IMPLEMENT_REFCOUNTING to use base::AtomicRefCount*. -- Remove the CefAtomic* functions. -- IMPLEMENT_REFCOUNTING now enforces via a compile-time error that the correct class name was passed to the macro. - Change IMPLEMENT_LOCKING to use base::Lock. -- Remove the CefCriticalSection class. -- Deprecate the IMPLEMENT_LOCKING macro. -- base::Lock will DCHECK() in Debug builds if lock usage is reentrant. - Move include/internal/cef_tuple.h to include/base/cef_tuple.h. - Allow an empty |callback| parameter passed to CefBeginTracing. Changes to the CEF implementation: - Fix incorrect names passed to the IMPLEMENT_REFCOUNTING macro. - Fix instances of reentrant locking in the CefXmlObject and CefRequest implementations. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cef_unittests: - Add tests/unittests/chromium_includes.h and always include it first from unit test .cc files to avoid name conflicts with Chromium types. - Fix wrong header include ordering. - Remove use of the IMPLEMENT_LOCKING macro. Changes to cefclient and cefsimple: - Use base::Bind and cef_closure_task.h instead of NewCefRunnable*. - Remove use of the IMPEMENT_LOCKING macro. - Fix incorrect/unnecessary locking. - Add additional runtime thread checks. - Windows: Perform actions on the UI thread instead of the main thread when running in multi-threaded-message-loop mode to avoid excessive locking. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1769 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
382 lines
9.7 KiB
C++
382 lines
9.7 KiB
C++
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
|
// reserved. Use of this source code is governed by a BSD-style license that
|
|
// can be found in the LICENSE file.
|
|
|
|
#include <algorithm>
|
|
|
|
// Include this first to avoid type conflicts with CEF headers.
|
|
#include "tests/unittests/chromium_includes.h"
|
|
|
|
#include "include/cef_stream.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
static void VerifyStreamReadBehavior(CefRefPtr<CefStreamReader> stream,
|
|
const std::string& contents) {
|
|
int contentSize = static_cast<int>(contents.size());
|
|
const char* contentStr = contents.c_str();
|
|
|
|
// Move to the beginning of the stream
|
|
ASSERT_EQ(0, stream->Seek(0, SEEK_SET));
|
|
ASSERT_EQ(0, stream->Tell());
|
|
|
|
// Move to the end of the stream
|
|
ASSERT_EQ(0, stream->Seek(0, SEEK_END));
|
|
ASSERT_EQ(contentSize, stream->Tell());
|
|
|
|
// Move to the beginning of the stream
|
|
ASSERT_EQ(0, stream->Seek(-contentSize, SEEK_CUR));
|
|
ASSERT_EQ(0, stream->Tell());
|
|
|
|
// Read 10 characters at a time and verify the result
|
|
char buff[10];
|
|
int res, read, offset = 0;
|
|
do {
|
|
read = std::min(static_cast<int>(sizeof(buff)), contentSize-offset);
|
|
res = static_cast<int>(stream->Read(buff, 1, read));
|
|
ASSERT_EQ(read, res);
|
|
ASSERT_TRUE(!memcmp(contentStr+offset, buff, res));
|
|
offset += res;
|
|
} while (offset < contentSize);
|
|
|
|
// Read past the end of the file
|
|
stream->Read(buff, 1, 1);
|
|
ASSERT_TRUE(stream->Eof());
|
|
}
|
|
|
|
static void VerifyStreamWriteBehavior(CefRefPtr<CefStreamWriter> stream,
|
|
const std::string& contents) {
|
|
int contentSize = static_cast<int>(contents.size());
|
|
const char* contentStr = contents.c_str();
|
|
|
|
// Write 10 characters at a time and verify the result
|
|
int res, write, offset = 0;
|
|
do {
|
|
write = std::min(10, contentSize-offset);
|
|
res = static_cast<int>(stream->Write(contentStr+offset, 1, write));
|
|
ASSERT_EQ(write, res);
|
|
offset += res;
|
|
ASSERT_EQ(offset, stream->Tell());
|
|
} while (offset < contentSize);
|
|
|
|
// Move to the beginning of the stream
|
|
ASSERT_EQ(0, stream->Seek(-contentSize, SEEK_CUR));
|
|
ASSERT_EQ(0, stream->Tell());
|
|
|
|
// Move to the end of the stream
|
|
ASSERT_EQ(0, stream->Seek(0, SEEK_END));
|
|
ASSERT_EQ(contentSize, stream->Tell());
|
|
|
|
// Move to the beginning of the stream
|
|
ASSERT_EQ(0, stream->Seek(0, SEEK_SET));
|
|
ASSERT_EQ(0, stream->Tell());
|
|
}
|
|
|
|
TEST(StreamTest, ReadFile) {
|
|
const char* fileName = "StreamTest.VerifyReadFile.txt";
|
|
CefString fileNameStr = "StreamTest.VerifyReadFile.txt";
|
|
std::string contents = "This is my test\ncontents for the file";
|
|
|
|
// Create the file
|
|
FILE* f = NULL;
|
|
#ifdef _WIN32
|
|
fopen_s(&f, fileName, "wb");
|
|
#else
|
|
f = fopen(fileName, "wb");
|
|
#endif
|
|
ASSERT_TRUE(f != NULL);
|
|
ASSERT_EQ((size_t)1, fwrite(contents.c_str(), contents.size(), 1, f));
|
|
fclose(f);
|
|
|
|
// Test the stream
|
|
CefRefPtr<CefStreamReader> stream(
|
|
CefStreamReader::CreateForFile(fileNameStr));
|
|
ASSERT_TRUE(stream.get() != NULL);
|
|
ASSERT_TRUE(stream->MayBlock());
|
|
VerifyStreamReadBehavior(stream, contents);
|
|
|
|
// Release the file pointer
|
|
stream = NULL;
|
|
|
|
// Delete the file
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(0, _unlink(fileName));
|
|
#else
|
|
ASSERT_EQ(0, unlink(fileName));
|
|
#endif
|
|
}
|
|
|
|
TEST(StreamTest, ReadData) {
|
|
std::string contents = "This is my test\ncontents for the file";
|
|
|
|
// Test the stream
|
|
CefRefPtr<CefStreamReader> stream(
|
|
CefStreamReader::CreateForData(
|
|
static_cast<void*>(const_cast<char*>(contents.c_str())),
|
|
contents.size()));
|
|
ASSERT_TRUE(stream.get() != NULL);
|
|
ASSERT_FALSE(stream->MayBlock());
|
|
VerifyStreamReadBehavior(stream, contents);
|
|
}
|
|
|
|
TEST(StreamTest, WriteFile) {
|
|
const char* fileName = "StreamTest.VerifyWriteFile.txt";
|
|
CefString fileNameStr = "StreamTest.VerifyWriteFile.txt";
|
|
std::string contents = "This is my test\ncontents for the file";
|
|
|
|
// Test the stream
|
|
CefRefPtr<CefStreamWriter> stream(
|
|
CefStreamWriter::CreateForFile(fileNameStr));
|
|
ASSERT_TRUE(stream.get() != NULL);
|
|
ASSERT_TRUE(stream->MayBlock());
|
|
VerifyStreamWriteBehavior(stream, contents);
|
|
|
|
// Release the file pointer
|
|
stream = NULL;
|
|
|
|
// Read the file that was written
|
|
FILE* f = NULL;
|
|
char* buff = new char[contents.size()];
|
|
#ifdef _WIN32
|
|
fopen_s(&f, fileName, "rb");
|
|
#else
|
|
f = fopen(fileName, "rb");
|
|
#endif
|
|
ASSERT_TRUE(f != NULL);
|
|
ASSERT_EQ((size_t)1, fread(buff, contents.size(), 1, f));
|
|
|
|
// Read past the end of the file
|
|
fgetc(f);
|
|
ASSERT_TRUE(feof(f));
|
|
fclose(f);
|
|
|
|
// Verify the file contents
|
|
ASSERT_TRUE(!memcmp(contents.c_str(), buff, contents.size()));
|
|
delete [] buff;
|
|
|
|
// Delete the file
|
|
#ifdef _WIN32
|
|
ASSERT_EQ(0, _unlink(fileName));
|
|
#else
|
|
ASSERT_EQ(0, unlink(fileName));
|
|
#endif
|
|
}
|
|
|
|
bool g_ReadHandlerTesterDeleted = false;
|
|
|
|
class ReadHandlerTester : public CefReadHandler {
|
|
public:
|
|
ReadHandlerTester()
|
|
: read_called_(false),
|
|
read_ptr_(NULL),
|
|
read_size_(0),
|
|
read_n_(0),
|
|
seek_called_(false),
|
|
seek_offset_(0),
|
|
seek_whence_(0),
|
|
tell_called_(false),
|
|
eof_called_(false) {
|
|
}
|
|
virtual ~ReadHandlerTester() {
|
|
g_ReadHandlerTesterDeleted = true;
|
|
}
|
|
|
|
virtual size_t Read(void* ptr, size_t size, size_t n) OVERRIDE {
|
|
read_called_ = true;
|
|
read_ptr_ = ptr;
|
|
read_size_ = size;
|
|
read_n_ = n;
|
|
return 10;
|
|
}
|
|
|
|
virtual int Seek(int64 offset, int whence) OVERRIDE {
|
|
seek_called_ = true;
|
|
seek_offset_ = offset;
|
|
seek_whence_ = whence;
|
|
return 10;
|
|
}
|
|
|
|
virtual int64 Tell() OVERRIDE {
|
|
tell_called_ = true;
|
|
return 10;
|
|
}
|
|
|
|
virtual int Eof() OVERRIDE {
|
|
eof_called_ = true;
|
|
return 10;
|
|
}
|
|
|
|
virtual bool MayBlock() OVERRIDE {
|
|
return false;
|
|
}
|
|
|
|
bool read_called_;
|
|
const void* read_ptr_;
|
|
size_t read_size_;
|
|
size_t read_n_;
|
|
|
|
bool seek_called_;
|
|
int64 seek_offset_;
|
|
int seek_whence_;
|
|
|
|
bool tell_called_;
|
|
|
|
bool eof_called_;
|
|
|
|
IMPLEMENT_REFCOUNTING(ReadHandlerTester);
|
|
};
|
|
|
|
TEST(StreamTest, ReadHandler) {
|
|
ReadHandlerTester* handler = new ReadHandlerTester();
|
|
ASSERT_TRUE(handler != NULL);
|
|
|
|
CefRefPtr<CefStreamReader> stream(CefStreamReader::CreateForHandler(handler));
|
|
ASSERT_TRUE(stream.get() != NULL);
|
|
ASSERT_FALSE(stream->MayBlock());
|
|
|
|
// CefReadHandler Read
|
|
const char* read_ptr = "My data";
|
|
size_t read_size = sizeof(read_ptr);
|
|
size_t read_n = 1;
|
|
size_t read_res = stream->Read(
|
|
static_cast<void*>(const_cast<char*>(read_ptr)), read_size, read_n);
|
|
ASSERT_TRUE(handler->read_called_);
|
|
ASSERT_EQ((size_t)10, read_res);
|
|
ASSERT_EQ(read_ptr, handler->read_ptr_);
|
|
ASSERT_EQ(read_size, handler->read_size_);
|
|
ASSERT_EQ(read_n, handler->read_n_);
|
|
|
|
// CefReadHandler Seek
|
|
int64 seek_offset = 10;
|
|
int seek_whence = SEEK_CUR;
|
|
int seek_res = stream->Seek(seek_offset, seek_whence);
|
|
ASSERT_TRUE(handler->seek_called_);
|
|
ASSERT_EQ(10, seek_res);
|
|
ASSERT_EQ(seek_offset, handler->seek_offset_);
|
|
ASSERT_EQ(seek_whence, handler->seek_whence_);
|
|
|
|
// CefReadHandler Tell
|
|
int64 tell_res = stream->Tell();
|
|
ASSERT_TRUE(handler->tell_called_);
|
|
ASSERT_EQ(10, tell_res);
|
|
|
|
// CefReadHandler Eof
|
|
int eof_res = stream->Eof();
|
|
ASSERT_TRUE(handler->eof_called_);
|
|
ASSERT_EQ(10, eof_res);
|
|
|
|
// Delete the stream
|
|
stream = NULL;
|
|
|
|
// Verify that the handler object was deleted
|
|
ASSERT_TRUE(g_ReadHandlerTesterDeleted);
|
|
}
|
|
|
|
bool g_WriteHandlerTesterDeleted = false;
|
|
|
|
class WriteHandlerTester : public CefWriteHandler {
|
|
public:
|
|
WriteHandlerTester()
|
|
: write_called_(false),
|
|
write_ptr_(NULL),
|
|
write_size_(0),
|
|
write_n_(0),
|
|
seek_called_(false),
|
|
seek_offset_(0),
|
|
seek_whence_(0),
|
|
tell_called_(false),
|
|
flush_called_(false) {
|
|
}
|
|
virtual ~WriteHandlerTester() {
|
|
g_WriteHandlerTesterDeleted = true;
|
|
}
|
|
|
|
virtual size_t Write(const void* ptr, size_t size, size_t n) OVERRIDE {
|
|
write_called_ = true;
|
|
write_ptr_ = ptr;
|
|
write_size_ = size;
|
|
write_n_ = n;
|
|
return 10;
|
|
}
|
|
|
|
virtual int Seek(int64 offset, int whence) OVERRIDE {
|
|
seek_called_ = true;
|
|
seek_offset_ = offset;
|
|
seek_whence_ = whence;
|
|
return 10;
|
|
}
|
|
|
|
virtual int64 Tell() OVERRIDE {
|
|
tell_called_ = true;
|
|
return 10;
|
|
}
|
|
|
|
virtual int Flush() OVERRIDE {
|
|
flush_called_ = true;
|
|
return 10;
|
|
}
|
|
|
|
virtual bool MayBlock() OVERRIDE {
|
|
return false;
|
|
}
|
|
|
|
bool write_called_;
|
|
const void* write_ptr_;
|
|
size_t write_size_;
|
|
size_t write_n_;
|
|
|
|
bool seek_called_;
|
|
int64 seek_offset_;
|
|
int seek_whence_;
|
|
|
|
bool tell_called_;
|
|
|
|
bool flush_called_;
|
|
|
|
IMPLEMENT_REFCOUNTING(WriteHandlerTester);
|
|
};
|
|
|
|
TEST(StreamTest, WriteHandler) {
|
|
WriteHandlerTester* handler = new WriteHandlerTester();
|
|
ASSERT_TRUE(handler != NULL);
|
|
|
|
CefRefPtr<CefStreamWriter> stream(CefStreamWriter::CreateForHandler(handler));
|
|
ASSERT_TRUE(stream.get() != NULL);
|
|
ASSERT_FALSE(stream->MayBlock());
|
|
|
|
// CefWriteHandler Write
|
|
const char* write_ptr = "My data";
|
|
size_t write_size = sizeof(write_ptr);
|
|
size_t write_n = 1;
|
|
size_t write_res = stream->Write(write_ptr, write_size, write_n);
|
|
ASSERT_TRUE(handler->write_called_);
|
|
ASSERT_EQ((size_t)10, write_res);
|
|
ASSERT_EQ(write_ptr, handler->write_ptr_);
|
|
ASSERT_EQ(write_size, handler->write_size_);
|
|
ASSERT_EQ(write_n, handler->write_n_);
|
|
|
|
// CefWriteHandler Seek
|
|
int64 seek_offset = 10;
|
|
int seek_whence = SEEK_CUR;
|
|
int seek_res = stream->Seek(seek_offset, seek_whence);
|
|
ASSERT_TRUE(handler->seek_called_);
|
|
ASSERT_EQ(10, seek_res);
|
|
ASSERT_EQ(seek_offset, handler->seek_offset_);
|
|
ASSERT_EQ(seek_whence, handler->seek_whence_);
|
|
|
|
// CefWriteHandler Tell
|
|
int64 tell_res = stream->Tell();
|
|
ASSERT_TRUE(handler->tell_called_);
|
|
ASSERT_EQ(10, tell_res);
|
|
|
|
// CefWriteHandler Flush
|
|
int flush_res = stream->Flush();
|
|
ASSERT_TRUE(handler->flush_called_);
|
|
ASSERT_EQ(10, flush_res);
|
|
|
|
// Delete the stream
|
|
stream = NULL;
|
|
|
|
// Verify that the handler object was deleted
|
|
ASSERT_TRUE(g_WriteHandlerTesterDeleted);
|
|
}
|