// Copyright © 2018 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. #pragma once #include "Stdafx.h" using namespace System; using namespace System::IO; namespace CefSharp { namespace Internals { private class CefWriteHandlerWrapper : public CefWriteHandler { gcroot _stream; bool _isMemoryStream; public: CefWriteHandlerWrapper(Stream^ stream) : _stream(stream) { //Reset stream position stream->Position = 0; _isMemoryStream = stream->GetType() == MemoryStream::typeid; } ~CefWriteHandlerWrapper() { //Remove the reference to the stream, must be kept open _stream = nullptr; } virtual size_t Write(const void* ptr, size_t size, size_t n) override { try { array^ buffer = gcnew array(n * size); pin_ptr src = &buffer[0]; memcpy(static_cast(src), ptr, n); _stream->Write(buffer, 0, n); return n / size; } catch (Exception^) { return -1; } } virtual int Seek(int64_t offset, int whence) override { System::IO::SeekOrigin seekOrigin; if (!_stream->CanSeek) { return -1; } switch (whence) { case SEEK_CUR: { seekOrigin = System::IO::SeekOrigin::Current; break; } case SEEK_END: { seekOrigin = System::IO::SeekOrigin::End; break; } case SEEK_SET: { seekOrigin = System::IO::SeekOrigin::Begin; break; } default: { return -1; } } try { _stream->Seek(offset, seekOrigin); } catch (Exception^) { return -1; } return 0; } virtual int64_t Tell() override { return static_cast(_stream->Position); } virtual int Flush() override { _stream->Flush(); return 0; } virtual bool MayBlock() override { return !_isMemoryStream; } IMPLEMENT_REFCOUNTINGM(CefWriteHandlerWrapper); }; } }