Commit a8197488 authored by lahiker42's avatar lahiker42

- fixin up services

- beginnings of simplerpc system


git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@45 00440858-1255-0410-a3e6-75ea37f81c3a
parent f87e0849
......@@ -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)
{
/* 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;
void
protobuf_c_service_generated_init (ProtobufCService *service,
const ProtobufCServiceDescriptor *descriptor,
ProtobufCServiceDestroy destroy)
{
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_;
......
#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)
{
...
}
#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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment