From 5a4c8f5a13eb02e21ba81c9ba6a8bf4477909c4c Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Sun, 24 Oct 2010 16:41:21 +0000 Subject: [PATCH] Expose zip archive reading support (issue #30). Move ClientReadHandler to CefByteReadHandler in cef_wrapper.h. Add support for the time_t data type to cef_parser.py. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@125 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- cef.gyp | 9 + include/cef.h | 72 ++++- include/cef_capi.h | 66 ++++- include/cef_wrapper.h | 98 +++++++ libcef/zip_reader_impl.cc | 298 ++++++++++++++++++++ libcef/zip_reader_impl.h | 52 ++++ libcef_dll/cpptoc/zip_reader_cpptoc.cc | 180 ++++++++++++ libcef_dll/cpptoc/zip_reader_cpptoc.h | 34 +++ libcef_dll/ctocpp/zip_reader_ctocpp.cc | 141 +++++++++ libcef_dll/ctocpp/zip_reader_ctocpp.h | 50 ++++ libcef_dll/libcef_dll.cc | 2 + libcef_dll/wrapper/cef_byte_read_handler.cc | 67 +++++ libcef_dll/wrapper/cef_zip_archive.cc | 163 +++++++++++ libcef_dll/wrapper/libcef_dll_wrapper.cc | 2 + tests/cefclient/cefclient.cpp | 7 +- tests/cefclient/resource_util.cpp | 65 ----- tests/cefclient/resource_util.h | 29 -- tests/cefclient/scheme_test.cpp | 1 + tests/unittests/zip_reader_unittest.cc | 254 +++++++++++++++++ tools/cef_parser.py | 1 + 20 files changed, 1492 insertions(+), 99 deletions(-) create mode 100644 libcef/zip_reader_impl.cc create mode 100644 libcef/zip_reader_impl.h create mode 100644 libcef_dll/cpptoc/zip_reader_cpptoc.cc create mode 100644 libcef_dll/cpptoc/zip_reader_cpptoc.h create mode 100644 libcef_dll/ctocpp/zip_reader_ctocpp.cc create mode 100644 libcef_dll/ctocpp/zip_reader_ctocpp.h create mode 100644 libcef_dll/wrapper/cef_byte_read_handler.cc create mode 100644 libcef_dll/wrapper/cef_zip_archive.cc create mode 100644 tests/unittests/zip_reader_unittest.cc diff --git a/cef.gyp b/cef.gyp index 777f8d614..923480f20 100644 --- a/cef.gyp +++ b/cef.gyp @@ -99,6 +99,7 @@ 'tests/unittests/test_suite.h', 'tests/unittests/v8_unittest.cc', 'tests/unittests/xml_reader_unittest.cc', + 'tests/unittests/zip_reader_unittest.cc', ], 'include_dirs': [ '.', @@ -219,6 +220,8 @@ 'libcef_dll/cpptoc/v8value_cpptoc.h', 'libcef_dll/cpptoc/xml_reader_cpptoc.cc', 'libcef_dll/cpptoc/xml_reader_cpptoc.h', + 'libcef_dll/cpptoc/zip_reader_cpptoc.cc', + 'libcef_dll/cpptoc/zip_reader_cpptoc.h', 'libcef_dll/ctocpp/ctocpp.h', 'libcef_dll/ctocpp/download_handler_ctocpp.cc', 'libcef_dll/ctocpp/download_handler_ctocpp.h', @@ -315,9 +318,13 @@ 'libcef_dll/ctocpp/v8value_ctocpp.h', 'libcef_dll/ctocpp/xml_reader_ctocpp.cc', 'libcef_dll/ctocpp/xml_reader_ctocpp.h', + 'libcef_dll/ctocpp/zip_reader_ctocpp.cc', + 'libcef_dll/ctocpp/zip_reader_ctocpp.h', 'libcef_dll/transfer_util.cpp', 'libcef_dll/transfer_util.h', + 'libcef_dll/wrapper/cef_byte_read_handler.cc', 'libcef_dll/wrapper/cef_xml_object.cc', + 'libcef_dll/wrapper/cef_zip_archive.cc', 'libcef_dll/wrapper/libcef_dll_wrapper.cc', ], }, @@ -431,6 +438,8 @@ 'libcef/webwidget_host.h', 'libcef/xml_reader_impl.cc', 'libcef/xml_reader_impl.h', + 'libcef/zip_reader_impl.cc', + 'libcef/zip_reader_impl.h', ], 'conditions': [ ['OS=="win"', { diff --git a/include/cef.h b/include/cef.h index 6898823c6..68d793bf3 100644 --- a/include/cef.h +++ b/include/cef.h @@ -1272,7 +1272,7 @@ public: /*--cef()--*/ virtual bool MoveToNextNode() =0; - // Close the document. This must be called directly to ensure that cleanup + // Close the document. This should be called directly to ensure that cleanup // occurs on the correct thread. /*--cef()--*/ virtual bool Close() =0; @@ -1412,4 +1412,74 @@ public: virtual bool MoveToCarryingElement() =0; }; + +// Class that supports the reading of zip archives via the zlib unzip API. +/*--cef(source=library)--*/ +class CefZipReader : public CefBase +{ +public: + // Create a new CefZipReader object. The returned object's methods can only + // be called from the thread that created the object. + /*--cef()--*/ + static CefRefPtr Create(CefRefPtr stream); + + // Moves the cursor to the first file in the archive. Returns true if the + // cursor position was set successfully. + /*--cef()--*/ + virtual bool MoveToFirstFile() =0; + + // Moves the cursor to the next file in the archive. Returns true if the + // cursor position was set successfully. + /*--cef()--*/ + virtual bool MoveToNextFile() =0; + + // Moves the cursor to the specified file in the archive. If |caseSensitive| + // is true then the search will be case sensitive. Returns true if the cursor + // position was set successfully. + /*--cef()--*/ + virtual bool MoveToFile(const std::wstring& fileName, bool caseSensitive) =0; + + // Closes the archive. This should be called directly to ensure that cleanup + // occurs on the correct thread. + /*--cef()--*/ + virtual bool Close() =0; + + + // The below methods act on the file at the current cursor position. + + // Returns the name of the file. + /*--cef()--*/ + virtual std::wstring GetFileName() =0; + + // Returns the uncompressed size of the file. + /*--cef()--*/ + virtual long GetFileSize() =0; + + // Returns the last modified timestamp for the file. + /*--cef()--*/ + virtual time_t GetFileLastModified() =0; + + // Opens the file for reading of uncompressed data. A read password may + // optionally be specified. + /*--cef()--*/ + virtual bool OpenFile(const std::wstring& password) =0; + + // Closes the file. + /*--cef()--*/ + virtual bool CloseFile() =0; + + // Read uncompressed file contents into the specified buffer. Returns < 0 if + // an error occurred, 0 if at the end of file, or the number of bytes read. + /*--cef()--*/ + virtual int ReadFile(void* buffer, size_t bufferSize) =0; + + // Returns the current offset in the uncompressed file contents. + /*--cef()--*/ + virtual long Tell() =0; + + // Returns true if at end of the file contents. + /*--cef()--*/ + virtual bool Eof() =0; +}; + #endif // _CEF_H diff --git a/include/cef_capi.h b/include/cef_capi.h index 71d830bd0..2d07fdcdc 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -1015,7 +1015,7 @@ typedef struct _cef_xml_reader_t // if the cursor position was set successfully. int (CEF_CALLBACK *move_to_next_node)(struct _cef_xml_reader_t* self); - // Close the document. This must be called directly to ensure that cleanup + // Close the document. This should be called directly to ensure that cleanup // occurs on the correct thread. int (CEF_CALLBACK *close)(struct _cef_xml_reader_t* self); @@ -1157,6 +1157,70 @@ CEF_EXPORT cef_xml_reader_t* cef_xml_reader_create(cef_stream_reader_t* stream, enum cef_xml_encoding_type_t encodingType, const wchar_t* URI); +// Structure that supports the reading of zip archives via the zlib unzip API. +typedef struct _cef_zip_reader_t +{ + // Base structure. + cef_base_t base; + + // Moves the cursor to the first file in the archive. Returns true (1) if the + // cursor position was set successfully. + int (CEF_CALLBACK *move_to_first_file)(struct _cef_zip_reader_t* self); + + // Moves the cursor to the next file in the archive. Returns true (1) if the + // cursor position was set successfully. + int (CEF_CALLBACK *move_to_next_file)(struct _cef_zip_reader_t* self); + + // Moves the cursor to the specified file in the archive. If |caseSensitive| + // is true (1) then the search will be case sensitive. Returns true (1) if the + // cursor position was set successfully. + int (CEF_CALLBACK *move_to_file)(struct _cef_zip_reader_t* self, + const wchar_t* fileName, int caseSensitive); + + // Closes the archive. This should be called directly to ensure that cleanup + // occurs on the correct thread. + int (CEF_CALLBACK *close)(struct _cef_zip_reader_t* self); + + + // The below functions act on the file at the current cursor position. + + // Returns the name of the file. + // The resulting string must be freed by calling cef_string_free(). + cef_string_t (CEF_CALLBACK *get_file_name)(struct _cef_zip_reader_t* self); + + // Returns the uncompressed size of the file. + long (CEF_CALLBACK *get_file_size)(struct _cef_zip_reader_t* self); + + // Returns the last modified timestamp for the file. + time_t (CEF_CALLBACK *get_file_last_modified)(struct _cef_zip_reader_t* self); + + // Opens the file for reading of uncompressed data. A read password may + // optionally be specified. + int (CEF_CALLBACK *open_file)(struct _cef_zip_reader_t* self, + const wchar_t* password); + + // Closes the file. + int (CEF_CALLBACK *close_file)(struct _cef_zip_reader_t* self); + + // Read uncompressed file contents into the specified buffer. Returns < 0 if + // an error occurred, 0 if at the end of file, or the number of bytes read. + int (CEF_CALLBACK *read_file)(struct _cef_zip_reader_t* self, void* buffer, + size_t bufferSize); + + // Returns the current offset in the uncompressed file contents. + long (CEF_CALLBACK *tell)(struct _cef_zip_reader_t* self); + + // Returns true (1) if at end of the file contents. + int (CEF_CALLBACK *eof)(struct _cef_zip_reader_t* self); + +} cef_zip_reader_t; + + +// Create a new cef_zip_reader_t object. The returned object's functions can +// only be called from the thread that created the object. +CEF_EXPORT cef_zip_reader_t* cef_zip_reader_create(cef_stream_reader_t* stream); + + #ifdef __cplusplus } #endif diff --git a/include/cef_wrapper.h b/include/cef_wrapper.h index 947fdf74f..04b64f1de 100644 --- a/include/cef_wrapper.h +++ b/include/cef_wrapper.h @@ -40,6 +40,11 @@ #include #include +#ifndef min +#define min(a,b) ((a)<(b)?(a):(b)) +#endif + + // Thread safe class for representing XML data as a structured object. This // class should not be used with large XML documents because all data will be // resident in memory at the same time. This implementation supports a @@ -149,4 +154,97 @@ private: ObjectVector children_; }; + +// Thread safe implementation of the CefReadHandler class for reading an +// in-memory array of bytes. +class CefByteReadHandler : public CefThreadSafeBase +{ +public: + // Create a new object for reading an array of bytes. An optional |source| + // reference can be kept to keep the underlying data source from being + // released while the reader exists. + CefByteReadHandler(const unsigned char* bytes, size_t size, + CefRefPtr source); + + // Read raw binary data. + virtual size_t Read(void* ptr, size_t size, size_t n); + + // Seek to the specified offset position. |whence| may be any one of + // SEEK_CUR, SEEK_END or SEEK_SET. + virtual int Seek(long offset, int whence); + + // Return the current offset position. + virtual long Tell(); + + // Return non-zero if at end of file. + virtual int Eof(); + +private: + const unsigned char* bytes_; + size_t size_; + size_t offset_; + CefRefPtr source_; +}; + + +// Thread-safe class for accessing zip archive file contents. This class should +// not be used with large archive files because all data will be resident in +// memory at the same time. This implementation supports a restricted set of zip +// archive features: +// (1) Password-protected files are not supported. +// (2) All file names are stored and compared in lower case. +// (3) File ordering from the original zip archive is not maintained. This +// means that files from the same folder may not be located together in the +// file content map. +class CefZipArchive : public CefThreadSafeBase +{ +public: + // Class representing a file in the archive. Accessing the file data from + // multiple threads is safe provided a reference to the File object is kept. + class File : public CefBase + { + public: + // Returns the read-only data contained in the file. + virtual const unsigned char* GetData() =0; + + // Returns the size of the data in the file. + virtual size_t GetDataSize() =0; + + // Returns a CefStreamReader object for streaming the contents of the file. + virtual CefRefPtr GetStreamReader() =0; + }; + typedef std::map > FileMap; + + // Create a new object. + CefZipArchive(); + virtual ~CefZipArchive(); + + // Load the contents of the specified zip archive stream into this object. + // If |overwriteExisting| is true then any files in this object that also + // exist in the specified archive will be replaced with the new files. + // Returns the number of files successfully loaded. + size_t Load(CefRefPtr stream, bool overwriteExisting); + + // Clears the contents of this object. + void Clear(); + + // Returns the number of files in the archive. + size_t GetFileCount(); + + // Returns true if the specified file exists and has contents. + bool HasFile(const std::wstring& fileName); + + // Returns the specified file. + CefRefPtr GetFile(const std::wstring& fileName); + + // Removes the specified file. + bool RemoveFile(const std::wstring& fileName); + + // Returns the map of all files. + size_t GetFiles(FileMap& map); + +private: + FileMap contents_; +}; + #endif // _CEF_WRAPPER_H diff --git a/libcef/zip_reader_impl.cc b/libcef/zip_reader_impl.cc new file mode 100644 index 000000000..4384c533e --- /dev/null +++ b/libcef/zip_reader_impl.cc @@ -0,0 +1,298 @@ +// Copyright (c) 20010 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 "zip_reader_impl.h" +#include "base/logging.h" +#include "base/utf_string_conversions.h" +#include + +// Static functions + +//static +CefRefPtr CefZipReader::Create(CefRefPtr stream) +{ + CefRefPtr impl(new CefZipReaderImpl()); + if (!impl->Initialize(stream)) + return NULL; + return impl.get(); +} + + +// CefZipReaderImpl + +namespace { + +voidpf ZCALLBACK zlib_open_callback OF((voidpf opaque, const char* filename, + int mode)) +{ + // The stream is already implicitly open so just return the pointer. + return opaque; +} + +uLong ZCALLBACK zlib_read_callback OF((voidpf opaque, voidpf stream, void* buf, + uLong size)) +{ + CefRefPtr reader(static_cast(opaque)); + return reader->Read(buf, 1, size); +} + +long ZCALLBACK zlib_tell_callback OF((voidpf opaque, voidpf stream)) +{ + CefRefPtr reader(static_cast(opaque)); + return reader->Tell(); +} + +long ZCALLBACK zlib_seek_callback OF((voidpf opaque, voidpf stream, + uLong offset, int origin)) +{ + CefRefPtr reader(static_cast(opaque)); + int whence; + switch (origin) { + case ZLIB_FILEFUNC_SEEK_CUR: + whence = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + whence = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + whence = SEEK_SET; + break; + default: + NOTREACHED(); + return -1; + } + return reader->Seek(offset, whence); +} + +int ZCALLBACK zlib_close_callback OF((voidpf opaque, voidpf stream)) +{ + CefRefPtr reader(static_cast(opaque)); + // Release the reference added by CefZipReaderImpl::Initialize(). + reader->Release(); + return 0; +} + +int ZCALLBACK zlib_error_callback OF((voidpf opaque, voidpf stream)) +{ + return 0; +} + +} // namespace + +CefZipReaderImpl::CefZipReaderImpl() + : supported_thread_id_(PlatformThread::CurrentId()), reader_(NULL), + has_fileopen_(false), has_fileinfo_(false), filesize_(0), filemodified_(0) +{ +} + +CefZipReaderImpl::~CefZipReaderImpl() +{ + if (reader_ != NULL) { + if (!VerifyContext()) { + // Close() is supposed to be called directly. We'll try to free the reader + // now on the wrong thread but there's no guarantee this call won't crash. + if (has_fileopen_) + unzCloseCurrentFile(reader_); + unzClose(reader_); + } else { + Close(); + } + } +} + +bool CefZipReaderImpl::Initialize(CefRefPtr stream) +{ + zlib_filefunc_def filefunc_def; + filefunc_def.zopen_file = zlib_open_callback; + filefunc_def.zread_file = zlib_read_callback; + filefunc_def.zwrite_file = NULL; + filefunc_def.ztell_file = zlib_tell_callback; + filefunc_def.zseek_file = zlib_seek_callback; + filefunc_def.zclose_file = zlib_close_callback; + filefunc_def.zerror_file = zlib_error_callback; + filefunc_def.opaque = stream.get(); + + // Add a reference that will be released by zlib_close_callback(). + stream->AddRef(); + + reader_ = unzOpen2("", &filefunc_def); + return (reader_ != NULL); +} + +bool CefZipReaderImpl::MoveToFirstFile() +{ + if (!VerifyContext()) + return false; + + if (has_fileopen_) + CloseFile(); + + has_fileinfo_ = false; + + return (unzGoToFirstFile(reader_) == UNZ_OK); +} + +bool CefZipReaderImpl::MoveToNextFile() +{ + if (!VerifyContext()) + return false; + + if (has_fileopen_) + CloseFile(); + + has_fileinfo_ = false; + + return (unzGoToNextFile(reader_) == UNZ_OK); +} + +bool CefZipReaderImpl::MoveToFile(const std::wstring& fileName, bool caseSensitive) +{ + if (!VerifyContext()) + return false; + + if (has_fileopen_) + CloseFile(); + + has_fileinfo_ = false; + + std::string fileNameStr = WideToUTF8(fileName); + return (unzLocateFile(reader_, fileNameStr.c_str(), + (caseSensitive ? 1 : 2)) == UNZ_OK); +} + +bool CefZipReaderImpl::Close() +{ + if (!VerifyContext()) + return false; + + if (has_fileopen_) + CloseFile(); + + int result = unzClose(reader_); + reader_ = NULL; + return (result == UNZ_OK); +} + +std::wstring CefZipReaderImpl::GetFileName() +{ + if (!VerifyContext() || !GetFileInfo()) + return std::wstring(); + + return filename_; +} + +long CefZipReaderImpl::GetFileSize() +{ + if (!VerifyContext() || !GetFileInfo()) + return -1; + + return filesize_; +} + +time_t CefZipReaderImpl::GetFileLastModified() +{ + if (!VerifyContext() || !GetFileInfo()) + return 0; + + return filemodified_; +} + +bool CefZipReaderImpl::OpenFile(const std::wstring& password) +{ + if (!VerifyContext()) + return false; + + if (has_fileopen_) + CloseFile(); + + bool ret; + + if (password.empty()) { + ret = (unzOpenCurrentFile(reader_) == UNZ_OK); + } else { + std::string passwordStr = WideToUTF8(password); + ret = (unzOpenCurrentFilePassword(reader_, passwordStr.c_str()) == UNZ_OK); + } + + if (ret) + has_fileopen_ = true; + return ret; +} + +bool CefZipReaderImpl::CloseFile() +{ + if (!VerifyContext() || !has_fileopen_) + return false; + + has_fileopen_ = false; + has_fileinfo_ = false; + + return (unzCloseCurrentFile(reader_) == UNZ_OK); +} + +int CefZipReaderImpl::ReadFile(void* buffer, size_t bufferSize) +{ + if (!VerifyContext() || !has_fileopen_) + return -1; + + return unzReadCurrentFile(reader_, buffer, bufferSize); +} + +long CefZipReaderImpl::Tell() +{ + if (!VerifyContext() || !has_fileopen_) + return -1; + + return unztell(reader_); +} + +bool CefZipReaderImpl::Eof() +{ + if (!VerifyContext() || !has_fileopen_) + return true; + + return (unzeof(reader_) == 1 ? true : false); +} + +bool CefZipReaderImpl::GetFileInfo() +{ + if (has_fileinfo_) + return true; + + char file_name[512] = {0}; + unz_file_info file_info; + memset(&file_info, 0, sizeof(file_info)); + + if (unzGetCurrentFileInfo(reader_, &file_info, file_name, sizeof(file_name), + NULL, 0, NULL, 0) != UNZ_OK) { + return false; + } + + has_fileinfo_ = true; + UTF8ToWide(file_name, strlen(file_name), &filename_); + filesize_ = file_info.uncompressed_size; + + struct tm time; + memset(&time, 0, sizeof(time)); + time.tm_sec = file_info.tmu_date.tm_sec; + time.tm_min = file_info.tmu_date.tm_min; + time.tm_hour = file_info.tmu_date.tm_hour; + time.tm_mday = file_info.tmu_date.tm_mday; + time.tm_mon = file_info.tmu_date.tm_mon; + time.tm_year = file_info.tmu_date.tm_year; + filemodified_ = mktime(&time); + + return true; +} + +bool CefZipReaderImpl::VerifyContext() +{ + if (PlatformThread::CurrentId() != supported_thread_id_) { + // This object should only be accessed from the thread that created it. + NOTREACHED(); + return false; + } + + return (reader_ != NULL); +} diff --git a/libcef/zip_reader_impl.h b/libcef/zip_reader_impl.h new file mode 100644 index 000000000..0ed9b723c --- /dev/null +++ b/libcef/zip_reader_impl.h @@ -0,0 +1,52 @@ +// Copyright (c) 20010 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. + +#ifndef _ZIP_READER_IMPL_H +#define _ZIP_READER_IMPL_H + +#include "../include/cef.h" +#include "base/platform_thread.h" +#include "third_party/zlib/contrib/minizip/unzip.h" +#include + +// Implementation of CefZipReader +class CefZipReaderImpl : public CefThreadSafeBase +{ +public: + CefZipReaderImpl(); + ~CefZipReaderImpl(); + + // Initialize the reader context. + bool Initialize(CefRefPtr stream); + + virtual bool MoveToFirstFile(); + virtual bool MoveToNextFile(); + virtual bool MoveToFile(const std::wstring& fileName, bool caseSensitive); + virtual bool Close(); + virtual std::wstring GetFileName(); + virtual long GetFileSize(); + virtual time_t GetFileLastModified(); + virtual bool OpenFile(const std::wstring& password); + virtual bool CloseFile(); + virtual int ReadFile(void* buffer, size_t bufferSize); + virtual long Tell(); + virtual bool Eof(); + + bool GetFileInfo(); + + // Verify that the reader exists and is being accessed from the correct + // thread. + bool VerifyContext(); + +protected: + unzFile reader_; + bool has_fileopen_; + bool has_fileinfo_; + std::wstring filename_; + long filesize_; + time_t filemodified_; + PlatformThreadId supported_thread_id_; +}; + +#endif // _ZIP_READER_IMPL_H diff --git a/libcef_dll/cpptoc/zip_reader_cpptoc.cc b/libcef_dll/cpptoc/zip_reader_cpptoc.cc new file mode 100644 index 000000000..9f8469e51 --- /dev/null +++ b/libcef_dll/cpptoc/zip_reader_cpptoc.cc @@ -0,0 +1,180 @@ +// Copyright (c) 2010 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. +// +// --------------------------------------------------------------------------- +// +// A portion of this file was generated by the CEF translator tool. When +// making changes by hand only do so within the body of existing function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// + +#include "libcef_dll/cpptoc/stream_reader_cpptoc.h" +#include "libcef_dll/cpptoc/zip_reader_cpptoc.h" + + +// GLOBAL FUNCTIONS - Body may be edited by hand. + +CEF_EXPORT cef_zip_reader_t* cef_zip_reader_create(cef_stream_reader_t* stream) +{ + CefRefPtr impl = CefZipReader::Create( + CefStreamReaderCppToC::Unwrap(stream)); + if(impl.get()) + return CefZipReaderCppToC::Wrap(impl); + return NULL; +} + + +// MEMBER FUNCTIONS - Body may be edited by hand. + +int CEF_CALLBACK zip_reader_move_to_first_file(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->MoveToFirstFile(); +} + +int CEF_CALLBACK zip_reader_move_to_next_file(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->MoveToNextFile(); +} + +int CEF_CALLBACK zip_reader_move_to_file(struct _cef_zip_reader_t* self, + const wchar_t* fileName, int caseSensitive) +{ + DCHECK(self); + if(!self) + return 0; + + std::wstring fileNameStr; + if (fileName) + fileNameStr = fileName; + + return CefZipReaderCppToC::Get(self)->MoveToFile(fileNameStr, + caseSensitive ? true : false); +} + +int CEF_CALLBACK zip_reader_close(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->Close(); +} + +cef_string_t CEF_CALLBACK zip_reader_get_file_name( + struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return NULL; + + std::wstring retStr = CefZipReaderCppToC::Get(self)->GetFileName(); + if(!retStr.empty()) + return cef_string_alloc(retStr.c_str()); + return NULL; +} + +long CEF_CALLBACK zip_reader_get_file_size(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->GetFileSize(); +} + +time_t CEF_CALLBACK zip_reader_get_file_last_modified( + struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->GetFileLastModified(); +} + +int CEF_CALLBACK zip_reader_open_file(struct _cef_zip_reader_t* self, + const wchar_t* password) +{ + DCHECK(self); + if(!self) + return 0; + + std::wstring passwordStr; + if (password) + passwordStr = password; + + return CefZipReaderCppToC::Get(self)->OpenFile(passwordStr); +} + +int CEF_CALLBACK zip_reader_close_file(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->CloseFile(); +} + +int CEF_CALLBACK zip_reader_read_file(struct _cef_zip_reader_t* self, + void* buffer, size_t bufferSize) +{ + DCHECK(self); + if(!self) + return -1; + + return CefZipReaderCppToC::Get(self)->ReadFile(buffer, bufferSize); +} + +long CEF_CALLBACK zip_reader_tell(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return -1; + + return CefZipReaderCppToC::Get(self)->Tell(); +} + +int CEF_CALLBACK zip_reader_eof(struct _cef_zip_reader_t* self) +{ + DCHECK(self); + if(!self) + return 0; + + return CefZipReaderCppToC::Get(self)->Eof(); +} + + +// CONSTRUCTOR - Do not edit by hand. + +CefZipReaderCppToC::CefZipReaderCppToC(CefZipReader* cls) + : CefCppToC(cls) +{ + struct_.struct_.move_to_first_file = zip_reader_move_to_first_file; + struct_.struct_.move_to_next_file = zip_reader_move_to_next_file; + struct_.struct_.move_to_file = zip_reader_move_to_file; + struct_.struct_.close = zip_reader_close; + struct_.struct_.get_file_name = zip_reader_get_file_name; + struct_.struct_.get_file_size = zip_reader_get_file_size; + struct_.struct_.get_file_last_modified = zip_reader_get_file_last_modified; + struct_.struct_.open_file = zip_reader_open_file; + struct_.struct_.close_file = zip_reader_close_file; + struct_.struct_.read_file = zip_reader_read_file; + struct_.struct_.tell = zip_reader_tell; + struct_.struct_.eof = zip_reader_eof; +} + +#ifdef _DEBUG +long CefCppToC::DebugObjCt = + 0; +#endif + diff --git a/libcef_dll/cpptoc/zip_reader_cpptoc.h b/libcef_dll/cpptoc/zip_reader_cpptoc.h new file mode 100644 index 000000000..292b95dda --- /dev/null +++ b/libcef_dll/cpptoc/zip_reader_cpptoc.h @@ -0,0 +1,34 @@ +// Copyright (c) 2010 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. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// +#ifndef _ZIPREADER_CPPTOC_H +#define _ZIPREADER_CPPTOC_H + +#ifndef BUILDING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed DLL-side only") +#else // BUILDING_CEF_SHARED + +#include "include/cef.h" +#include "include/cef_capi.h" +#include "libcef_dll/cpptoc/cpptoc.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed DLL-side only. +class CefZipReaderCppToC + : public CefCppToC +{ +public: + CefZipReaderCppToC(CefZipReader* cls); + virtual ~CefZipReaderCppToC() {} +}; + +#endif // BUILDING_CEF_SHARED +#endif // _ZIPREADER_CPPTOC_H + diff --git a/libcef_dll/ctocpp/zip_reader_ctocpp.cc b/libcef_dll/ctocpp/zip_reader_ctocpp.cc new file mode 100644 index 000000000..8a451cdc3 --- /dev/null +++ b/libcef_dll/ctocpp/zip_reader_ctocpp.cc @@ -0,0 +1,141 @@ +// Copyright (c) 2010 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. +// +// --------------------------------------------------------------------------- +// +// A portion of this file was generated by the CEF translator tool. When +// making changes by hand only do so within the body of existing static and +// virtual method implementations. See the translator.README.txt file in the +// tools directory for more information. +// + +#include "libcef_dll/ctocpp/stream_reader_ctocpp.h" +#include "libcef_dll/ctocpp/zip_reader_ctocpp.h" + + +// STATIC METHODS - Body may be edited by hand. + +CefRefPtr CefZipReader::Create(CefRefPtr stream) +{ + cef_zip_reader_t* impl = cef_zip_reader_create( + CefStreamReaderCToCpp::Unwrap(stream)); + if(impl) + return CefZipReaderCToCpp::Wrap(impl); + return NULL; +} + + +// VIRTUAL METHODS - Body may be edited by hand. + +bool CefZipReaderCToCpp::MoveToFirstFile() +{ + if(CEF_MEMBER_MISSING(struct_, move_to_first_file)) + return false; + + return struct_->move_to_first_file(struct_) ? true : false; +} + +bool CefZipReaderCToCpp::MoveToNextFile() +{ + if(CEF_MEMBER_MISSING(struct_, move_to_next_file)) + return false; + + return struct_->move_to_next_file(struct_) ? true : false; +} + +bool CefZipReaderCToCpp::MoveToFile(const std::wstring& fileName, + bool caseSensitive) +{ + if(CEF_MEMBER_MISSING(struct_, move_to_file)) + return false; + + return struct_->move_to_file(struct_, fileName.c_str(), caseSensitive) ? + true : false; +} + +bool CefZipReaderCToCpp::Close() +{ + if(CEF_MEMBER_MISSING(struct_, close)) + return false; + + return struct_->close(struct_) ? true : false; +} + +std::wstring CefZipReaderCToCpp::GetFileName() +{ + std::wstring str; + if(CEF_MEMBER_MISSING(struct_, get_file_name)) + return str; + + cef_string_t cef_str = struct_->get_file_name(struct_); + if(cef_str) { + str = cef_str; + cef_string_free(cef_str); + } + + return str; +} + +long CefZipReaderCToCpp::GetFileSize() +{ + if(CEF_MEMBER_MISSING(struct_, get_file_size)) + return -1; + + return struct_->get_file_size(struct_); +} + +time_t CefZipReaderCToCpp::GetFileLastModified() +{ + if(CEF_MEMBER_MISSING(struct_, get_file_last_modified)) + return 0; + + return struct_->get_file_last_modified(struct_); +} + +bool CefZipReaderCToCpp::OpenFile(const std::wstring& password) +{ + if(CEF_MEMBER_MISSING(struct_, open_file)) + return 0; + + return struct_->open_file(struct_, password.c_str()) ? true : false; +} + +bool CefZipReaderCToCpp::CloseFile() +{ + if(CEF_MEMBER_MISSING(struct_, close_file)) + return 0; + + return struct_->close_file(struct_) ? true : false; +} + +int CefZipReaderCToCpp::ReadFile(void* buffer, size_t bufferSize) +{ + if(CEF_MEMBER_MISSING(struct_, read_file)) + return -1; + + return struct_->read_file(struct_, buffer, bufferSize); +} + +long CefZipReaderCToCpp::Tell() +{ + if(CEF_MEMBER_MISSING(struct_, tell)) + return -1; + + return struct_->tell(struct_); +} + +bool CefZipReaderCToCpp::Eof() +{ + if(CEF_MEMBER_MISSING(struct_, eof)) + return false; + + return struct_->eof(struct_) ? true : false; +} + + +#ifdef _DEBUG +long CefCToCpp::DebugObjCt = + 0; +#endif + diff --git a/libcef_dll/ctocpp/zip_reader_ctocpp.h b/libcef_dll/ctocpp/zip_reader_ctocpp.h new file mode 100644 index 000000000..564a312dc --- /dev/null +++ b/libcef_dll/ctocpp/zip_reader_ctocpp.h @@ -0,0 +1,50 @@ +// Copyright (c) 2010 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. +// +// ------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// + +#ifndef _ZIPREADER_CTOCPP_H +#define _ZIPREADER_CTOCPP_H + +#ifndef USING_CEF_SHARED +#pragma message("Warning: "__FILE__" may be accessed wrapper-side only") +#else // USING_CEF_SHARED + +#include "include/cef.h" +#include "include/cef_capi.h" +#include "libcef_dll/ctocpp/ctocpp.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed wrapper-side only. +class CefZipReaderCToCpp + : public CefCToCpp +{ +public: + CefZipReaderCToCpp(cef_zip_reader_t* str) + : CefCToCpp(str) {} + virtual ~CefZipReaderCToCpp() {} + + // CefZipReader methods + virtual bool MoveToFirstFile(); + virtual bool MoveToNextFile(); + virtual bool MoveToFile(const std::wstring& fileName, bool caseSensitive); + virtual bool Close(); + virtual std::wstring GetFileName(); + virtual long GetFileSize(); + virtual time_t GetFileLastModified(); + virtual bool OpenFile(const std::wstring& password); + virtual bool CloseFile(); + virtual int ReadFile(void* buffer, size_t bufferSize); + virtual long Tell(); + virtual bool Eof(); +}; + +#endif // USING_CEF_SHARED +#endif // _ZIPREADER_CTOCPP_H + diff --git a/libcef_dll/libcef_dll.cc b/libcef_dll/libcef_dll.cc index f4a5b2bc2..1219a1163 100644 --- a/libcef_dll/libcef_dll.cc +++ b/libcef_dll/libcef_dll.cc @@ -15,6 +15,7 @@ #include "cpptoc/stream_writer_cpptoc.h" #include "cpptoc/v8value_cpptoc.h" #include "cpptoc/xml_reader_cpptoc.h" +#include "cpptoc/zip_reader_cpptoc.h" #include "ctocpp/download_handler_ctocpp.h" #include "ctocpp/handler_ctocpp.h" #include "ctocpp/read_handler_ctocpp.h" @@ -49,6 +50,7 @@ CEF_EXPORT void cef_shutdown() DCHECK(CefStreamWriterCppToC::DebugObjCt == 0); DCHECK(CefV8ValueCppToC::DebugObjCt == 0); DCHECK(CefXmlReaderCppToC::DebugObjCt == 0); + DCHECK(CefZipReaderCppToC::DebugObjCt == 0); DCHECK(CefDownloadHandlerCToCpp::DebugObjCt == 0); DCHECK(CefHandlerCToCpp::DebugObjCt == 0); DCHECK(CefReadHandlerCToCpp::DebugObjCt == 0); diff --git a/libcef_dll/wrapper/cef_byte_read_handler.cc b/libcef_dll/wrapper/cef_byte_read_handler.cc new file mode 100644 index 000000000..687dcbc6f --- /dev/null +++ b/libcef_dll/wrapper/cef_byte_read_handler.cc @@ -0,0 +1,67 @@ +// Copyright (c) 2010 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 "include/cef_wrapper.h" +#include "base/logging.h" + +CefByteReadHandler::CefByteReadHandler(const unsigned char* bytes, size_t size, + CefRefPtr source) + : bytes_(bytes), size_(size), offset_(0), source_(source) +{ +} + +size_t CefByteReadHandler::Read(void* ptr, size_t size, size_t n) +{ + Lock(); + size_t s = (size_ - offset_) / size; + size_t ret = min(n, s); + memcpy(ptr, bytes_ + offset_, ret * size); + offset_ += ret * size; + Unlock(); + return ret; +} + +int CefByteReadHandler::Seek(long offset, int whence) +{ + int rv = -1L; + Lock(); + switch(whence) { + case SEEK_CUR: + if(offset_ + offset > size_) + break; + offset_ += offset; + rv = offset_; + break; + case SEEK_END: + if(offset > static_cast(size_)) + break; + offset_ = size_ - offset; + rv = offset_; + case SEEK_SET: + if(offset > static_cast(size_)) + break; + offset_ = offset; + rv = offset_; + break; + } + Unlock(); + + return rv; +} + +long CefByteReadHandler::Tell() +{ + Lock(); + long rv = offset_; + Unlock(); + return rv; +} + +int CefByteReadHandler::Eof() +{ + Lock(); + int rv = (offset_ >= size_); + Unlock(); + return rv; +} diff --git a/libcef_dll/wrapper/cef_zip_archive.cc b/libcef_dll/wrapper/cef_zip_archive.cc new file mode 100644 index 000000000..606cebebe --- /dev/null +++ b/libcef_dll/wrapper/cef_zip_archive.cc @@ -0,0 +1,163 @@ +// Copyright (c) 2010 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 "include/cef_wrapper.h" +#include "base/logging.h" +#include + +namespace { + +class CefZipFile : public CefThreadSafeBase +{ +public: + CefZipFile(size_t size) : data_(size) {} + ~CefZipFile() {} + + // Returns the read-only data contained in the file. + virtual const unsigned char* GetData() { return &data_[0]; } + + // Returns the size of the data in the file. + virtual size_t GetDataSize() { return data_.size(); } + + // Returns a CefStreamReader object for streaming the contents of the file. + virtual CefRefPtr GetStreamReader() { + CefRefPtr handler( + new CefByteReadHandler(GetData(), GetDataSize(), this)); + return CefStreamReader::CreateForHandler(handler); + } + + std::vector* GetDataVector() { return &data_; } + +private: + std::vector data_; +}; + +} // namespace + +// CefZipArchive implementation + +CefZipArchive::CefZipArchive() +{ +} + +CefZipArchive::~CefZipArchive() +{ +} + +size_t CefZipArchive::Load(CefRefPtr stream, + bool overwriteExisting) +{ + AutoLock lock_scope(this); + + CefRefPtr reader(CefZipReader::Create(stream)); + if (!reader.get()) + return 0; + + if (!reader->MoveToFirstFile()) + return 0; + + std::wstring name; + CefRefPtr contents; + FileMap::iterator it; + std::vector* data; + size_t count = 0, size, offset; + + do { + size = static_cast(reader->GetFileSize()); + if (size == 0) { + // Skip directories and empty files. + continue; + } + + if (!reader->OpenFile(L"")) + break; + + name = reader->GetFileName(); + std::transform(name.begin(), name.end(), name.begin(), towlower); + + it = contents_.find(name); + if (it != contents_.end()) { + if (overwriteExisting) + contents_.erase(it); + else // Skip files that already exist. + continue; + } + + contents = new CefZipFile(size); + data = contents->GetDataVector(); + offset = 0; + + // Read the file contents. + do { + offset += reader->ReadFile(&(*data)[offset], size - offset); + } while (offset < size && !reader->Eof()); + + DCHECK(offset == size); + + reader->CloseFile(); + count++; + + // Add the file to the map. + contents_.insert( + std::make_pair >(name, contents.get())); + } while (reader->MoveToNextFile()); + + return count; +} + +void CefZipArchive::Clear() +{ + AutoLock lock_scope(this); + contents_.empty(); +} + +size_t CefZipArchive::GetFileCount() +{ + AutoLock lock_scope(this); + return contents_.size(); +} + +bool CefZipArchive::HasFile(const std::wstring& fileName) +{ + std::wstring str = fileName; + std::transform(str.begin(), str.end(), str.begin(), towlower); + + AutoLock lock_scope(this); + FileMap::const_iterator it = contents_.find(str); + return (it != contents_.end()); +} + +CefRefPtr CefZipArchive::GetFile( + const std::wstring& fileName) +{ + std::wstring str = fileName; + std::transform(str.begin(), str.end(), str.begin(), towlower); + + AutoLock lock_scope(this); + FileMap::const_iterator it = contents_.find(str); + if (it != contents_.end()) + return it->second; + return NULL; +} + +bool CefZipArchive::RemoveFile(const std::wstring& fileName) +{ + std::wstring str = fileName; + std::transform(str.begin(), str.end(), str.begin(), towlower); + + AutoLock lock_scope(this); + FileMap::iterator it = contents_.find(str); + if (it != contents_.end()) { + contents_.erase(it); + return true; + } + return false; +} + +size_t CefZipArchive::GetFiles(FileMap& map) +{ + AutoLock lock_scope(this); + map = contents_; + return contents_.size(); +} diff --git a/libcef_dll/wrapper/libcef_dll_wrapper.cc b/libcef_dll/wrapper/libcef_dll_wrapper.cc index b11e786e4..6262f89aa 100644 --- a/libcef_dll/wrapper/libcef_dll_wrapper.cc +++ b/libcef_dll/wrapper/libcef_dll_wrapper.cc @@ -22,6 +22,7 @@ #include "libcef_dll/ctocpp/stream_writer_ctocpp.h" #include "libcef_dll/ctocpp/v8value_ctocpp.h" #include "libcef_dll/ctocpp/xml_reader_ctocpp.h" +#include "libcef_dll/ctocpp/zip_reader_ctocpp.h" bool CefInitialize(bool multi_threaded_message_loop, @@ -52,6 +53,7 @@ void CefShutdown() DCHECK(CefStreamWriterCToCpp::DebugObjCt == 0); DCHECK(CefV8ValueCToCpp::DebugObjCt == 0); DCHECK(CefXmlReaderCToCpp::DebugObjCt == 0); + DCHECK(CefZipReaderCToCpp::DebugObjCt == 0); #endif // _DEBUG } diff --git a/tests/cefclient/cefclient.cpp b/tests/cefclient/cefclient.cpp index 7942c4ff9..c968dcc82 100644 --- a/tests/cefclient/cefclient.cpp +++ b/tests/cefclient/cefclient.cpp @@ -3,6 +3,7 @@ // can be found in the LICENSE file. #include "include/cef.h" +#include "include/cef_wrapper.h" #include "cefclient.h" #include "binding_test.h" #include "download_handler.h" @@ -408,21 +409,21 @@ public: // Show the uiapp contents if(LoadBinaryResource(IDS_UIPLUGIN, dwSize, pBytes)) { resourceStream = CefStreamReader::CreateForHandler( - new ClientReadHandler(pBytes, dwSize)); + new CefByteReadHandler(pBytes, dwSize, NULL)); mimeType = L"text/html"; } } else if(wcsstr(url.c_str(), L"/ps_logo2.png") != NULL) { // Any time we find "ps_logo2.png" in the URL substitute in our own image if(LoadBinaryResource(IDS_LOGO, dwSize, pBytes)) { resourceStream = CefStreamReader::CreateForHandler( - new ClientReadHandler(pBytes, dwSize)); + new CefByteReadHandler(pBytes, dwSize, NULL)); mimeType = L"image/png"; } } else if(wcsstr(url.c_str(), L"/logoball.png") != NULL) { // Load the "logoball.png" image resource. if(LoadBinaryResource(IDS_LOGOBALL, dwSize, pBytes)) { resourceStream = CefStreamReader::CreateForHandler( - new ClientReadHandler(pBytes, dwSize)); + new CefByteReadHandler(pBytes, dwSize, NULL)); mimeType = L"image/png"; } } diff --git a/tests/cefclient/resource_util.cpp b/tests/cefclient/resource_util.cpp index e18a8c28f..3a5b192cc 100644 --- a/tests/cefclient/resource_util.cpp +++ b/tests/cefclient/resource_util.cpp @@ -4,7 +4,6 @@ #include "resource_util.h" - bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes) { extern HINSTANCE hInst; @@ -24,67 +23,3 @@ bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes) return false; } - - -// ClientReadHandler implementation - -ClientReadHandler::ClientReadHandler(LPBYTE pBytes, DWORD dwSize) - : bytes_(pBytes), size_(dwSize), offset_(0) {} - -size_t ClientReadHandler::Read(void* ptr, size_t size, size_t n) -{ - Lock(); - size_t s = (size_ - offset_) / size; - size_t ret = min(n, s); - memcpy(ptr, bytes_ + offset_, ret * size); - offset_ += ret * size; - Unlock(); - return ret; -} - -int ClientReadHandler::Seek(long offset, int whence) -{ - int rv = -1L; - Lock(); - switch(whence) { - case SEEK_CUR: - if(offset_ + offset > size_) { - break; - } - offset_ += offset; - rv = offset_; - break; - case SEEK_END: - if(offset > (int)size_) { - break; - } - offset_ = size_ - offset; - rv = offset_; - case SEEK_SET: - if(offset > (int)size_) { - break; - } - offset_ = offset; - rv = offset_; - break; - } - Unlock(); - - return rv; -} - -long ClientReadHandler::Tell() -{ - Lock(); - long rv = offset_; - Unlock(); - return rv; -} - -int ClientReadHandler::Eof() -{ - Lock(); - int rv = (offset_ >= size_); - Unlock(); - return rv; -} diff --git a/tests/cefclient/resource_util.h b/tests/cefclient/resource_util.h index 278d1aa64..32db5a127 100644 --- a/tests/cefclient/resource_util.h +++ b/tests/cefclient/resource_util.h @@ -6,34 +6,5 @@ #include "include/cef.h" -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif - // Load a resource of type BINARY bool LoadBinaryResource(int binaryId, DWORD &dwSize, LPBYTE &pBytes); - - -// Implementation of the stream read handler for reading in-memory data. -class ClientReadHandler : public CefThreadSafeBase -{ -public: - ClientReadHandler(LPBYTE pBytes, DWORD dwSize); - - // Read raw binary data. - virtual size_t Read(void* ptr, size_t size, size_t n); - - // Seek to the specified offset position. |whence| may be any one of - // SEEK_CUR, SEEK_END or SEEK_SET. - virtual int Seek(long offset, int whence); - - // Return the current offset position. - virtual long Tell(); - - // Return non-zero if at end of file. - virtual int Eof(); - -private: - LPBYTE bytes_; - DWORD size_, offset_; -}; diff --git a/tests/cefclient/scheme_test.cpp b/tests/cefclient/scheme_test.cpp index 1bbd02fc6..5920257f9 100644 --- a/tests/cefclient/scheme_test.cpp +++ b/tests/cefclient/scheme_test.cpp @@ -2,6 +2,7 @@ // reserved. Use of this source code is governed by a BSD-style license that // can be found in the LICENSE file. +#include "include/cef_wrapper.h" #include "scheme_test.h" #include "string_util.h" #include "resource_util.h" diff --git a/tests/unittests/zip_reader_unittest.cc b/tests/unittests/zip_reader_unittest.cc new file mode 100644 index 000000000..995650d19 --- /dev/null +++ b/tests/unittests/zip_reader_unittest.cc @@ -0,0 +1,254 @@ +// Copyright (c) 2010 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 "include/cef.h" +#include "include/cef_wrapper.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + + unsigned char g_test_zip[] = { + 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x7f, + 0x57, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, + 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x50, 0x4b, 0x03, 0x04, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x7f, 0x57, 0x3d, 0xf8, 0x47, 0x0c, + 0xc6, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, + 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x2e, 0x74, 0x78, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, 0x20, + 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x2e, 0x50, 0x4b, 0x03, 0x04, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x7f, 0x57, 0x3d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, + 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x2f, 0x50, + 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x7f, 0x57, + 0x3d, 0x43, 0xe3, 0x11, 0x5f, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, + 0x00, 0x21, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x20, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x61, 0x2e, 0x74, + 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, + 0x66, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x41, 0x2e, 0x50, 0x4b, + 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x7f, 0x57, 0x3d, + 0x80, 0xb0, 0x3c, 0x74, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, + 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x62, 0x2e, 0x74, 0x78, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x42, 0x2e, 0x50, 0x4b, 0x03, + 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x7f, 0x57, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, + 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x61, 0x2f, 0x50, + 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7f, 0x57, + 0x3d, 0x15, 0xed, 0x04, 0x2c, 0x15, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x20, 0x31, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x61, + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x61, 0x31, 0x2e, 0x74, 0x78, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x66, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x41, 0x31, 0x2e, 0x50, 0x4b, + 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x7f, 0x57, 0x3d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, + 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, + 0x32, 0x2f, 0x50, 0x4b, 0x03, 0x04, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x80, 0x57, 0x3d, 0x1a, 0x5d, 0x57, 0x5d, 0x14, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, + 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x20, 0x32, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x32, + 0x61, 0x2e, 0x74, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x73, 0x20, 0x6f, 0x66, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x32, 0x41, + 0x2e, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x67, 0x7f, 0x57, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, + 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x70, 0x7f, 0x57, 0x3d, 0xf8, 0x47, 0x0c, 0xc6, 0x13, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x31, 0x2e, 0x74, 0x78, 0x74, 0x50, 0x4b, 0x01, + 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x7f, 0x57, + 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, + 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, + 0x65, 0x72, 0x20, 0x31, 0x2f, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x7f, 0x57, 0x3d, 0x43, 0xe3, 0x11, + 0x5f, 0x14, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xa7, + 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, + 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, + 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x31, 0x61, 0x2e, 0x74, 0x78, 0x74, + 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x78, 0x7f, 0x57, 0x3d, 0x80, 0xb0, 0x3c, 0x74, 0x14, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x74, 0x65, + 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, + 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x2f, 0x66, 0x69, 0x6c, 0x65, + 0x20, 0x31, 0x62, 0x2e, 0x74, 0x78, 0x74, 0x50, 0x4b, 0x01, 0x02, 0x14, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x7f, 0x57, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x4d, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x20, 0x31, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x61, + 0x2f, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0x7f, 0x57, 0x3d, 0x15, 0xed, 0x04, 0x2c, 0x15, 0x00, 0x00, + 0x00, 0x15, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00, 0x74, + 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, + 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x31, 0x2f, 0x66, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x20, 0x31, 0x61, 0x2f, 0x66, 0x69, 0x6c, 0x65, 0x20, + 0x31, 0x61, 0x31, 0x2e, 0x74, 0x78, 0x74, 0x50, 0x4b, 0x01, 0x02, 0x14, + 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x7f, 0x57, 0x3d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + 0x00, 0xea, 0x01, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, + 0x63, 0x68, 0x69, 0x76, 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x20, 0x32, 0x2f, 0x50, 0x4b, 0x01, 0x02, 0x14, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x80, 0x57, 0x3d, 0x1a, 0x5d, 0x57, 0x5d, 0x14, + 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x1e, 0x02, 0x00, + 0x00, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, + 0x65, 0x2f, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x20, 0x32, 0x2f, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x32, 0x61, 0x2e, 0x74, 0x78, 0x74, 0x50, 0x4b, + 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x09, 0x00, 0x9d, 0x02, + 0x00, 0x00, 0x71, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + +} // namespace + +// Test Zip reading. +TEST(ZipReaderTest, Read) +{ + // Create the stream reader. + CefRefPtr stream( + CefStreamReader::CreateForData(g_test_zip, sizeof(g_test_zip) - 1)); + ASSERT_TRUE(stream.get() != NULL); + + // Create the Zip reader. + CefRefPtr reader(CefZipReader::Create(stream)); + ASSERT_TRUE(reader.get() != NULL); + + char buff[25]; + + // Walk through the archive contents. + ASSERT_TRUE(reader->MoveToFirstFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/"); + ASSERT_EQ(reader->GetFileSize(), 0); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/file 1.txt"); + ASSERT_EQ(reader->GetFileSize(), 19); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 19); + ASSERT_TRUE(!strncmp(buff, "Contents of file 1.", 19)); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 1/"); + ASSERT_EQ(reader->GetFileSize(), 0); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 1/file 1a.txt"); + ASSERT_EQ(reader->GetFileSize(), 20); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 20); + ASSERT_TRUE(reader->CloseFile()); + ASSERT_TRUE(!strncmp(buff, "Contents of file 1A.", 20)); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 1/file 1b.txt"); + ASSERT_EQ(reader->GetFileSize(), 20); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 20); + ASSERT_TRUE(reader->CloseFile()); + ASSERT_TRUE(!strncmp(buff, "Contents of file 1B.", 20)); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 1/folder 1a/"); + ASSERT_EQ(reader->GetFileSize(), 0); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), + L"test_archive/folder 1/folder 1a/file 1a1.txt"); + ASSERT_EQ(reader->GetFileSize(), 21); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 21); + ASSERT_TRUE(reader->CloseFile()); + ASSERT_TRUE(!strncmp(buff, "Contents of file 1A1.", 21)); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 2/"); + ASSERT_EQ(reader->GetFileSize(), 0); + + ASSERT_TRUE(reader->MoveToNextFile()); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 2/file 2a.txt"); + ASSERT_EQ(reader->GetFileSize(), 20); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 20); + ASSERT_TRUE(reader->CloseFile()); + ASSERT_TRUE(!strncmp(buff, "Contents of file 2A.", 20)); + + ASSERT_FALSE(reader->MoveToNextFile()); + + // Try seeking a particular file + ASSERT_TRUE(reader->MoveToFile(L"TEST_ARCHIVE/FOLDER 1/FILE 1B.TXT", false)); + ASSERT_EQ(reader->GetFileName(), L"test_archive/folder 1/file 1b.txt"); + ASSERT_EQ(reader->GetFileSize(), 20); + ASSERT_TRUE(reader->OpenFile(L"")); + ASSERT_EQ(reader->ReadFile(buff, sizeof(buff)), 20); + ASSERT_TRUE(reader->CloseFile()); + ASSERT_TRUE(!strncmp(buff, "Contents of file 1B.", 20)); + + ASSERT_TRUE(reader->MoveToFile(L"test_archive/folder 1/file 1b.txt", true)); + ASSERT_FALSE(reader->MoveToFile(L"test_archive/folder 1/FILE 1B.txt", true)); + + ASSERT_TRUE(reader->Close()); +} + +// Test CefZipArchive object. +TEST(ZipReaderTest, ReadArchive) +{ + // Create the stream reader. + CefRefPtr stream( + CefStreamReader::CreateForData(g_test_zip, sizeof(g_test_zip) - 1)); + ASSERT_TRUE(stream.get() != NULL); + + // Create the Zip archive object. + CefRefPtr archive(new CefZipArchive()); + + ASSERT_EQ(archive->Load(stream, false), 5); + + ASSERT_TRUE(archive->HasFile(L"test_archive/file 1.txt")); + ASSERT_TRUE(archive->HasFile(L"test_archive/folder 1/file 1a.txt")); + ASSERT_TRUE(archive->HasFile(L"test_archive/FOLDER 1/file 1b.txt")); + ASSERT_TRUE(archive->HasFile(L"test_archive/folder 1/folder 1a/file 1a1.txt")); + ASSERT_TRUE(archive->HasFile(L"test_archive/folder 2/file 2a.txt")); + + // Test content retrieval. + CefRefPtr file; + file = archive->GetFile(L"test_archive/folder 2/file 2a.txt"); + ASSERT_TRUE(file.get()); + + ASSERT_EQ(file->GetDataSize(), 20); + ASSERT_TRUE(!strncmp(reinterpret_cast(file->GetData()), + "Contents of file 2A.", 20)); + + // Test stream reading. + CefRefPtr reader(file->GetStreamReader()); + ASSERT_TRUE(reader.get()); + + char buff[8]; + ASSERT_EQ(reader->Read(buff, 1, 8), 8); + ASSERT_TRUE(!strncmp(buff, "Contents", 8)); + ASSERT_EQ(reader->Read(buff, 1, 8), 8); + ASSERT_TRUE(!strncmp(buff, " of file", 8)); + ASSERT_EQ(reader->Read(buff, 1, 8), 4); + ASSERT_TRUE(!strncmp(buff, " 2A.", 4)); + ASSERT_TRUE(reader->Eof()); +} diff --git a/tools/cef_parser.py b/tools/cef_parser.py index 4118d5de7..2a292bb05 100644 --- a/tools/cef_parser.py +++ b/tools/cef_parser.py @@ -1073,6 +1073,7 @@ class obj_analysis: 'long' : 'long', 'unsigned long' : 'unsigned long', 'size_t' : 'size_t', + 'time_t' : 'time_t', 'bool' : 'int', 'CefWindowHandle' : 'cef_window_handle_t', 'CefRect' : 'cef_rect_t',