mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-27 22:01:02 +08:00
- fixin up services
- beginnings of simplerpc system git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@45 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
parent
f87e0849ea
commit
a81974883a
@ -34,3 +34,11 @@ int protobuf_c_int_ranges_lookup (unsigned n_ranges,
|
|||||||
#define PROTOBUF_C_SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
|
#define PROTOBUF_C_SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
|
||||||
#define PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
|
#define PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
|
||||||
#define PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC 0x114315af
|
#define PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC 0x114315af
|
||||||
|
|
||||||
|
/* === behind the scenes on the generated service's __init functions */
|
||||||
|
typedef void (*ProtobufCServiceDestroy) (ProtobufCService *service);
|
||||||
|
void
|
||||||
|
protobuf_c_service_generated_init (ProtobufCService *service,
|
||||||
|
const ProtobufCServiceDescriptor *descriptor,
|
||||||
|
ProtobufCServiceDestroy destroy);
|
||||||
|
|
||||||
|
@ -35,6 +35,15 @@
|
|||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
|
||||||
|
#define ASSERT_IS_ENUM_DESCRIPTOR(desc) \
|
||||||
|
assert((desc)->magic == PROTOBUF_C_ENUM_DESCRIPTOR_MAGIC)
|
||||||
|
#define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \
|
||||||
|
assert((desc)->magic == PROTOBUF_C_MESSAGE_DESCRIPTOR_MAGIC)
|
||||||
|
#define ASSERT_IS_MESSAGE(message) \
|
||||||
|
ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor)
|
||||||
|
#define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \
|
||||||
|
assert((desc)->magic == PROTOBUF_C_SERVICE_DESCRIPTOR_MAGIC)
|
||||||
|
|
||||||
/* --- allocator --- */
|
/* --- allocator --- */
|
||||||
|
|
||||||
static void protobuf_c_out_of_memory_default (void)
|
static void protobuf_c_out_of_memory_default (void)
|
||||||
@ -354,6 +363,7 @@ size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
size_t rv = 0;
|
size_t rv = 0;
|
||||||
|
ASSERT_IS_MESSAGE (message);
|
||||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||||
{
|
{
|
||||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||||
@ -662,6 +672,7 @@ size_t protobuf_c_message_pack (const ProtobufCMessage *message,
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
size_t rv = 0;
|
size_t rv = 0;
|
||||||
|
ASSERT_IS_MESSAGE (message);
|
||||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||||
{
|
{
|
||||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||||
@ -839,6 +850,7 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
size_t rv = 0;
|
size_t rv = 0;
|
||||||
|
ASSERT_IS_MESSAGE (message);
|
||||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||||
{
|
{
|
||||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||||
@ -1266,6 +1278,8 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
|||||||
unsigned f;
|
unsigned f;
|
||||||
unsigned i_slab;
|
unsigned i_slab;
|
||||||
|
|
||||||
|
ASSERT_IS_MESSAGE_DESCRIPTOR (desc);
|
||||||
|
|
||||||
if (allocator == NULL)
|
if (allocator == NULL)
|
||||||
allocator = &protobuf_c_default_allocator;
|
allocator = &protobuf_c_default_allocator;
|
||||||
rv = ALLOC (allocator, desc->sizeof_message);
|
rv = ALLOC (allocator, desc->sizeof_message);
|
||||||
@ -1455,8 +1469,10 @@ protobuf_c_message_free_unpacked (ProtobufCMessage *message,
|
|||||||
{
|
{
|
||||||
const ProtobufCMessageDescriptor *desc = message->descriptor;
|
const ProtobufCMessageDescriptor *desc = message->descriptor;
|
||||||
unsigned f;
|
unsigned f;
|
||||||
|
ASSERT_IS_MESSAGE (message);
|
||||||
if (allocator == NULL)
|
if (allocator == NULL)
|
||||||
allocator = &protobuf_c_default_allocator;
|
allocator = &protobuf_c_default_allocator;
|
||||||
|
message->descriptor = NULL;
|
||||||
for (f = 0; f < desc->n_fields; f++)
|
for (f = 0; f < desc->n_fields; f++)
|
||||||
{
|
{
|
||||||
if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED)
|
if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED)
|
||||||
@ -1536,30 +1552,16 @@ service_machgen_invoke(ProtobufCService *service,
|
|||||||
(*handler) (machgen->service, input, closure, closure_data);
|
(*handler) (machgen->service, input, closure, closure_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
service_machgen_destroy (ProtobufCService *service)
|
protobuf_c_service_generated_init (ProtobufCService *service,
|
||||||
|
const ProtobufCServiceDescriptor *descriptor,
|
||||||
|
ProtobufCServiceDestroy destroy)
|
||||||
{
|
{
|
||||||
/* destroy function always follows the methods.
|
ASSERT_IS_SERVICE_DESCRIPTOR(descriptor);
|
||||||
we assume these function pointers are the same size. */
|
service->descriptor = descriptor;
|
||||||
DestroyHandler *handlers;
|
service->destroy = destroy;
|
||||||
DestroyHandler handler;
|
service->invoke = service_machgen_invoke;
|
||||||
ServiceMachgen *machgen = (ServiceMachgen *) service;
|
memset (service + 1, 0, descriptor->n_methods * sizeof (GenericHandler));
|
||||||
handlers = (DestroyHandler *) machgen->service;
|
|
||||||
handler = handlers[service->descriptor->n_methods];
|
|
||||||
(*handler) (machgen->service);
|
|
||||||
FREE (&protobuf_c_default_allocator, service);
|
|
||||||
}
|
|
||||||
ProtobufCService *
|
|
||||||
protobuf_c_create_service_from_vfuncs
|
|
||||||
(const ProtobufCServiceDescriptor *descriptor,
|
|
||||||
void *service)
|
|
||||||
{
|
|
||||||
ServiceMachgen *rv = ALLOC (&protobuf_c_default_allocator, sizeof (ServiceMachgen));
|
|
||||||
rv->base.descriptor = descriptor;
|
|
||||||
rv->base.invoke = service_machgen_invoke;
|
|
||||||
rv->base.destroy = service_machgen_destroy;
|
|
||||||
rv->service = service;
|
|
||||||
return &rv->base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void protobuf_c_service_destroy (ProtobufCService *service)
|
void protobuf_c_service_destroy (ProtobufCService *service)
|
||||||
|
@ -205,12 +205,11 @@ struct _ProtobufCService
|
|||||||
void (*destroy) (ProtobufCService *service);
|
void (*destroy) (ProtobufCService *service);
|
||||||
};
|
};
|
||||||
|
|
||||||
ProtobufCService *protobuf_c_create_service_from_vfuncs
|
|
||||||
(const ProtobufCServiceDescriptor *descriptor,
|
|
||||||
void *service);
|
|
||||||
void protobuf_c_service_destroy (ProtobufCService *);
|
void protobuf_c_service_destroy (ProtobufCService *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* --- wire format enums --- */
|
/* --- wire format enums --- */
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
|
|||||||
vars_["fullname"] = descriptor_->full_name();
|
vars_["fullname"] = descriptor_->full_name();
|
||||||
vars_["cname"] = FullNameToC(descriptor_->full_name());
|
vars_["cname"] = FullNameToC(descriptor_->full_name());
|
||||||
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name());
|
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name());
|
||||||
|
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
|
||||||
vars_["package"] = descriptor_->file()->package();
|
vars_["package"] = descriptor_->file()->package();
|
||||||
if (dllexport_decl.empty()) {
|
if (dllexport_decl.empty()) {
|
||||||
vars_["dllexport"] = "";
|
vars_["dllexport"] = "";
|
||||||
@ -58,7 +59,8 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
|
|||||||
printer->Print(vars_,
|
printer->Print(vars_,
|
||||||
"typedef struct _$cname$_Service $cname$_Service;\n"
|
"typedef struct _$cname$_Service $cname$_Service;\n"
|
||||||
"struct _$cname$_Service\n"
|
"struct _$cname$_Service\n"
|
||||||
"{\n");
|
"{\n"
|
||||||
|
" ProtobufCService base;\n");
|
||||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||||
const MethodDescriptor *method = descriptor_->method(i);
|
const MethodDescriptor *method = descriptor_->method(i);
|
||||||
string lcname = CamelToLower(method->name());
|
string lcname = CamelToLower(method->name());
|
||||||
@ -72,10 +74,12 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
|
|||||||
" $metpad$ $output_typename$_Closure closure,\n"
|
" $metpad$ $output_typename$_Closure closure,\n"
|
||||||
" $metpad$ void *closure_data);\n");
|
" $metpad$ void *closure_data);\n");
|
||||||
}
|
}
|
||||||
printer->Print(vars_,
|
|
||||||
" void (*destroy) ($cname$_Service *service);\n");
|
|
||||||
printer->Print(vars_,
|
printer->Print(vars_,
|
||||||
"};\n");
|
"};\n");
|
||||||
|
printer->Print(vars_,
|
||||||
|
"typedef void (*$cname$_ServiceDestroy)($cname$_Service);\n"
|
||||||
|
"void $lcfullname$__init ($cname$_Service *service,\n"
|
||||||
|
" $lcfullpadd$ $cname$_ServiceDestroy destroy);\n");
|
||||||
}
|
}
|
||||||
void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
|
void ServiceGenerator::GenerateCallersDeclarations(io::Printer* printer)
|
||||||
{
|
{
|
||||||
@ -111,9 +115,21 @@ void ServiceGenerator::GenerateDescriptorDeclarations(io::Printer* printer)
|
|||||||
void ServiceGenerator::GenerateCFile(io::Printer* printer)
|
void ServiceGenerator::GenerateCFile(io::Printer* printer)
|
||||||
{
|
{
|
||||||
GenerateServiceDescriptor(printer);
|
GenerateServiceDescriptor(printer);
|
||||||
GenerateCreateService(printer);
|
|
||||||
GenerateCallersImplementations(printer);
|
GenerateCallersImplementations(printer);
|
||||||
|
GenerateInit(printer);
|
||||||
}
|
}
|
||||||
|
void ServiceGenerator::GenerateInit(io::Printer* printer)
|
||||||
|
{
|
||||||
|
printer->Print(vars_,
|
||||||
|
"void $lcfullname$__init ($cname$_Service *service,\n"
|
||||||
|
" $lcfullpadd$ $cname$_ServiceDestroy destroy)\n"
|
||||||
|
"{\n"
|
||||||
|
" protobuf_c_service_generated_init (&service->base,\n"
|
||||||
|
" &$lcfullname$__descriptor,\n"
|
||||||
|
" (ProtobufCServiceDestroy) destroy);\n"
|
||||||
|
"}\n");
|
||||||
|
}
|
||||||
|
|
||||||
void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
|
void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
|
||||||
{
|
{
|
||||||
int n_methods = descriptor_->method_count();
|
int n_methods = descriptor_->method_count();
|
||||||
@ -141,14 +157,6 @@ void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
|
|||||||
"};\n");
|
"};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceGenerator::GenerateCreateService(io::Printer* printer)
|
|
||||||
{
|
|
||||||
printer->Print(vars_, "ProtobufCService *\n"
|
|
||||||
"$lcfullname$__create_service ($cname$_Service *service)\n"
|
|
||||||
"{\n"
|
|
||||||
" return protobuf_c_create_service_from_vfuncs (&$lcfullname$__descriptor, service);\n"
|
|
||||||
"}\n");
|
|
||||||
}
|
|
||||||
void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer)
|
void ServiceGenerator::GenerateCallersImplementations(io::Printer* printer)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||||
|
@ -56,7 +56,7 @@ class ServiceGenerator {
|
|||||||
// Source file stuff.
|
// Source file stuff.
|
||||||
void GenerateCFile(io::Printer* printer);
|
void GenerateCFile(io::Printer* printer);
|
||||||
void GenerateServiceDescriptor(io::Printer* printer);
|
void GenerateServiceDescriptor(io::Printer* printer);
|
||||||
void GenerateCreateService(io::Printer* printer);
|
void GenerateInit(io::Printer* printer);
|
||||||
void GenerateCallersImplementations(io::Printer* printer);
|
void GenerateCallersImplementations(io::Printer* printer);
|
||||||
|
|
||||||
const ServiceDescriptor* descriptor_;
|
const ServiceDescriptor* descriptor_;
|
||||||
|
89
src/simplerpc/simplerpc.c
Normal file
89
src/simplerpc/simplerpc.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include <gsk/gsk.h>
|
||||||
|
|
||||||
|
struct _SimplerpcServerStream
|
||||||
|
{
|
||||||
|
SimplerpcServer *server;
|
||||||
|
GskStream *connection;
|
||||||
|
GskBuffer incoming, outgoing;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _SimplerpcServer
|
||||||
|
{
|
||||||
|
GskStreamListener *listener;
|
||||||
|
GHashTable *domain_to_service;
|
||||||
|
guint ref_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static SimplerpcServer *
|
||||||
|
simplerpc_server_from_listener (GskStreamListener *listener)
|
||||||
|
{
|
||||||
|
SimplerpcServer *rv = g_slice_new (SimplerpcServer);
|
||||||
|
rv->listener = listener;
|
||||||
|
rv->ref_count = 1;
|
||||||
|
rv->domain_to_service = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
|
g_free,
|
||||||
|
protobuf_c_server_destroy);
|
||||||
|
gsk_stream_listener_handle_accept (listener, handle_accept,
|
||||||
|
handle_listener_error,
|
||||||
|
rv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplerpcServer *
|
||||||
|
simplerpc_bind_ipv4 (int tcp_port,
|
||||||
|
SimplerpcBindIpv4Flags flags,
|
||||||
|
ProtobufCError **error)
|
||||||
|
{
|
||||||
|
GskStreamListener *listener;
|
||||||
|
GskSocketAddress *addr;
|
||||||
|
const guint8 *ipaddr = (flags & SIMPLERPC_BIND_IPV4_LOCALHOST)
|
||||||
|
? gsk_ipv4_ip_address_localhost
|
||||||
|
: gsk_ipv4_ip_address_any;
|
||||||
|
addr = gsk_socket_address_new_ipv4 (ipaddr, tcp_port);
|
||||||
|
listener = gsk_stream_listener_socket_new_bind (addr, &ge);
|
||||||
|
if (listener == NULL)
|
||||||
|
{
|
||||||
|
set_protobuf_c_error_from_gerror (error, ge);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return simplerpc_server_from_listener (listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimplerpcServer *
|
||||||
|
simplerpc_bind_local (const char *path,
|
||||||
|
ProtobufCError **error)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
return simplerpc_server_from_listener (listener);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
simplerpc_add_service (SimplerpcServer *server,
|
||||||
|
const char *domain,
|
||||||
|
ProtobufCService *service)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
void
|
||||||
|
simplerpc_server_destroy (SimplerpcServer *server)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SimplerpcClient *
|
||||||
|
simplerpc_client_new_ipv4 (const uint8_t *ip_addr,
|
||||||
|
uint16_t port,
|
||||||
|
ProtobufCError **error)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtobufCService *
|
||||||
|
simplerpc_client_new_service (SimplerpcClient *client,
|
||||||
|
const char *domain,
|
||||||
|
const ProtobufCServiceDescriptor *descriptor,
|
||||||
|
ProtobufCError **error)
|
||||||
|
{
|
||||||
|
...
|
||||||
|
}
|
27
src/simplerpc/simplerpc.h
Normal file
27
src/simplerpc/simplerpc.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef __PROTOBUF_SIMPLERPC_H_
|
||||||
|
#ifndef __PROTOBUF_SIMPLERPC_H_
|
||||||
|
|
||||||
|
#include <google/protobuf-c/protobuf.h>
|
||||||
|
|
||||||
|
SimplerpcServer * simplerpc_bind_ipv4 (int tcp_port,
|
||||||
|
SimplerpcBindIpv4Flags flags,
|
||||||
|
ProtobufCError **error);
|
||||||
|
SimplerpcServer * simplerpc_bind_local (const char *path,
|
||||||
|
ProtobufCError **error);
|
||||||
|
void simplerpc_add_service (SimplerpcServer *server,
|
||||||
|
const char *domain,
|
||||||
|
ProtobufCService *service);
|
||||||
|
void simplerpc_server_destroy (SimplerpcServer *server);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SimplerpcClient *simplerpc_client_new_ipv4 (const uint8_t *ip_addr,
|
||||||
|
uint16_t port,
|
||||||
|
ProtobufCError **error);
|
||||||
|
|
||||||
|
ProtobufCService *simplerpc_client_new_service (SimplerpcClient *client,
|
||||||
|
const char *domain,
|
||||||
|
const ProtobufCServiceDescriptor *descriptor,
|
||||||
|
ProtobufCError **error);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user