// Copyright © 2015 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. #include "Stdafx.h" #include "Primitives.h" #include "include/cef_app.h" using namespace std; namespace CefSharp { namespace Internals { namespace Serialization { enum class PrimitiveType : unsigned char { INT64, CEFTIME, JSCALLBACK, ARRAYBUFFER }; template bool IsType(PrimitiveType type, const CefRefPtr& list, TIndex index) { auto result = list->GetType(index) == VTYPE_BINARY; if (result) { underlying_type::type typeRead; auto binaryValue = list->GetBinary(index); binaryValue->GetData(&typeRead, sizeof(underlying_type::type), 0); result = typeRead == static_cast::type>(type); } return result; } template void SetInt64(const CefRefPtr& list, TIndex index, const int64_t&value) { unsigned char mem[1 + sizeof(int64_t)]; mem[0] = static_cast(PrimitiveType::INT64); memcpy(reinterpret_cast(mem + 1), &value, sizeof(int64_t)); auto binaryValue = CefBinaryValue::Create(mem, sizeof(mem)); list->SetBinary(index, binaryValue); } template int64_t GetInt64(const CefRefPtr& list, TIndex index) { int64_t result; auto binaryValue = list->GetBinary(index); binaryValue->GetData(&result, sizeof(int64_t), 1); return result; } template bool IsInt64(const CefRefPtr& list, TIndex index) { return IsType(PrimitiveType::INT64, list, index); } template void SetCefTime(const CefRefPtr& list, TIndex index, const int64_t&value) { unsigned char mem[1 + sizeof(int64_t)]; mem[0] = static_cast(PrimitiveType::CEFTIME); memcpy(reinterpret_cast(mem + 1), &value, sizeof(int64_t)); auto binaryValue = CefBinaryValue::Create(mem, sizeof(mem)); list->SetBinary(index, binaryValue); } template CefBaseTime GetCefTime(const CefRefPtr& list, TIndex index) { CefBaseTime baseTime; auto binaryValue = list->GetBinary(index); binaryValue->GetData(&baseTime.val, sizeof(int64_t), 1); return baseTime; } template bool IsCefTime(const CefRefPtr& list, TIndex index) { return IsType(PrimitiveType::CEFTIME, list, index); } template void SetArrayBuffer(const CefRefPtr& list, TIndex index, const size_t& size, const void* value) { const auto src = static_cast(value); auto dest = new uint8_t[size + 1]; dest[0] = static_cast(PrimitiveType::ARRAYBUFFER); memcpy(&dest[1], src, size); list->SetBinary(index, CefBinaryValue::Create(dest, size + 1)); } template cli::array^ GetArrayBuffer(const CefRefPtr& list, TIndex index) { auto binaryValue = list->GetBinary(index); auto size = binaryValue->GetSize() - 1; auto bufferByte = gcnew cli::array(static_cast(size)); pin_ptr src = &bufferByte[0]; // pin pointer to first element in arr binaryValue->GetData(static_cast(src), size, 1); return bufferByte; } template bool IsArrayBuffer(const CefRefPtr& list, TIndex index) { return IsType(PrimitiveType::ARRAYBUFFER, list, index); } template void SetJsCallback(const CefRefPtr& list, TIndex index, JavascriptCallback^ value) { auto bytes = value->ToByteArray(static_cast(PrimitiveType::JSCALLBACK)); pin_ptr bytesPtr = &bytes[0]; auto binaryValue = CefBinaryValue::Create(bytesPtr, bytes->Length); list->SetBinary(index, binaryValue); } template JavascriptCallback^ GetJsCallback(const CefRefPtr& list, TIndex index) { auto binaryValue = list->GetBinary(index); auto bufferSize = (int)binaryValue->GetSize(); auto buffer = gcnew cli::array(bufferSize); pin_ptr bufferPtr = &buffer[0]; // pin pointer to first element in arr //TODO: We can potentially further optimise this by geting binaryValue->GetRawData // and then reading directly from that binaryValue->GetData(static_cast(bufferPtr), bufferSize, 0); return JavascriptCallback::FromBytes(buffer); } template bool IsJsCallback(const CefRefPtr& list, TIndex index) { return IsType(PrimitiveType::JSCALLBACK, list, index); } } } }