blob: 94bcf0eda35648552edbc8a6de54c1433bc1d8dc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "geode_defs.hpp"
#include "begin_native.hpp"
#include <geode/CacheableBuiltins.hpp>
#include "end_native.hpp"
#include "CacheableKey.hpp"
#include "Serializable.hpp"
#include "ExceptionTypes.hpp"
#include "DataOutput.hpp"
#include "DataInput.hpp"
using namespace System;
namespace Apache
{
namespace Geode
{
namespace Client
{
namespace native = apache::geode::client;
/// <summary>
/// An immutable template wrapper for C++ <c>CacheableKey</c>s that can
/// serve as a distributable key object for caching.
/// </summary>
template <typename TNative, typename TManaged, int8_t TYPEID>
ref class CacheableBuiltinKey
: public IDataSerializablePrimitive, public CacheableKey
{
public:
/// <summary>
/// Allocates a new instance
/// </summary>
CacheableBuiltinKey()
{
auto nativeptr = TNative::create();
m_nativeptr = gcnew native_shared_ptr<native::Serializable>(nativeptr);
}
/// <summary>
/// Allocates a new instance with the given value.
/// </summary>
/// <param name="value">the value of the new instance</param>
CacheableBuiltinKey(TManaged value)
{
auto nativeptr = TNative::create(value);
m_nativeptr = gcnew native_shared_ptr<native::Serializable>(nativeptr);
}
property int8_t DsCode
{
virtual int8_t get()
{
return TYPEID;
}
}
/// <summary>
/// Return a string representation of the object.
/// This returns the string for the <c>Value</c> property.
/// </summary>
String^ ToString() override
{
try
{
return GetNative()->value().ToString();
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
/// <summary>
/// Return true if this key matches other object.
/// It invokes the '==' operator of the underlying
/// native object.
/// </summary>
virtual bool Equals(ICacheableKey^ other) override
{
if (auto o = dynamic_cast<CacheableBuiltinKey^>(other)) {
try
{
return GetNative()->operator==(
*dynamic_cast<TNative*>(o->m_nativeptr->get()));
}
finally
{
GC::KeepAlive(m_nativeptr);
GC::KeepAlive(o->m_nativeptr);
}
}
return false;
}
/// <summary>
/// Return true if this key matches other object.
/// It invokes the '==' operator of the underlying
/// native object.
/// </summary>
virtual bool Equals(Object^ obj) override
{
return Equals(dynamic_cast<CacheableBuiltinKey^>(obj));
}
/// <summary>
/// Comparison operator against another value.
/// </summary>
bool operator == (TManaged other)
{
try
{
return (GetNative()->value() == other);
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
/// <summary>
/// Gets the value.
/// </summary>
property TManaged Value
{
inline TManaged get()
{
try
{
return GetNative()->value();
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
}
virtual void ToData(DataOutput^ dataOutput)
{
try
{
return GetNative()->toData(*dataOutput->GetNative());
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
virtual void FromData(DataInput^ dataInput)
{
try
{
return GetNative()->fromData(*dataInput->GetNative());
}
finally
{
GC::KeepAlive(m_nativeptr);
}
}
protected:
/// <summary>
/// Protected constructor to wrap a native object pointer
/// </summary>
/// <param name="nativeptr">The native object pointer</param>
inline CacheableBuiltinKey(std::shared_ptr<native::Serializable> nativeptr)
: CacheableKey(nativeptr) { }
private:
inline TNative* GetNative()
{
return dynamic_cast<TNative*>(m_nativeptr->get());
}
};
/// <summary>
/// An immutable template array wrapper that can serve as a
/// distributable object for caching.
/// </summary>
template <typename TNative, typename TNativePtr, typename TManaged,
int8_t TYPEID>
ref class CacheableBuiltinArray
: public IDataSerializablePrimitive
{
public:
/// <summary>
/// Returns the classId of the instance being serialized.
/// This is used by deserialization to determine what instance
/// type to create and deserialize into.
/// </summary>
/// <returns>the classId</returns>
property int8_t DsCode
{
virtual int8_t get()
{
return TYPEID;
}
}
virtual void ToData(DataOutput^ output)
{
output->WriteObject(m_value);
}
virtual void FromData(DataInput^ input)
{
input->ReadObject(m_value);
}
property System::UInt64 ObjectSize
{
virtual System::UInt64 get()
{
return m_value->Length * sizeof(TManaged);
}
}
/// <summary>
/// Returns a copy of the underlying array.
/// </summary>
property array<TManaged>^ Value
{
inline array<TManaged>^ get()
{
return m_value;
}
}
/// <summary>
/// Returns the size of this array.
/// </summary>
property System::Int32 Length
{
inline System::Int32 get()
{
return m_value->Length;
}
}
virtual String^ ToString() override
{
return m_value->ToString();
}
/// <summary>
/// Returns the value at the given index.
/// </summary>
property TManaged GFINDEXER(System::Int32)
{
inline TManaged get(System::Int32 index)
{
return m_value[index];
}
}
protected:
array<TManaged>^ m_value;
/// <summary>
/// Protected constructor
/// </summary>
inline CacheableBuiltinArray()
{
//TODO:
//native::Serializable* sp = TNative::createDeserializable();
//SetSP(sp);
}
/// <summary>
/// Protected constructor to wrap a native object pointer
/// </summary>
/// <param name="nativeptr">The native object pointer</param>
inline CacheableBuiltinArray(std::shared_ptr<native::Serializable> nptr)
{
auto nativeptr = std::dynamic_pointer_cast<TNative>(nptr);
System::Int32 len = nativeptr->length();
if (len > 0)
{
array<TManaged>^ buffer = gcnew array<TManaged>(len);
pin_ptr<TManaged> pin_buffer = &buffer[0];
memcpy((void*)pin_buffer, nativeptr->value().data(),
len * sizeof(TManaged));
m_value = buffer;
}
}
/// <summary>
/// Allocates a new instance copying from the given array.
/// </summary>
/// <remarks>
/// This method performs no argument checking which is the
/// responsibility of the caller.
/// </remarks>
/// <param name="buffer">the array to copy from</param>
CacheableBuiltinArray(array<TManaged>^ buffer)
{
m_value = buffer;
//setting local value as well
//m_value = gcnew array<TManaged>(buffer->Length);
//System::Array::Copy(buffer, 0, m_value,0, buffer->Length);
}
/// <summary>
/// Allocates a new instance copying given length from the
/// start of given array.
/// </summary>
/// <remarks>
/// This method performs no argument checking which is the
/// responsibility of the caller.
/// </remarks>
/// <param name="buffer">the array to copy from</param>
/// <param name="length">length of array from start to copy</param>
CacheableBuiltinArray(array<TManaged>^ buffer, System::Int32 length)
{
//TODO:
if (length > buffer->Length) {
length = buffer->Length;
}
//setting local value as well
m_value = gcnew array<TManaged>(length);
System::Array::Copy(buffer, 0, m_value, 0, length);
}
};
//n = native type
//m = CacheableInt(managed cacheable)
//mt = managed type(bool, int)
#define _GFCLI_CACHEABLE_KEY_DEF_NEW(n, m, mt) \
ref class m : public CacheableBuiltinKey<n, mt, \
static_cast<int8_t>(DSCode::m)> \
{ \
public: \
/** <summary>
* Allocates a new instance with the given value.
* </summary>
* <param name="value">the value of the new instance</param>
*/ \
inline m() \
: CacheableBuiltinKey() { } \
/** <summary>
* Allocates a new instance with the given value.
* </summary>
* <param name="value">the value of the new instance</param>
*/ \
inline m(mt value) \
: CacheableBuiltinKey(value) { } \
/** <summary>
* Static function to create a new instance given value.
* </summary>
* <param name="value">the value of the new instance</param>
*/ \
inline static m^ Create(mt value) \
{ \
return gcnew m(value); \
} \
/** <summary>
* Explicit conversion operator to contained value type.
* </summary>
*/ \
inline static explicit operator mt (m^ value) \
{ \
return value->Value; \
} \
\
/** <summary>
* Factory function to register this class.
* </summary>
*/ \
static ISerializable^ CreateDeserializable() \
{ \
return gcnew m(); \
} \
\
internal: \
static ISerializable^ Create(std::shared_ptr<native::Serializable> obj) \
{ \
return (obj != nullptr ? gcnew m(obj) : nullptr); \
} \
\
private: \
inline m(std::shared_ptr<native::Serializable> nativeptr) \
: CacheableBuiltinKey(nativeptr) { } \
};
// Built-in CacheableKeys
/// <summary>
/// An immutable wrapper for booleans that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableBoolean,
CacheableBoolean, bool);
/// <summary>
/// An immutable wrapper for bytes that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableByte,
CacheableByte, Byte);
/// <summary>
/// An immutable wrapper for 16-bit characters that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableCharacter,
CacheableCharacter, Char);
/// <summary>
/// An immutable wrapper for doubles that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableDouble,
CacheableDouble, Double);
/// <summary>
/// An immutable wrapper for floats that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableFloat,
CacheableFloat, Single);
/// <summary>
/// An immutable wrapper for 16-bit integers that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableInt16,
CacheableInt16, System::Int16);
/// <summary>
/// An immutable wrapper for 32-bit integers that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableInt32,
CacheableInt32, System::Int32);
/// <summary>
/// An immutable wrapper for 64-bit integers that can serve
/// as a distributable key object for caching.
/// </summary>
_GFCLI_CACHEABLE_KEY_DEF_NEW(native::CacheableInt64,
CacheableInt64, System::Int64);
// Built-in Cacheable array types
template <typename NativeArray, typename ManagedType, int8_t DsCode>
ref class CacheableArray : public CacheableBuiltinArray<
NativeArray, NativeArray, ManagedType, DsCode> {
public:
/** <summary>
* Static function to create a new instance copying
* from the given array.
* </summary>
* <remarks>
* Providing a null or zero size array will return a null object.
* </remarks>
* <param name="value">the array to create the new instance</param>
*/
inline static CacheableArray^ Create(array<ManagedType>^ value)
{
return (value != nullptr /*&& value->Length > 0*/ ?
gcnew CacheableArray(value) : nullptr);
}
/** <summary>
* Static function to create a new instance copying
* from the given array.
* </summary>
* <remarks>
* Providing a null or zero size array will return a null object.
* </remarks>
* <param name="value">the array to create the new instance</param>
*/
inline static CacheableArray^ Create(array<ManagedType>^ value, System::Int32 length)
{
return (value != nullptr && value->Length > 0 ?
gcnew CacheableArray(value, length) : nullptr);
}
/** <summary>
* Explicit conversion operator to contained array type.
* </summary>
*/
inline static explicit operator array<ManagedType> ^ (CacheableArray^ value)
{
return (value != nullptr ? value->Value : nullptr);
}
/** <summary>
* Factory function to register this class.
* </summary>
*/
static ISerializable^ CreateDeserializable()
{
return gcnew CacheableArray();
}
internal:
static ISerializable^ Create(std::shared_ptr<native::Serializable> obj)
{
return (obj != nullptr ? gcnew CacheableArray(obj) : nullptr);
}
private:
/** <summary>
* Allocates a new instance
* </summary>
*/
inline CacheableArray() : CacheableBuiltinArray() { }
/** <summary>
* Allocates a new instance copying from the given array.
* </summary>
* <remarks>
* Providing a null or zero size array will return a null object.
* </remarks>
* <param name="value">the array to create the new instance</param>
*/
inline CacheableArray(array<ManagedType>^ value) : CacheableBuiltinArray(value) { }
/** <summary>
* Allocates a new instance copying given length from the
* start of given array.
* </summary>
* <remarks>
* Providing a null or zero size array will return a null object.
* </remarks>
* <param name="value">the array to create the new instance</param>
*/
inline CacheableArray(array<ManagedType>^ value, System::Int32 length)
: CacheableBuiltinArray(value, length) { }
inline CacheableArray(std::shared_ptr<native::Serializable> nativeptr)
: CacheableBuiltinArray(nativeptr) { }
};
/// <summary>
/// An immutable wrapper for byte arrays that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableBytes = CacheableArray<native::internal::CacheableArrayPrimitive<int8_t, native::internal::DSCode::CacheableBytes>, Byte, static_cast<int8_t>(DSCode::CacheableBytes)>;
/// <summary>
/// An immutable wrapper for array of doubles that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableDoubleArray = CacheableArray<native::internal::CacheableArrayPrimitive<double, native::internal::DSCode::CacheableDoubleArray>, Double, static_cast<int8_t>(DSCode::CacheableDoubleArray)>;
/// <summary>
/// An immutable wrapper for array of floats that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableFloatArray = CacheableArray<native::internal::CacheableArrayPrimitive<float, native::internal::DSCode::CacheableFloatArray>, Single, static_cast<int8_t>(DSCode::CacheableFloatArray)>;
/// <summary>
/// An immutable wrapper for array of 16-bit integers that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableInt16Array = CacheableArray<native::internal::CacheableArrayPrimitive<int16_t, native::internal::DSCode::CacheableInt16Array>, System::Int16, static_cast<int8_t>(DSCode::CacheableInt16Array)>;
/// <summary>
/// An immutable wrapper for array of 32-bit integers that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableInt32Array = CacheableArray<native::internal::CacheableArrayPrimitive<int32_t, native::internal::DSCode::CacheableInt32Array>, System::Int32, static_cast<int8_t>(DSCode::CacheableInt32Array)>;
/// <summary>
/// An immutable wrapper for array of 64-bit integers that can serve
/// as a distributable object for caching.
/// </summary>
using CacheableInt64Array = CacheableArray<native::internal::CacheableArrayPrimitive<int64_t, native::internal::DSCode::CacheableInt64Array>, System::Int64, static_cast<int8_t>(DSCode::CacheableInt64Array)>;
/// <summary>
/// An immutable wrapper for array of booleans that can serve
/// as a distributable object for caching.
/// </summary>
using BooleanArray = CacheableArray<native::internal::CacheableArrayPrimitive<bool, native::internal::DSCode::BooleanArray>, bool, static_cast<int8_t>(DSCode::BooleanArray)>;
/// <summary>
/// An immutable wrapper for array of 16-bit characters that can serve
/// as a distributable object for caching.
/// </summary>
using CharArray = CacheableArray<native::internal::CacheableArrayPrimitive<char16_t, native::internal::DSCode::CharArray>, Char, static_cast<int8_t>(DSCode::CharArray)>;
} // namespace Client
} // namespace Geode
} // namespace Apache