def generate(self): self.decl_includes = [ "modules/protobuf/src/protobuf_utils.h", "modules/protobuf/src/protobuf_message.h", ] self.decl_forward_decls = [ "OpScopeTPMessage", "OpProtobufField", "OpProtobufMessage", ] self.impl_includes = [ "modules/protobuf/src/protobuf_utils.h", "modules/scope/src/scope_tp_message.h", "modules/scope/src/scope_default_message.h", "modules/scope/src/scope_manager.h", "modules/scope/src/generated/g_scope_manager.h", ] if "cpp_file" in self.service.options: cpp_file = self.service.options["cpp_file"].value else: cpp_file = utils.join_underscore( utils.split_camelcase(self.service.name)) files = self.service.cpp.files() self.impl_includes.append(files["generatedServiceDeclaration"]) self.impl_includes.append(files["serviceDeclaration"]) commands = copy(self.sortedCommands()) for command in commands: command.options["cpp_enum_name"] = commandEnumName(command.name) requests = [ command for command in commands if issubclass(type(command), Request) and not is_deferred(command) ] events = [ command for command in commands if issubclass(type(command), Event) ] async = [(command.toRequest(), command.toEvent()) for command in commands if issubclass(type(command), Request) and is_deferred(command) ] requests += [req[0] for req in async] events += [req[1] for req in async] self.service.version = self.getVersion() import hob.proto self.commands = commands self.requests = requests self.events = events
def generate(self): self.decl_includes = ["modules/protobuf/src/protobuf_utils.h", "modules/protobuf/src/protobuf_message.h"] self.decl_forward_decls = ["OpScopeTPMessage", "OpProtobufField", "OpProtobufMessage"] self.impl_includes = [ "modules/protobuf/src/protobuf_utils.h", "modules/scope/src/scope_tp_message.h", "modules/scope/src/scope_default_message.h", "modules/scope/src/scope_manager.h", "modules/scope/src/generated/g_scope_manager.h", ] if "cpp_file" in self.service.options: cpp_file = self.service.options["cpp_file"].value else: cpp_file = utils.join_underscore(utils.split_camelcase(self.service.name)) files = self.service.cpp.files() self.impl_includes.append(files["generatedServiceDeclaration"]) self.impl_includes.append(files["serviceDeclaration"]) commands = copy(self.sortedCommands()) for command in commands: command.options["cpp_enum_name"] = commandEnumName(command.name) requests = [command for command in commands if issubclass(type(command), Request) and not is_deferred(command)] events = [command for command in commands if issubclass(type(command), Event)] async = [ (command.toRequest(), command.toEvent()) for command in commands if issubclass(type(command), Request) and is_deferred(command) ] requests += [req[0] for req in async] events += [req[1] for req in async] self.service.version = self.getVersion() import hob.proto self.commands = commands self.requests = requests self.events = events
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
def renderDeclaration(self, services): text = "" text += "\n" + render(""" // Includes #include "modules/scope/src/scope_service.h" // Includes for shared variables """) + "\n\n" for include in self.manager_options.includes: text += """#include "%s"\n""" % include text += "\n" + render(""" // Forward declarations """) + "\n\n" for service in services: if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true": if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += "class %(class)s;\n" % {"class": service.options["cpp_class"].value} if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += "\n" + render(""" // Interface definitions """) + "\n\n" for service in services: if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value} prefix = "g_scope_" basename = utils.join_underscore(utils.split_camelcase(service.name)) if "cpp_file" in service.options: basename = service.options["cpp_file"].value prefix = "g_" text += """# include "%(cpp_gen_base)s/%(file)s_interface.h"\n""" % { "file": prefix + basename, "cpp_gen_base": service.options["cpp_gen_base"].value, } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += "\n" + render(""" class OpScopeDescriptorSet; class OpScopeManager; class OpScopeServiceManager; /** * This is a generated class which defines all services which are use in scope. * It provides methods for registering meta-services as well as creating all * service objects. * In addition it keeps an instance of the OpScopeDescriptorSet class, this is * used to provide descriptor objects for messages in each service. * * This class is meant to be sub-classed into a real scope manager. The sub-class * must call RegisterMetaService() to register meta-services, and then call * CreateServices() and CreateServiceDescriptors() at a convenient time to * initialize the class properly. * * @note This class is generated. */ class OpScopeServiceFactory { public: /** * Initializes the generated manager with all service pointers set to NULL. */ OpScopeServiceFactory(); /** * Deletes all active services and the descriptor set. */ virtual ~OpScopeServiceFactory(); /** * Get a reference to the descriptor set. Can only be used * after a successful call to CreateServiceDescriptors. */ OpScopeDescriptorSet &GetDescriptorSet(); /** * Add a new meta-service named @a name. Meta-services are services * which have no functionality, no version and cannot be introspected. * * The actual service will be created when CreateServices() is called * by a sub-class. Adding a meta-service after that point will have no * effect. * * If the meta-service has already been registered it will return OpStatus::ERR. * * @param name The name of the meta-service. * @return OpStatus::OK, OpStatus::ERR or OpStatus::ERR_NO_MEMORY * */ OP_STATUS RegisterMetaService(const uni_char *name); /** * @see RegisterMetaService(const uni_char *name); */ OP_STATUS RegisterMetaService(const OpString &name) { return RegisterMetaService(name.CStr()); } protected: /** * Creates all services. * * @param manager The manager that owns the services. * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise. */ OP_STATUS CreateServices(OpScopeServiceManager *manager); /** * Deletes all services. No more events will be accepted from Core * after this method is called, even events triggered by service * destruction. */ void DeleteServices(); /** * Create service descriptions. * * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise. */ OP_STATUS CreateServiceDescriptors(); public: OpScopeDescriptorSet *descriptors; // Services: """) + "\n\n" for service in services: if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true": if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += " %(class)s *%(name)s;\n" % { "class": service.options["cpp_class"].value, "name": self.memberName(service.name), } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += "\n" + render(""" private: /** * Defines the name of a meta-service and manages the service object. * The meta-service is first initailized with a name and later on in the * CreateServices() a service object is created and placed in service. * When the MetaService is destructed it will delete the service object. */ struct MetaService : public ListElement<MetaService> { MetaService() : service(NULL) {} ~MetaService() { OP_DELETE(service); } OpString name; OpScopeService *service; }; /** * List of meta-services currently registered. */ List<MetaService> meta_services; // NOTE: These two methods are meant to be manually created outside of these classes // See modules/scope/src/scope_manager.cpp for the implementation /** * Initializes any shared member variables, called before the services are created. */ OP_STATUS InitializeShared(); /** * Cleans up the shared member variables, called after the services has been deleted. */ void CleanupShared(); // Shared member variables. See cpp.conf for more information. """) + "\n" for field in self.manager_options.shared_fields: text += " %s;\n" % field text += render(""" }; // OpScopeServiceFactory /** * Contains the descriptors of all services in use by scope. * * @note This class is generated. */ class OpScopeDescriptorSet { public: OpScopeDescriptorSet(); ~OpScopeDescriptorSet(); OP_STATUS Construct(); private: // Not really used for anything, except to prevent errors on certain // compile configurations. int dummy; public: """) + "\n" for service in services: if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += " %(class)s_SI::Descriptors *%(name)s;\n" % { "class": service.options["cpp_class"].value, "name": self.varName(service.name), } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value} text += "\n" + render(""" }; // OpScopeDescriptorSet """) + "\n" return text
def renderDeclaration(self, services): text = "" text += "\n" + render(""" // Includes #include "modules/scope/src/scope_service.h" // Includes for shared variables """) + "\n\n" for include in self.manager_options.includes: text += """#include "%s"\n""" % include text += "\n" + render(""" // Forward declarations """) + "\n\n" for service in services: if "cpp_instance" not in service.options or service.options[ "cpp_instance"].value == "true": if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += "class %(class)s;\n" % { "class": service.options["cpp_class"].value } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += "\n" + render(""" // Interface definitions """) + "\n\n" for service in services: if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % { "feature": service.options["cpp_feature"].value } prefix = "g_scope_" basename = utils.join_underscore( utils.split_camelcase(service.name)) if "cpp_file" in service.options: basename = service.options["cpp_file"].value prefix = "g_" text += """# include "%(cpp_gen_base)s/%(file)s_interface.h"\n""" % { "file": prefix + basename, "cpp_gen_base": service.options["cpp_gen_base"].value, } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += "\n" + render(""" class OpScopeDescriptorSet; class OpScopeManager; class OpScopeServiceManager; /** * This is a generated class which defines all services which are use in scope. * It provides methods for registering meta-services as well as creating all * service objects. * In addition it keeps an instance of the OpScopeDescriptorSet class, this is * used to provide descriptor objects for messages in each service. * * This class is meant to be sub-classed into a real scope manager. The sub-class * must call RegisterMetaService() to register meta-services, and then call * CreateServices() and CreateServiceDescriptors() at a convenient time to * initialize the class properly. * * @note This class is generated. */ class OpScopeServiceFactory { public: /** * Initializes the generated manager with all service pointers set to NULL. */ OpScopeServiceFactory(); /** * Deletes all active services and the descriptor set. */ virtual ~OpScopeServiceFactory(); /** * Get a reference to the descriptor set. Can only be used * after a successful call to CreateServiceDescriptors. */ OpScopeDescriptorSet &GetDescriptorSet(); /** * Add a new meta-service named @a name. Meta-services are services * which have no functionality, no version and cannot be introspected. * * The actual service will be created when CreateServices() is called * by a sub-class. Adding a meta-service after that point will have no * effect. * * If the meta-service has already been registered it will return OpStatus::ERR. * * @param name The name of the meta-service. * @return OpStatus::OK, OpStatus::ERR or OpStatus::ERR_NO_MEMORY * */ OP_STATUS RegisterMetaService(const uni_char *name); /** * @see RegisterMetaService(const uni_char *name); */ OP_STATUS RegisterMetaService(const OpString &name) { return RegisterMetaService(name.CStr()); } protected: /** * Creates all services. * * @param manager The manager that owns the services. * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise. */ OP_STATUS CreateServices(OpScopeServiceManager *manager); /** * Deletes all services. No more events will be accepted from Core * after this method is called, even events triggered by service * destruction. */ void DeleteServices(); /** * Create service descriptions. * * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise. */ OP_STATUS CreateServiceDescriptors(); public: OpScopeDescriptorSet *descriptors; // Services: """) + "\n\n" for service in services: if "cpp_instance" not in service.options or service.options[ "cpp_instance"].value == "true": if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += " %(class)s *%(name)s;\n" % { "class": service.options["cpp_class"].value, "name": self.memberName(service.name), } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += "\n" + render(""" private: /** * Defines the name of a meta-service and manages the service object. * The meta-service is first initailized with a name and later on in the * CreateServices() a service object is created and placed in service. * When the MetaService is destructed it will delete the service object. */ struct MetaService : public ListElement<MetaService> { MetaService() : service(NULL) {} ~MetaService() { OP_DELETE(service); } OpString name; OpScopeService *service; }; /** * List of meta-services currently registered. */ List<MetaService> meta_services; // NOTE: These two methods are meant to be manually created outside of these classes // See modules/scope/src/scope_manager.cpp for the implementation /** * Initializes any shared member variables, called before the services are created. */ OP_STATUS InitializeShared(); /** * Cleans up the shared member variables, called after the services has been deleted. */ void CleanupShared(); // Shared member variables. See cpp.conf for more information. """) + "\n" for field in self.manager_options.shared_fields: text += " %s;\n" % field text += render(""" }; // OpScopeServiceFactory /** * Contains the descriptors of all services in use by scope. * * @note This class is generated. */ class OpScopeDescriptorSet { public: OpScopeDescriptorSet(); ~OpScopeDescriptorSet(); OP_STATUS Construct(); private: // Not really used for anything, except to prevent errors on certain // compile configurations. int dummy; public: """) + "\n" for service in services: if "cpp_feature" in service.options: text += "#ifdef %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += " %(class)s_SI::Descriptors *%(name)s;\n" % { "class": service.options["cpp_class"].value, "name": self.varName(service.name), } if "cpp_feature" in service.options: text += "#endif // %(feature)s\n" % { "feature": service.options["cpp_feature"].value } text += "\n" + render(""" }; // OpScopeDescriptorSet """) + "\n" return text
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