From 306828480fc78fa3900ef09ee2ccec8abf201129 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Sat, 16 Mar 2013 13:31:56 -0400 Subject: [PATCH] Added repeated field handing to PbSet* natives (bug 5633, r=asherkin). --- core/UserMessagePBHelpers.h | 179 +++++++++++++++++++++++++++++++++++ core/smn_protobuf.cpp | 120 +++++++++++++++++++---- plugins/include/protobuf.inc | 24 +++-- 3 files changed, 299 insertions(+), 24 deletions(-) diff --git a/core/UserMessagePBHelpers.h b/core/UserMessagePBHelpers.h index bdf3b434..068d77bc 100644 --- a/core/UserMessagePBHelpers.h +++ b/core/UserMessagePBHelpers.h @@ -139,6 +139,17 @@ public: return true; } + inline bool SetRepeatedInt32(const char *pszFieldName, int index, int32 value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(INT32); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedInt32(msg, field, index, value); + return true; + } + inline bool AddInt32(const char *pszFieldName, int32 value) { GETCHECK_FIELD(); @@ -180,6 +191,17 @@ public: return true; } + inline bool SetRepeatedInt64(const char *pszFieldName, int index, int64 value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(INT64); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedInt64(msg, field, index, value); + return true; + } + inline bool AddInt64(const char *pszFieldName, int64 value) { GETCHECK_FIELD(); @@ -221,6 +243,17 @@ public: return true; } + inline bool SetRepeatedUInt32(const char *pszFieldName, int index, uint32 value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(UINT32); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedUInt32(msg, field, index, value); + return true; + } + inline bool AddUInt32(const char *pszFieldName, uint32 value) { GETCHECK_FIELD(); @@ -262,6 +295,17 @@ public: return true; } + inline bool SetRepeatedUInt64(const char *pszFieldName, int index, uint64 value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(UINT64); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedUInt64(msg, field, index, value); + return true; + } + inline bool AddUInt64(const char *pszFieldName, uint64 value) { GETCHECK_FIELD(); @@ -315,6 +359,21 @@ public: return true; } + inline bool SetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE2(INT32, UINT32); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32) + msg->GetReflection()->SetRepeatedUInt32(msg, field, index, (uint32)value); + else + msg->GetReflection()->SetRepeatedInt32(msg, field, index, value); + + return true; + } + inline bool AddInt32OrUnsigned(const char *pszFieldName, int32 value) { GETCHECK_FIELD(); @@ -360,6 +419,17 @@ public: return true; } + inline bool SetRepeatedBool(const char *pszFieldName, int index, bool value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(BOOL); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedBool(msg, field, index, value); + return true; + } + inline bool AddBool(const char *pszFieldName, bool value) { GETCHECK_FIELD(); @@ -401,6 +471,17 @@ public: return true; } + inline bool SetRepeatedFloat(const char *pszFieldName, int index, float value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(FLOAT); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedFloat(msg, field, index, value); + return true; + } + inline bool AddFloat(const char *pszFieldName, float value) { GETCHECK_FIELD(); @@ -442,6 +523,17 @@ public: return true; } + inline bool SetRepeatedDouble(const char *pszFieldName, int index, double value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(DOUBLE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedDouble(msg, field, index, value); + return true; + } + inline bool AddDouble(const char *pszFieldName, double value) { GETCHECK_FIELD(); @@ -495,6 +587,21 @@ public: return true; } + inline bool SetRepeatedFloatOrDouble(const char *pszFieldName, int index, float value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE2(FLOAT, DOUBLE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE) + msg->GetReflection()->SetRepeatedDouble(msg, field, index, (double)value); + else + msg->GetReflection()->SetRepeatedFloat(msg, field, index, value); + + return true; + } + inline bool AddFloatOrDouble(const char *pszFieldName, float value) { GETCHECK_FIELD(); @@ -544,6 +651,18 @@ public: return true; } + inline bool SetRepeatedString(const char *pszFieldName, int index, const char *value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(STRING); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + msg->GetReflection()->SetRepeatedString(msg, field, index, value); + + return true; + } + inline bool AddString(const char *pszFieldName, const char *value) { GETCHECK_FIELD(); @@ -604,6 +723,22 @@ public: return true; } + inline bool SetRepeatedColor(const char *pszFieldName, int index, const Color &value) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(MESSAGE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + CMsgRGBA *msgRGBA = (CMsgRGBA *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index); + msgRGBA->set_r(value.r()); + msgRGBA->set_g(value.g()); + msgRGBA->set_b(value.b()); + msgRGBA->set_a(value.a()); + + return true; + } + inline bool AddColor(const char *pszFieldName, const Color &value) { GETCHECK_FIELD(); @@ -663,6 +798,20 @@ public: return true; } + inline bool SetRepeatedVector2D(const char *pszFieldName, int index, Vector2D &vec) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(MESSAGE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + CMsgVector2D *msgVec2d = (CMsgVector2D *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index); + msgVec2d->set_x(vec.x); + msgVec2d->set_y(vec.y); + + return true; + } + inline bool AddVector2D(const char *pszFieldName, Vector2D &vec) { GETCHECK_FIELD(); @@ -723,6 +872,21 @@ public: return true; } + inline bool SetRepeatedVector(const char *pszFieldName, int index, Vector &vec) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(MESSAGE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + CMsgVector *msgVec = (CMsgVector *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index); + msgVec->set_x(vec.x); + msgVec->set_y(vec.y); + msgVec->set_z(vec.z); + + return true; + } + inline bool AddVector(const char *pszFieldName, Vector &vec) { GETCHECK_FIELD(); @@ -784,6 +948,21 @@ public: return true; } + inline bool SetRepeatedQAngle(const char *pszFieldName, int index, QAngle &vec) + { + GETCHECK_FIELD(); + CHECK_FIELD_TYPE(MESSAGE); + CHECK_FIELD_REPEATED(); + CHECK_REPEATED_ELEMENT(index); + + CMsgQAngle *msgAng = (CMsgQAngle *)msg->GetReflection()->MutableRepeatedMessage(msg, field, index); + msgAng->set_x(vec.x); + msgAng->set_y(vec.y); + msgAng->set_z(vec.z); + + return true; + } + inline bool AddQAngle(const char *pszFieldName, QAngle &vec) { GETCHECK_FIELD(); diff --git a/core/smn_protobuf.cpp b/core/smn_protobuf.cpp index 92f8b132..0c8d4ec5 100644 --- a/core/smn_protobuf.cpp +++ b/core/smn_protobuf.cpp @@ -458,9 +458,20 @@ static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params) GET_MSG_FROM_HANDLE_OR_ERR(); GET_FIELD_NAME_OR_ERR(); - if (!msg->SetInt32OrUnsigned(strField, params[3])) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetInt32OrUnsigned(strField, params[3])) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedInt32OrUnsigned(strField, index, params[3])) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -471,9 +482,20 @@ static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params) GET_MSG_FROM_HANDLE_OR_ERR(); GET_FIELD_NAME_OR_ERR(); - if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3]))) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3]))) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedFloatOrDouble(strField, index, sp_ctof(params[3]))) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -485,9 +507,20 @@ static cell_t smn_PbSetBool(IPluginContext *pCtx, const cell_t *params) GET_FIELD_NAME_OR_ERR(); bool value = (params[3] == 0 ? false : true); - if (!msg->SetBool(strField, value)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetBool(strField, value)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedBool(strField, index, value)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -505,9 +538,20 @@ static cell_t smn_PbSetString(IPluginContext *pCtx, const cell_t *params) return 0; } - if (!msg->SetString(strField, strValue)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetString(strField, strValue)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedString(strField, index, strValue)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -531,9 +575,20 @@ static cell_t smn_PbSetColor(IPluginContext *pCtx, const cell_t *params) clrParams[2], clrParams[3]); - if (!msg->SetColor(strField, clr)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetColor(strField, clr)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedColor(strField, index, clr)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -556,9 +611,20 @@ static cell_t smn_PbSetAngle(IPluginContext *pCtx, const cell_t *params) sp_ctof(angParams[1]), sp_ctof(angParams[2])); - if (!msg->SetQAngle(strField, ang)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetQAngle(strField, ang)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedQAngle(strField, index, ang)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -581,9 +647,20 @@ static cell_t smn_PbSetVector(IPluginContext *pCtx, const cell_t *params) sp_ctof(vecParams[1]), sp_ctof(vecParams[2])); - if (!msg->SetVector(strField, vec)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetVector(strField, vec)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedVector(strField, index, vec)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; @@ -605,9 +682,20 @@ static cell_t smn_PbSetVector2D(IPluginContext *pCtx, const cell_t *params) sp_ctof(vecParams[0]), sp_ctof(vecParams[1])); - if (!msg->SetVector2D(strField, vec)) + int index = params[0] >= 4 ? params[4] : -1; + if (index < 0) { - return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + if (!msg->SetVector2D(strField, vec)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str()); + } + } + else + { + if (!msg->SetRepeatedVector2D(strField, index, vec)) + { + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str()); + } } return 1; diff --git a/plugins/include/protobuf.inc b/plugins/include/protobuf.inc index c0248678..a24e8059 100644 --- a/plugins/include/protobuf.inc +++ b/plugins/include/protobuf.inc @@ -249,10 +249,11 @@ native PbReadRepeatedVector2D(Handle:pb, const String:field[], index, Float:buff * @param pb protobuf handle. * @param field Field name. * @param value Integer value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetInt(Handle:pb, const String:field[], value); +native PbSetInt(Handle:pb, const String:field[], value, index=PB_FIELD_NOT_REPEATED); /** * Sets a float or double on a protobuf message. @@ -260,10 +261,11 @@ native PbSetInt(Handle:pb, const String:field[], value); * @param pb protobuf handle. * @param field Field name. * @param value Float value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetFloat(Handle:pb, const String:field[], Float:value); +native PbSetFloat(Handle:pb, const String:field[], Float:value, index=PB_FIELD_NOT_REPEATED); /** * Sets a bool on a protobuf message. @@ -271,10 +273,11 @@ native PbSetFloat(Handle:pb, const String:field[], Float:value); * @param pb protobuf handle. * @param field Field name. * @param value Boolean value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetBool(Handle:pb, const String:field[], bool:value); +native PbSetBool(Handle:pb, const String:field[], bool:value, index=PB_FIELD_NOT_REPEATED); /** * Sets a string on a protobuf message. @@ -282,10 +285,11 @@ native PbSetBool(Handle:pb, const String:field[], bool:value); * @param pb protobuf handle. * @param field Field name. * @param value String value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetString(Handle:pb, const String:field[], const String:value[]); +native PbSetString(Handle:pb, const String:field[], const String:value[], index=PB_FIELD_NOT_REPEATED); /** * Sets an RGBA color on a protobuf message. @@ -293,10 +297,11 @@ native PbSetString(Handle:pb, const String:field[], const String:value[]); * @param pb protobuf handle. * @param field Field name. * @param value Color value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetColor(Handle:pb, const String:field[], const color[4]); +native PbSetColor(Handle:pb, const String:field[], const color[4], index=PB_FIELD_NOT_REPEATED); /** * Sets an XYZ angle on a protobuf message. @@ -304,10 +309,11 @@ native PbSetColor(Handle:pb, const String:field[], const color[4]); * @param pb protobuf handle. * @param field Field name. * @param value Angle value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetAngle(Handle:pb, const String:field[], const Float:angle[3]); +native PbSetAngle(Handle:pb, const String:field[], const Float:angle[3], index=PB_FIELD_NOT_REPEATED); /** * Sets an XYZ vector on a protobuf message. @@ -315,10 +321,11 @@ native PbSetAngle(Handle:pb, const String:field[], const Float:angle[3]); * @param pb protobuf handle. * @param field Field name. * @param value Vector value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetVector(Handle:pb, const String:field[], const Float:vec[3]); +native PbSetVector(Handle:pb, const String:field[], const Float:vec[3], index=PB_FIELD_NOT_REPEATED); /** * Sets an XY vector on a protobuf message. @@ -326,10 +333,11 @@ native PbSetVector(Handle:pb, const String:field[], const Float:vec[3]); * @param pb protobuf handle. * @param field Field name. * @param value Vector value to set. + * @param index Index into repeated field. * @noreturn * @error Invalid or incorrect Handle, non-existant field, or incorrect field type. */ -native PbSetVector2D(Handle:pb, const String:field[], const Float:vec[2]); +native PbSetVector2D(Handle:pb, const String:field[], const Float:vec[2], index=PB_FIELD_NOT_REPEATED); /** * Add an int32, uint32, sint32, fixed32, or sfixed32 to a protobuf message repeated field.