Exemplo n.º 1
0
def request_functionSignature(command):
    out = "virtual OP_STATUS Do" + command.name + "("
    args = []
    #    if command.cpp_send_message:
    #        args.append("const OpScopeTPHeader &msg")
    if command.message.isNonEmpty():
        args.append("const %s &in" % message_className(command.message))
    if command.response.isNonEmpty():
        args.append("%s &out" % message_className(command.response))
    if is_deferred(command):
        args.append("unsigned int async_tag")
    out += ", ".join(args)
    out += ") = 0;"
    return out
Exemplo n.º 2
0
def request_functionSignature(command):
    out = "virtual OP_STATUS Do" + command.name + "("
    args = []
    #    if command.cpp_send_message:
    #        args.append("const OpScopeTPHeader &msg")
    if command.message.isNonEmpty():
        args.append("const %s &in" % message_className(command.message))
    if command.response.isNonEmpty():
        args.append("%s &out" % message_className(command.response))
    if is_deferred(command):
        args.append("unsigned int async_tag")
    out += ", ".join(args)
    out += ") = 0;"
    return out
Exemplo n.º 3
0
def event_functionSignature(command):
    if issubclass(type(command), Request):
        message = command.response
    else:
        message = command.message
    params = []
    if message.isNonEmpty():
        params.append("const %s &msg" % message_className(message))
    if is_deferred(command):
        params.append("unsigned int tag")
    out = "OP_STATUS %s(%s);" % (event_functionName(command), ", ".join(params))
    return out
Exemplo n.º 4
0
def event_functionSignature(command):
    if issubclass(type(command), Request):
        message = command.response
    else:
        message = command.message
    params = []
    if message.isNonEmpty():
        params.append("const %s &msg" % message_className(message))
    if is_deferred(command):
        params.append("unsigned int tag")
    out = "OP_STATUS %s(%s);" % (event_functionName(command),
                                 ", ".join(params))
    return out
Exemplo n.º 5
0
    def renderServiceImplementation(self, service, requests, events, generate_instance):
        class_name = service.options["cpp_class"].value + "_SI"

        class_name_base = service.iparent.cpp.cppMessageSet().symbol()
        if class_name_base.find("_MessageSet"):
            cpp_descriptor_class_name = class_name_base.replace("_MessageSet", "_Descriptors")
        else:
            cpp_descriptor_class_name = class_name_base + "_Descriptors"

        text = "\n"

        text += (
            "\n"
            + render(
                """
            // Service implementation

            %(class)s::%(class)s(const uni_char* id, OpScopeServiceManager *manager, ControlType control)
            		: OpScopeService(id == NULL ? UNI_L(%(protocol_name_quoted)s) : id, manager, control)
            {
            }

            /*virtual*/
            %(class)s::~%(class)s()
            {
            }
            """,
                {
                    "class": class_name,
                    "protocol_name_quoted": strQuote(utils.join_dashed(utils.split_camelcase(service.name))),
                    "serviceVarName": self.varName(service.name),
                },
            )
            + "\n"
        )
        if not generate_instance:
            return text

        text += (
            "\n"
            + render(
                """
            /*virtual*/
            int
            %(class)s::GetCommandCount() const
            {
            	return Command_Count;
            }

            /*virtual*/
            OpScopeService::CommandRange
            %(class)s::GetCommands() const
            {
            	Descriptors *descriptors = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(descriptors);
            	return CommandRange(descriptors ? descriptors->command_list : NULL, Command_Count);
            }

            /*virtual*/
            OP_STATUS
            %(class)s::DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg )
            {
            	// Check for invalid request data
            	if (msg.Status() != OpScopeTPMessage::OK) // All calls must have status OK
            		return SetCommandError(OpScopeTPMessage::BadRequest, GetInvalidStatusFieldText());
            	if (msg.ServiceName().Compare(GetName()) != 0) // Make sure the service name matches the one in the message
            		return SetCommandError(OpScopeTPMessage::InternalError, GetIncorrectServiceText());
            """,
                {
                    "class": class_name,
                    "protocol_name_quoted": strQuote(utils.join_dashed(utils.split_camelcase(service.name))),
                    "serviceVarName": self.varName(service.name),
                },
            )
            + "\n\n"
        )

        if requests:
            text += (
                self.indent(
                    render(
                        """
                if (msg.CommandID() == %(requestID)s) // %(requestName)s
                {
                """,
                        {"requestID": enumName(requests[0]), "requestName": requests[0].name},
                    )
                )
                + self.renderRequestDecode(requests[0])
                + "	}\n"
            )

            for command in requests[1:]:
                text += (
                    self.indent(
                        render(
                            """
                    else if (msg.CommandID() == %(requestID)s) // %(requestName)s
                    {
                    """,
                            {"requestID": enumName(command), "requestName": command.name},
                        )
                    )
                    + self.renderRequestDecode(command)
                    + "	}\n"
                )

            text += (
                self.indent(
                    render(
                        """
                else
                {
                	SetCommandError(OpScopeTPMessage::CommandNotFound, GetCommandNotFoundText());
                	return OpStatus::ERR;
                }
                """
                    )
                )
                + "\n"
            )

        text += "	return OpStatus::OK;\n}\n\n"

        messages = [msg for msg in service.messages() if msg != defaultMessage]
        enums = self.enums()

        text += (
            render(
                """
            /*virtual*/
            const OpProtobufMessage *
            %(class)s::GetMessage(unsigned message_id) const
            {
            	Descriptors *descriptors = GetDescriptors();
            	if (!descriptors)
            		return NULL;
            	return descriptors->Get(message_id);
            }

            %(class)s::Descriptors *
            %(class)s::GetDescriptors() const
            {
            	Descriptors *d = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(d);
            	return d;
            }

            /*virtual*/
            unsigned
            %(class)s::GetMessageCount() const
            {
            	return %(descriptorClass)s::_gen_Message_Count;
            }

            /*virtual*/
            OpScopeService::MessageIDRange
            %(class)s::GetMessageIDs() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageIDRange(start, start + %(descriptorClass)s::_gen_Message_Count);
            }

            /*virtual*/
            OpScopeService::MessageRange
            %(class)s::GetMessages() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageRange(this, start, start + %(descriptorClass)s::_gen_Message_Count);
            }
            """,
                {
                    "class": class_name,
                    "serviceVarName": self.varName(service.name),
                    "descriptorClass": cpp_descriptor_class_name,
                },
            )
            + "\n\n"
        )

        text += (
            render(
                """
            /* virtual */
            const char *
            %(class)s::GetVersionString() const
            {
            	return "%(version)s";
            }

            /* virtual */
            int
            %(class)s::GetMajorVersion() const
            {
            	return %(versionMajor)s;
            }

            /* virtual */
            int
            %(class)s::GetMinorVersion() const
            {
            	return %(versionMinor)s;
            }

            /* virtual */
            const char *
            %(class)s::GetPatchVersion() const
            {
            	return "%(versionPatch)s";
            }
            """,
                {
                    "class": class_name,
                    "version": service.options["version"].value,
                    "versionMajor": service.version[0],
                    "versionMinor": service.version[1],
                    "versionPatch": service.version[2],
                },
            )
            + "\n"
        )

        if events:
            for event in events:
                params = []
                if event.message.isNonEmpty():
                    params.append("const %s &msg" % message_className(event.message))
                if requiresAsyncResponse(event):
                    params.append("unsigned int tag")

                text += (
                    "\n"
                    + render(
                        """
                    OP_STATUS
                    %(class)s::%(eventMethod)s(%(eventParams)s) // %(eventName)s
                    {
                    """,
                        {
                            "class": class_name,
                            "eventMethod": event_functionName(event),
                            "eventParams": ", ".join(params),
                            "eventName": event.name,
                        },
                    )
                    + "\n"
                )

                if event.message.isNonEmpty():
                    text += (
                        "	OpProtobufInstanceProxy proxy(%(messageClass)s::GetMessageDescriptor(GetDescriptors()), const_cast<%(messageClass)s *>(&msg));\n"
                        % {"messageClass": message_className(event.message)}
                    )
                else:
                    text += "	OpProtobufInstanceProxy proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);\n"

                text += "	if (proxy.GetProtoMessage() == NULL)\n" + "		return OpStatus::ERR_NO_MEMORY;\n"

                if requiresAsyncResponse(event):
                    text += "	return SendAsyncResponse(tag, proxy, %(eventEnum)s);\n" % {"eventEnum": enumName(event)}
                else:
                    text += "	return SendEvent(proxy, %(eventEnum)s);\n" % {"eventEnum": enumName(event)}

                text += "}\n\n"

        if enums:
            text += (
                render(
                    """
                // Enum introspection: BEGIN

                /*virtual*/
                OpScopeService::EnumIDRange
                %(class)s::GetEnumIDs() const
                {
                	Descriptors *descriptors = GetDescriptors();
                	return EnumIDRange(descriptors ? descriptors->enum_id_list : NULL, %(descriptorClass)s::_gen_Enum_Count);
                }

                /*virtual*/
                unsigned
                %(class)s::GetEnumCount() const
                {
                	return %(descriptorClass)s::_gen_Enum_Count;
                }

                /*virtual*/
                BOOL
                %(class)s::HasEnum(unsigned enum_id) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name, "descriptorClass": cpp_descriptor_class_name},
                )
                + "\n"
            )
            for enum in enums:
                text += "		case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:\n" % {
                    "enumPath": "_".join(enum.path()),
                    "descriptorClass": cpp_descriptor_class_name,
                }

            text += "			return TRUE;\n" "	}\n" "	return FALSE;\n" "}\n" "\n"
            text += (
                render(
                    """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name},
                )
                + "\n"
            )

            for enum in enums:
                text += (
                    self.indent(
                        render(
                            """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    	name = UNI_L(%(enum)s);
                    	value_count = %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s;
                    	return OpStatus::OK;
                    """,
                            {
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumPath": "_".join(enum.path()),
                                "enum": strQuote(enum.name),
                                "descriptorClass": cpp_descriptor_class_name,
                            },
                        ),
                        2,
                    )
                    + "\n"
                )

            text += "	}\n" "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n" "}\n" "\n"
            text += (
                render(
                    """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name},
                )
                + "\n"
            )

            for enum in enums:
                text += (
                    self.indent(
                        render(
                            """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    {
                    """,
                            {
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumPath": "_".join(enum.path()),
                                "descriptorClass": cpp_descriptor_class_name,
                            },
                        ),
                        2,
                    )
                    + "\n"
                )
                if enum.values:
                    text += (
                        self.indent(
                            render(
                                """
                        if (idx > %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s)
                        	return OpStatus::ERR_OUT_OF_RANGE;
                        // Values for %(messageClassPath)s
                        const unsigned enum_numbers[] = {
                        	  %(enumValue)s
                        """,
                                {
                                    "enumPath": "_".join(enum.path()),
                                    "messageClassPath": messageClassPath(enum)[1],
                                    "enumValue": enum.values[0].value,
                                    "descriptorClass": cpp_descriptor_class_name,
                                },
                            ),
                            3,
                        )
                        + "\n"
                    )
                    for value in enum.values[1:]:
                        text += "				, %s\n" % value.value

                    text += (
                        self.indent(
                            render(
                                """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const unsigned name_offsets[] = {
                        	  0
                        """
                            ),
                            3,
                        )
                        + "\n"
                    )
                    for idx in range(1, len(enum.values)):
                        text += "				, %(offset)s\n" % {
                            "offset": sum([len(value.name) + 1 for value in enum.values[:idx]])
                        }

                    text += (
                        self.indent(
                            render(
                                """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const uni_char *names = UNI_L( %(enumStrings)s );
                        OP_ASSERT(idx < sizeof(name_offsets));
                        OP_ASSERT(idx < sizeof(enum_numbers));
                        value_name = names + name_offsets[idx];
                        value_number = enum_numbers[idx];
                        return OpStatus::OK;
                        """,
                                {
                                    "enumStrings": strQuote(
                                        "".join(
                                            [value.name + "\0" for value in enum.values[:-1]] + [enum.values[-1].name]
                                        )
                                    )
                                },
                            ),
                            3,
                        )
                        + "\n"
                    )
                else:
                    text += "			return OpStatus::ERR; // No values so return error\n"

                text += "		}\n\n"

            text += "	}\n" "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n" "}\n" "// Enum introspection: END\n"
        return text
Exemplo n.º 6
0
    def renderRequestDecode(self, command):
        text = "\n		OP_STATUS status = OpStatus::OK;\n"

        if requiresAsyncResponse(command):
            text += (
                self.indent(
                    render(
                        """
                unsigned async_tag;
                status = InitAsyncCommand(msg, async_tag); // Needed for async requests, the response will use this info when request is done
                if (OpStatus::IsError(status))
                {
                	RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetInitAsyncCommandFailedText()));
                	return status;
                }
                """
                    ),
                    2,
                )
                + "\n"
            )

        if command.message.isNonEmpty():
            text += "		%(requestMessage)s in;\n" % {"requestMessage": message_className(command.message)}

        if hasattr(command, "response") and command.response.isNonEmpty():
            text += "		%(responseMessage)s out;\n" % {"responseMessage": message_className(command.response)}
        text += "\n"

        if command.message.isNonEmpty():
            text += (
                self.indent(
                    render(
                        """
                OpProtobufInstanceProxy in_proxy(%(requestMessage)s::GetMessageDescriptor(GetDescriptors()), &in);
                if (in_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = ParseMessage(client, msg, in_proxy);
                if (OpStatus::IsError(status))
                {
                	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by a parser
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetParseCommandMessageFailedText()));
                	return status;
                }
                """,
                        {"requestMessage": message_className(command.message)},
                    ),
                    2,
                )
                + "\n\n"
            )

        text += (
            self.indent(
                render(
                    """
            status = %(commandCall)s;
            if (OpStatus::IsError(status))
            {
            	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by command
            """
                )
                % {"commandCall": request_functionCall(command)},
                2,
            )
            + "\n"
        )

        if requiresAsyncResponse(command):
            text += (
                self.indent(
                    render(
                        """
                {
                	OP_STATUS tmp_status = SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText());
                	OpStatus::Ignore(tmp_status);
                }
                // Remove the async command since the command failed to send an async response
                CleanupAsyncCommand(async_tag);
            """
                    ),
                    3,
                )
                + "\n"
            )
        else:
            text += "			RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText()));\n"

        text += "			return status;\n" + "		}\n"

        if hasattr(command, "response") and command.response.isNonEmpty():
            text += (
                "\n"
                + self.indent(
                    render(
                        """
                OpProtobufInstanceProxy out_proxy(%(responseMessage)s::GetMessageDescriptor(GetDescriptors()), &out);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                RETURN_IF_ERROR(SendResponse(client, msg, out_proxy));
            """,
                        {"responseMessage": message_className(command.response)},
                    ),
                    2,
                )
                + "\n"
            )
        elif not requiresAsyncResponse(command):
            text += (
                "\n"
                + self.indent(
                    render(
                        """
                // The request does not define a response message so we send the default response which is an empty message
                OpProtobufInstanceProxy out_proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = SendResponse(client, msg, out_proxy);
                if (OpStatus::IsError(status))
                {
                	if (!IsResponseSent() && GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if response sending failed or no error was set by response code
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandResponseFailedText()));
                	return status;
                }
            """,
                        {},
                    ),
                    2,
                )
                + "\n"
            )
        return text
Exemplo n.º 7
0
    def renderServiceImplementation(self, service, requests, events,
                                    generate_instance):
        class_name = service.options["cpp_class"].value + "_SI"

        class_name_base = service.iparent.cpp.cppMessageSet().symbol()
        if class_name_base.find("_MessageSet"):
            cpp_descriptor_class_name = class_name_base.replace(
                "_MessageSet", "_Descriptors")
        else:
            cpp_descriptor_class_name = class_name_base + "_Descriptors"

        text = "\n"

        text += "\n" + render(
            """
            // Service implementation

            %(class)s::%(class)s(const uni_char* id, OpScopeServiceManager *manager, ControlType control)
            		: OpScopeService(id == NULL ? UNI_L(%(protocol_name_quoted)s) : id, manager, control)
            {
            }

            /*virtual*/
            %(class)s::~%(class)s()
            {
            }
            """, {
                "class":
                class_name,
                "protocol_name_quoted":
                strQuote(utils.join_dashed(utils.split_camelcase(
                    service.name))),
                "serviceVarName":
                self.varName(service.name),
            }) + "\n"
        if not generate_instance:
            return text

        text += "\n" + render(
            """
            /*virtual*/
            int
            %(class)s::GetCommandCount() const
            {
            	return Command_Count;
            }

            /*virtual*/
            OpScopeService::CommandRange
            %(class)s::GetCommands() const
            {
            	Descriptors *descriptors = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(descriptors);
            	return CommandRange(descriptors ? descriptors->command_list : NULL, Command_Count);
            }

            /*virtual*/
            OP_STATUS
            %(class)s::DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg )
            {
            	// Check for invalid request data
            	if (msg.Status() != OpScopeTPMessage::OK) // All calls must have status OK
            		return SetCommandError(OpScopeTPMessage::BadRequest, GetInvalidStatusFieldText());
            	if (msg.ServiceName().Compare(GetName()) != 0) // Make sure the service name matches the one in the message
            		return SetCommandError(OpScopeTPMessage::InternalError, GetIncorrectServiceText());
            """, {
                "class":
                class_name,
                "protocol_name_quoted":
                strQuote(utils.join_dashed(utils.split_camelcase(
                    service.name))),
                "serviceVarName":
                self.varName(service.name),
            }) + "\n\n"

        if requests:
            text += self.indent(
                render(
                    """
                if (msg.CommandID() == %(requestID)s) // %(requestName)s
                {
                """, {
                        "requestID": enumName(requests[0]),
                        "requestName": requests[0].name,
                    })) + self.renderRequestDecode(requests[0]) + "	}\n"

            for command in requests[1:]:
                text += self.indent(
                    render(
                        """
                    else if (msg.CommandID() == %(requestID)s) // %(requestName)s
                    {
                    """, {
                            "requestID": enumName(command),
                            "requestName": command.name,
                        })) + self.renderRequestDecode(command) + "	}\n"

            text += self.indent(
                render("""
                else
                {
                	SetCommandError(OpScopeTPMessage::CommandNotFound, GetCommandNotFoundText());
                	return OpStatus::ERR;
                }
                """)) + "\n"

        text += "	return OpStatus::OK;\n}\n\n"

        messages = [msg for msg in service.messages() if msg != defaultMessage]
        enums = self.enums()

        text += render(
            """
            /*virtual*/
            const OpProtobufMessage *
            %(class)s::GetMessage(unsigned message_id) const
            {
            	Descriptors *descriptors = GetDescriptors();
            	if (!descriptors)
            		return NULL;
            	return descriptors->Get(message_id);
            }

            %(class)s::Descriptors *
            %(class)s::GetDescriptors() const
            {
            	Descriptors *d = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(d);
            	return d;
            }

            /*virtual*/
            unsigned
            %(class)s::GetMessageCount() const
            {
            	return %(descriptorClass)s::_gen_Message_Count;
            }

            /*virtual*/
            OpScopeService::MessageIDRange
            %(class)s::GetMessageIDs() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageIDRange(start, start + %(descriptorClass)s::_gen_Message_Count);
            }

            /*virtual*/
            OpScopeService::MessageRange
            %(class)s::GetMessages() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageRange(this, start, start + %(descriptorClass)s::_gen_Message_Count);
            }
            """, {
                "class": class_name,
                "serviceVarName": self.varName(service.name),
                "descriptorClass": cpp_descriptor_class_name,
            }) + "\n\n"

        text += render(
            """
            /* virtual */
            const char *
            %(class)s::GetVersionString() const
            {
            	return "%(version)s";
            }

            /* virtual */
            int
            %(class)s::GetMajorVersion() const
            {
            	return %(versionMajor)s;
            }

            /* virtual */
            int
            %(class)s::GetMinorVersion() const
            {
            	return %(versionMinor)s;
            }

            /* virtual */
            const char *
            %(class)s::GetPatchVersion() const
            {
            	return "%(versionPatch)s";
            }
            """, {
                "class": class_name,
                "version": service.options["version"].value,
                "versionMajor": service.version[0],
                "versionMinor": service.version[1],
                "versionPatch": service.version[2],
            }) + "\n"

        if events:
            for event in events:
                params = []
                if event.message.isNonEmpty():
                    params.append("const %s &msg" %
                                  message_className(event.message))
                if requiresAsyncResponse(event):
                    params.append("unsigned int tag")

                text += "\n" + render(
                    """
                    OP_STATUS
                    %(class)s::%(eventMethod)s(%(eventParams)s) // %(eventName)s
                    {
                    """, {
                        "class": class_name,
                        "eventMethod": event_functionName(event),
                        "eventParams": ", ".join(params),
                        "eventName": event.name,
                    }) + "\n"

                if event.message.isNonEmpty():
                    text += "	OpProtobufInstanceProxy proxy(%(messageClass)s::GetMessageDescriptor(GetDescriptors()), const_cast<%(messageClass)s *>(&msg));\n" % {
                        "messageClass": message_className(event.message),
                    }
                else:
                    text += "	OpProtobufInstanceProxy proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);\n"

                text += ("	if (proxy.GetProtoMessage() == NULL)\n" +
                         "		return OpStatus::ERR_NO_MEMORY;\n")

                if requiresAsyncResponse(event):
                    text += "	return SendAsyncResponse(tag, proxy, %(eventEnum)s);\n" % {
                        "eventEnum": enumName(event)
                    }
                else:
                    text += "	return SendEvent(proxy, %(eventEnum)s);\n" % {
                        "eventEnum": enumName(event)
                    }

                text += "}\n\n"

        if enums:
            text += render(
                """
                // Enum introspection: BEGIN

                /*virtual*/
                OpScopeService::EnumIDRange
                %(class)s::GetEnumIDs() const
                {
                	Descriptors *descriptors = GetDescriptors();
                	return EnumIDRange(descriptors ? descriptors->enum_id_list : NULL, %(descriptorClass)s::_gen_Enum_Count);
                }

                /*virtual*/
                unsigned
                %(class)s::GetEnumCount() const
                {
                	return %(descriptorClass)s::_gen_Enum_Count;
                }

                /*virtual*/
                BOOL
                %(class)s::HasEnum(unsigned enum_id) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                    "descriptorClass": cpp_descriptor_class_name,
                }) + "\n"
            for enum in enums:
                text += "		case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:\n" % {
                    "enumPath": "_".join(enum.path()),
                    "descriptorClass": cpp_descriptor_class_name,
                }

            text += ("			return TRUE;\n" "	}\n" "	return FALSE;\n" "}\n" "\n")
            text += render(
                """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                }) + "\n"

            for enum in enums:
                text += self.indent(
                    render(
                        """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    	name = UNI_L(%(enum)s);
                    	value_count = %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s;
                    	return OpStatus::OK;
                    """, {
                            "messageClassPath": messageClassPath(enum)[1],
                            "enumPath": "_".join(enum.path()),
                            "enum": strQuote(enum.name),
                            "descriptorClass": cpp_descriptor_class_name,
                        }), 2) + "\n"

            text += ("	}\n"
                     "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n"
                     "}\n"
                     "\n")
            text += render(
                """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                }) + "\n"

            for enum in enums:
                text += self.indent(
                    render(
                        """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    {
                    """, {
                            "messageClassPath": messageClassPath(enum)[1],
                            "enumPath": "_".join(enum.path()),
                            "descriptorClass": cpp_descriptor_class_name,
                        }), 2) + "\n"
                if enum.values:
                    text += self.indent(
                        render(
                            """
                        if (idx > %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s)
                        	return OpStatus::ERR_OUT_OF_RANGE;
                        // Values for %(messageClassPath)s
                        const unsigned enum_numbers[] = {
                        	  %(enumValue)s
                        """, {
                                "enumPath": "_".join(enum.path()),
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumValue": enum.values[0].value,
                                "descriptorClass": cpp_descriptor_class_name,
                            }), 3) + "\n"
                    for value in enum.values[1:]:
                        text += "				, %s\n" % value.value

                    text += self.indent(
                        render("""
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const unsigned name_offsets[] = {
                        	  0
                        """), 3) + "\n"
                    for idx in range(1, len(enum.values)):
                        text += "				, %(offset)s\n" % {
                            "offset":
                            sum([
                                len(value.name) + 1
                                for value in enum.values[:idx]
                            ])
                        }

                    text += self.indent(
                        render(
                            """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const uni_char *names = UNI_L( %(enumStrings)s );
                        OP_ASSERT(idx < sizeof(name_offsets));
                        OP_ASSERT(idx < sizeof(enum_numbers));
                        value_name = names + name_offsets[idx];
                        value_number = enum_numbers[idx];
                        return OpStatus::OK;
                        """, {
                                "enumStrings":
                                strQuote("".join([
                                    value.name + "\0"
                                    for value in enum.values[:-1]
                                ] + [enum.values[-1].name]))
                            }), 3) + "\n"
                else:
                    text += "			return OpStatus::ERR; // No values so return error\n"

                text += "		}\n\n"

            text += ("	}\n"
                     "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n"
                     "}\n"
                     "// Enum introspection: END\n")
        return text
Exemplo n.º 8
0
    def renderRequestDecode(self, command):
        text = "\n		OP_STATUS status = OpStatus::OK;\n"

        if requiresAsyncResponse(command):
            text += self.indent(
                render("""
                unsigned async_tag;
                status = InitAsyncCommand(msg, async_tag); // Needed for async requests, the response will use this info when request is done
                if (OpStatus::IsError(status))
                {
                	RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetInitAsyncCommandFailedText()));
                	return status;
                }
                """), 2) + "\n"

        if command.message.isNonEmpty():
            text += "		%(requestMessage)s in;\n" % {
                "requestMessage": message_className(command.message)
            }

        if hasattr(command, 'response') and command.response.isNonEmpty():
            text += "		%(responseMessage)s out;\n" % {
                "responseMessage": message_className(command.response)
            }
        text += "\n"

        if command.message.isNonEmpty():
            text += self.indent(
                render(
                    """
                OpProtobufInstanceProxy in_proxy(%(requestMessage)s::GetMessageDescriptor(GetDescriptors()), &in);
                if (in_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = ParseMessage(client, msg, in_proxy);
                if (OpStatus::IsError(status))
                {
                	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by a parser
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetParseCommandMessageFailedText()));
                	return status;
                }
                """, {
                        "requestMessage": message_className(command.message),
                    }), 2) + "\n\n"

        text += self.indent(
            render("""
            status = %(commandCall)s;
            if (OpStatus::IsError(status))
            {
            	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by command
            """) % {
                "commandCall": request_functionCall(command),
            }, 2) + "\n"

        if requiresAsyncResponse(command):
            text += self.indent(
                render("""
                {
                	OP_STATUS tmp_status = SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText());
                	OpStatus::Ignore(tmp_status);
                }
                // Remove the async command since the command failed to send an async response
                CleanupAsyncCommand(async_tag);
            """), 3) + "\n"
        else:
            text += "			RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText()));\n"

        text += ("			return status;\n" + "		}\n")

        if hasattr(command, 'response') and command.response.isNonEmpty():
            text += "\n" + self.indent(
                render(
                    """
                OpProtobufInstanceProxy out_proxy(%(responseMessage)s::GetMessageDescriptor(GetDescriptors()), &out);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                RETURN_IF_ERROR(SendResponse(client, msg, out_proxy));
            """, {
                        "responseMessage": message_className(command.response),
                    }), 2) + "\n"
        elif not requiresAsyncResponse(command):
            text += "\n" + self.indent(
                render(
                    """
                // The request does not define a response message so we send the default response which is an empty message
                OpProtobufInstanceProxy out_proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = SendResponse(client, msg, out_proxy);
                if (OpStatus::IsError(status))
                {
                	if (!IsResponseSent() && GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if response sending failed or no error was set by response code
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandResponseFailedText()));
                	return status;
                }
            """, {}), 2) + "\n"
        return text