Skip to content
Permalink
Browse files

pb: Add natives to work with 64 bit values (#943)

* Add natives to work with 64 bit Protobuf values

* Fix linux build

* FIX alignment requirements

* FIX alignment requirements V2

* Remove legacy API

* Inattention
  • Loading branch information...
komashchenko authored and KyleSanderson committed Mar 4, 2019
1 parent 7f9ceaa commit 8031e42bdae3046781b5d52a7a90d59e788105e6
Showing with 194 additions and 1 deletion.
  1. +84 −0 core/UserMessagePBHelpers.h
  2. +83 −0 core/smn_protobuf.cpp
  3. +3 −0 plugins/include/core.inc
  4. +24 −1 plugins/include/protobuf.inc
@@ -348,6 +348,20 @@ class SMProtobufMessage

return true;
}

inline bool GetInt64OrUnsigned(const char *pszFieldName, int64 *out)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_NOT_REPEATED();

if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
*out = (int64)msg->GetReflection()->GetUInt64(*msg, field);
else
*out = msg->GetReflection()->GetInt64(*msg, field);

return true;
}

inline bool SetInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
{
@@ -374,6 +388,24 @@ class SMProtobufMessage

return true;
}

inline bool SetInt64OrUnsigned(const char *pszFieldName, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_NOT_REPEATED();

if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->SetUInt64(msg, field, (uint64)value);
}
else
{
msg->GetReflection()->SetInt64(msg, field, value);
}

return true;
}

inline bool GetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 *out)
{
@@ -391,6 +423,21 @@ class SMProtobufMessage

return true;
}

inline bool GetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 *out)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);

if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
*out = (int64)msg->GetReflection()->GetRepeatedUInt64(*msg, field, index);
else
*out = msg->GetReflection()->GetRepeatedInt64(*msg, field, index);

return true;
}

inline bool SetRepeatedInt32OrUnsignedOrEnum(const char *pszFieldName, int index, int32 value)
{
@@ -418,6 +465,25 @@ class SMProtobufMessage

return true;
}

inline bool SetRepeatedInt64OrUnsigned(const char *pszFieldName, int index, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();
CHECK_REPEATED_ELEMENT(index);

if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->SetRepeatedUInt64(msg, field, index, (uint64)value);
}
else
{
msg->GetReflection()->SetRepeatedInt64(msg, field, index, value);
}

return true;
}

inline bool AddInt32OrUnsignedOrEnum(const char *pszFieldName, int32 value)
{
@@ -444,6 +510,24 @@ class SMProtobufMessage

return true;
}

inline bool AddInt64OrUnsigned(const char *pszFieldName, int64 value)
{
GETCHECK_FIELD();
CHECK_FIELD_TYPE2(INT64, UINT64);
CHECK_FIELD_REPEATED();

if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT64)
{
msg->GetReflection()->AddUInt64(msg, field, (uint64)value);
}
else
{
msg->GetReflection()->AddInt64(msg, field, value);
}

return true;
}

inline bool GetBool(const char *pszFieldName, bool *out)
{
@@ -82,6 +82,38 @@ static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
return ret;
}

static cell_t smn_PbReadInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();

cell_t *ret;
pCtx->LocalToPhysAddr(params[3], &ret);
int64 temp;
((cell_t *)&temp)[0] = ret[0];
((cell_t *)&temp)[1] = ret[1];

if (params[4] < 0)
{
if (!msg->GetInt64OrUnsigned(strField, &temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->GetRepeatedInt64OrUnsigned(strField, params[4], &temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
}
}

ret[0] = ((cell_t *)&temp)[0];
ret[1] = ((cell_t *)&temp)[1];

return 1;
}

static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -336,6 +368,35 @@ static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
return 1;
}

static cell_t smn_PbSetInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();

cell_t *value;
pCtx->LocalToPhysAddr(params[3], &value);
int64 temp;
((cell_t *)&temp)[0] = value[0];
((cell_t *)&temp)[1] = value[1];

if (params[4] < 0)
{
if (!msg->SetInt64OrUnsigned(strField, temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}
}
else
{
if (!msg->SetRepeatedInt64OrUnsigned(strField, params[4], temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[4], msg->GetProtobufMessage()->GetTypeName().c_str());
}
}

return 1;
}

static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -553,6 +614,25 @@ static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
return 1;
}

static cell_t smn_PbAddInt64(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
GET_FIELD_NAME_OR_ERR();

cell_t *value;
pCtx->LocalToPhysAddr(params[3], &value);
int64 temp;
((cell_t *)&temp)[0] = value[0];
((cell_t *)&temp)[1] = value[1];

if (!msg->AddInt64OrUnsigned(strField, temp))
{
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
}

return 1;
}

static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
{
GET_MSG_FROM_HANDLE_OR_ERR();
@@ -778,6 +858,7 @@ REGISTER_NATIVES(protobufnatives)

// Transitional syntax.
{"Protobuf.ReadInt", smn_PbReadInt},
{"Protobuf.ReadInt64", smn_PbReadInt64},
{"Protobuf.ReadFloat", smn_PbReadFloat},
{"Protobuf.ReadBool", smn_PbReadBool},
{"Protobuf.ReadString", smn_PbReadString},
@@ -788,6 +869,7 @@ REGISTER_NATIVES(protobufnatives)
{"Protobuf.GetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
{"Protobuf.HasField", smn_PbHasField},
{"Protobuf.SetInt", smn_PbSetInt},
{"Protobuf.SetInt64", smn_PbSetInt64},
{"Protobuf.SetFloat", smn_PbSetFloat},
{"Protobuf.SetBool", smn_PbSetBool},
{"Protobuf.SetString", smn_PbSetString},
@@ -796,6 +878,7 @@ REGISTER_NATIVES(protobufnatives)
{"Protobuf.SetVector", smn_PbSetVector},
{"Protobuf.SetVector2D", smn_PbSetVector2D},
{"Protobuf.AddInt", smn_PbAddInt},
{"Protobuf.AddInt64", smn_PbAddInt64},
{"Protobuf.AddFloat", smn_PbAddFloat},
{"Protobuf.AddBool", smn_PbAddBool},
{"Protobuf.AddString", smn_PbAddString},
@@ -279,6 +279,7 @@ public void __ext_core_SetNTVOptional()
MarkNativeAsOptional("PbAddMessage");

MarkNativeAsOptional("Protobuf.ReadInt");
MarkNativeAsOptional("Protobuf.ReadInt64");
MarkNativeAsOptional("Protobuf.ReadFloat");
MarkNativeAsOptional("Protobuf.ReadBool");
MarkNativeAsOptional("Protobuf.ReadString");
@@ -288,6 +289,7 @@ public void __ext_core_SetNTVOptional()
MarkNativeAsOptional("Protobuf.ReadVector2D");
MarkNativeAsOptional("Protobuf.GetRepeatedFieldCount");
MarkNativeAsOptional("Protobuf.SetInt");
MarkNativeAsOptional("Protobuf.SetInt64");
MarkNativeAsOptional("Protobuf.SetFloat");
MarkNativeAsOptional("Protobuf.SetBool");
MarkNativeAsOptional("Protobuf.SetString");
@@ -296,6 +298,7 @@ public void __ext_core_SetNTVOptional()
MarkNativeAsOptional("Protobuf.SetVector");
MarkNativeAsOptional("Protobuf.SetVector2D");
MarkNativeAsOptional("Protobuf.AddInt");
MarkNativeAsOptional("Protobuf.AddInt64");
MarkNativeAsOptional("Protobuf.AddFloat");
MarkNativeAsOptional("Protobuf.AddBool");
MarkNativeAsOptional("Protobuf.AddString");
@@ -46,6 +46,14 @@ methodmap Protobuf < Handle
// @return Integer value read.
// @error Non-existent field, or incorrect field type.
public native int ReadInt(const char[] field, int index = PB_FIELD_NOT_REPEATED);

// Reads an int64, uint64, sint64, fixed64, sfixed64 from a protobuf message.
//
// @param field Field name.
// @param value Array to represent the large integer (0=High bits, 1=Low bits).
// @param index Index into repeated field.
// @error Non-existent field, or incorrect field type.
public native void ReadInt64(const char[] field, int value[2], int index = PB_FIELD_NOT_REPEATED);

// Reads a float or downcasted double from a protobuf message.
//
@@ -125,7 +133,15 @@ methodmap Protobuf < Handle
// @param value Integer value to set.
// @param index Index into repeated field.
// @error Non-existent field, or incorrect field type.
public native int SetInt(const char[] field, int value, int index = PB_FIELD_NOT_REPEATED);
public native void SetInt(const char[] field, int value, int index = PB_FIELD_NOT_REPEATED);

// Sets an int64, uint64, sint64, fixed64, sfixed64 on a protobuf message.
//
// @param field Field name.
// @param value Large integer value to set (0=High bits, 1=Low bits).
// @param index Index into repeated field.
// @error Non-existent field, or incorrect field type.
public native void SetInt64(const char[] field, int value[2], int index = PB_FIELD_NOT_REPEATED);

// Sets a float or double on a protobuf message.
//
@@ -189,6 +205,13 @@ methodmap Protobuf < Handle
// @param value Integer value to add.
// @error Non-existent field, or incorrect field type.
public native void AddInt(const char[] field, int value);

// Add an int64, uint64, sint64, fixed64, sfixed64 to a protobuf message repeated field.
//
// @param field Field name.
// @param value Large integer value to add (0=High bits, 1=Low bits).
// @error Non-existent field, or incorrect field type.
public native void AddInt64(const char[] field, int value[2]);

// Add a float or double to a protobuf message repeated field.
//

0 comments on commit 8031e42

Please sign in to comment.
You can’t perform that action at this time.