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
This commit is contained in:
komashchenko 2019-03-04 19:06:43 +02:00 committed by Kyle Sanderson
parent 7f9ceaac06
commit 8031e42bda
4 changed files with 194 additions and 1 deletions

View File

@ -348,6 +348,20 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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)
{

View File

@ -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},

View File

@ -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");

View File

@ -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.
//