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_MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
|
||||
#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 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 --- */
|
||||
|
||||
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;
|
||||
size_t rv = 0;
|
||||
ASSERT_IS_MESSAGE (message);
|
||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||
{
|
||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||
@ -662,6 +672,7 @@ size_t protobuf_c_message_pack (const ProtobufCMessage *message,
|
||||
{
|
||||
unsigned i;
|
||||
size_t rv = 0;
|
||||
ASSERT_IS_MESSAGE (message);
|
||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||
{
|
||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||
@ -839,6 +850,7 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
||||
{
|
||||
unsigned i;
|
||||
size_t rv = 0;
|
||||
ASSERT_IS_MESSAGE (message);
|
||||
for (i = 0; i < message->descriptor->n_fields; i++)
|
||||
{
|
||||
const ProtobufCFieldDescriptor *field = message->descriptor->fields + i;
|
||||
@ -1266,6 +1278,8 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
unsigned f;
|
||||
unsigned i_slab;
|
||||
|
||||
ASSERT_IS_MESSAGE_DESCRIPTOR (desc);
|
||||
|
||||
if (allocator == NULL)
|
||||
allocator = &protobuf_c_default_allocator;
|
||||
rv = ALLOC (allocator, desc->sizeof_message);
|
||||
@ -1455,8 +1469,10 @@ protobuf_c_message_free_unpacked (ProtobufCMessage *message,
|
||||
{
|
||||
const ProtobufCMessageDescriptor *desc = message->descriptor;
|
||||
unsigned f;
|
||||
ASSERT_IS_MESSAGE (message);
|
||||
if (allocator == NULL)
|
||||
allocator = &protobuf_c_default_allocator;
|
||||
message->descriptor = NULL;
|
||||
for (f = 0; f < desc->n_fields; f++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
static void
|
||||
service_machgen_destroy (ProtobufCService *service)
|
||||
void
|
||||
protobuf_c_service_generated_init (ProtobufCService *service,
|
||||
const ProtobufCServiceDescriptor *descriptor,
|
||||
ProtobufCServiceDestroy destroy)
|
||||
{
|
||||
/* destroy function always follows the methods.
|
||||
we assume these function pointers are the same size. */
|
||||
DestroyHandler *handlers;
|
||||
DestroyHandler handler;
|
||||
ServiceMachgen *machgen = (ServiceMachgen *) service;
|
||||
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;
|
||||
ASSERT_IS_SERVICE_DESCRIPTOR(descriptor);
|
||||
service->descriptor = descriptor;
|
||||
service->destroy = destroy;
|
||||
service->invoke = service_machgen_invoke;
|
||||
memset (service + 1, 0, descriptor->n_methods * sizeof (GenericHandler));
|
||||
}
|
||||
|
||||
void protobuf_c_service_destroy (ProtobufCService *service)
|
||||
|
@ -205,12 +205,11 @@ struct _ProtobufCService
|
||||
void (*destroy) (ProtobufCService *service);
|
||||
};
|
||||
|
||||
ProtobufCService *protobuf_c_create_service_from_vfuncs
|
||||
(const ProtobufCServiceDescriptor *descriptor,
|
||||
void *service);
|
||||
|
||||
void protobuf_c_service_destroy (ProtobufCService *);
|
||||
|
||||
|
||||
|
||||
/* --- wire format enums --- */
|
||||
typedef enum
|
||||
{
|
||||
|
@ -36,6 +36,7 @@ ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor,
|
||||
vars_["fullname"] = descriptor_->full_name();
|
||||
vars_["cname"] = FullNameToC(descriptor_->full_name());
|
||||
vars_["lcfullname"] = FullNameToLower(descriptor_->full_name());
|
||||
vars_["lcfullpadd"] = ConvertToSpaces(vars_["lcfullname"]);
|
||||
vars_["package"] = descriptor_->file()->package();
|
||||
if (dllexport_decl.empty()) {
|
||||
vars_["dllexport"] = "";
|
||||
@ -58,7 +59,8 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
|
||||
printer->Print(vars_,
|
||||
"typedef struct _$cname$_Service $cname$_Service;\n"
|
||||
"struct _$cname$_Service\n"
|
||||
"{\n");
|
||||
"{\n"
|
||||
" ProtobufCService base;\n");
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
const MethodDescriptor *method = descriptor_->method(i);
|
||||
string lcname = CamelToLower(method->name());
|
||||
@ -72,10 +74,12 @@ void ServiceGenerator::GenerateVfuncs(io::Printer* printer)
|
||||
" $metpad$ $output_typename$_Closure closure,\n"
|
||||
" $metpad$ void *closure_data);\n");
|
||||
}
|
||||
printer->Print(vars_,
|
||||
" void (*destroy) ($cname$_Service *service);\n");
|
||||
printer->Print(vars_,
|
||||
"};\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)
|
||||
{
|
||||
@ -111,9 +115,21 @@ void ServiceGenerator::GenerateDescriptorDeclarations(io::Printer* printer)
|
||||
void ServiceGenerator::GenerateCFile(io::Printer* printer)
|
||||
{
|
||||
GenerateServiceDescriptor(printer);
|
||||
GenerateCreateService(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)
|
||||
{
|
||||
int n_methods = descriptor_->method_count();
|
||||
@ -141,14 +157,6 @@ void ServiceGenerator::GenerateServiceDescriptor(io::Printer* printer)
|
||||
"};\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)
|
||||
{
|
||||
for (int i = 0; i < descriptor_->method_count(); i++) {
|
||||
|
@ -56,7 +56,7 @@ class ServiceGenerator {
|
||||
// Source file stuff.
|
||||
void GenerateCFile(io::Printer* printer);
|
||||
void GenerateServiceDescriptor(io::Printer* printer);
|
||||
void GenerateCreateService(io::Printer* printer);
|
||||
void GenerateInit(io::Printer* printer);
|
||||
void GenerateCallersImplementations(io::Printer* printer);
|
||||
|
||||
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