00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <adt/hash_table.h>
00038
00039 #include "trace.h"
00040 #include "proto.h"
00041
00042 #define SRV_PROTO_TABLE_CHAINS 32
00043 #define METHOD_OPER_TABLE_CHAINS 32
00044
00045 hash_table_t srv_proto;
00046
00047 typedef struct {
00048 unsigned srv;
00049 proto_t *proto;
00050 link_t link;
00051 } srv_proto_t;
00052
00053 typedef struct {
00054 sysarg_t method;
00055 oper_t *oper;
00056 link_t link;
00057 } method_oper_t;
00058
00059 static hash_index_t srv_proto_hash(unsigned long key[]);
00060 static int srv_proto_compare(unsigned long key[], hash_count_t keys,
00061 link_t *item);
00062 static void srv_proto_remove_callback(link_t *item);
00063
00064 hash_table_operations_t srv_proto_ops = {
00065 .hash = srv_proto_hash,
00066 .compare = srv_proto_compare,
00067 .remove_callback = srv_proto_remove_callback
00068 };
00069
00070 static hash_index_t method_oper_hash(unsigned long key[]);
00071 static int method_oper_compare(unsigned long key[], hash_count_t keys,
00072 link_t *item);
00073 static void method_oper_remove_callback(link_t *item);
00074
00075 hash_table_operations_t method_oper_ops = {
00076 .hash = method_oper_hash,
00077 .compare = method_oper_compare,
00078 .remove_callback = method_oper_remove_callback
00079 };
00080
00081 static hash_index_t srv_proto_hash(unsigned long key[])
00082 {
00083 return key[0] % SRV_PROTO_TABLE_CHAINS;
00084 }
00085
00086 static int srv_proto_compare(unsigned long key[], hash_count_t keys,
00087 link_t *item)
00088 {
00089 srv_proto_t *sp;
00090
00091 sp = hash_table_get_instance(item, srv_proto_t, link);
00092
00093 return key[0] == sp->srv;
00094 }
00095
00096 static void srv_proto_remove_callback(link_t *item)
00097 {
00098 }
00099
00100 static hash_index_t method_oper_hash(unsigned long key[])
00101 {
00102 return key[0] % METHOD_OPER_TABLE_CHAINS;
00103 }
00104
00105 static int method_oper_compare(unsigned long key[], hash_count_t keys,
00106 link_t *item)
00107 {
00108 method_oper_t *mo;
00109
00110 mo = hash_table_get_instance(item, method_oper_t, link);
00111
00112 return key[0] == mo->method;
00113 }
00114
00115 static void method_oper_remove_callback(link_t *item)
00116 {
00117 }
00118
00119
00120 void proto_init(void)
00121 {
00122 hash_table_create(&srv_proto, SRV_PROTO_TABLE_CHAINS, 1,
00123 &srv_proto_ops);
00124 }
00125
00126 void proto_cleanup(void)
00127 {
00128 hash_table_destroy(&srv_proto);
00129 }
00130
00131 void proto_register(int srv, proto_t *proto)
00132 {
00133 srv_proto_t *sp;
00134 unsigned long key;
00135
00136 sp = malloc(sizeof(srv_proto_t));
00137 sp->srv = srv;
00138 sp->proto = proto;
00139 key = srv;
00140
00141 hash_table_insert(&srv_proto, &key, &sp->link);
00142 }
00143
00144 proto_t *proto_get_by_srv(int srv)
00145 {
00146 unsigned long key;
00147 link_t *item;
00148 srv_proto_t *sp;
00149
00150 key = srv;
00151 item = hash_table_find(&srv_proto, &key);
00152 if (item == NULL) return NULL;
00153
00154 sp = hash_table_get_instance(item, srv_proto_t, link);
00155 return sp->proto;
00156 }
00157
00158 static void proto_struct_init(proto_t *proto, const char *name)
00159 {
00160 proto->name = name;
00161 hash_table_create(&proto->method_oper, SRV_PROTO_TABLE_CHAINS, 1,
00162 &method_oper_ops);
00163 }
00164
00165 proto_t *proto_new(const char *name)
00166 {
00167 proto_t *p;
00168
00169 p = malloc(sizeof(proto_t));
00170 proto_struct_init(p, name);
00171
00172 return p;
00173 }
00174
00175 void proto_delete(proto_t *proto)
00176 {
00177 free(proto);
00178 }
00179
00180 void proto_add_oper(proto_t *proto, int method, oper_t *oper)
00181 {
00182 method_oper_t *mo;
00183 unsigned long key;
00184
00185 mo = malloc(sizeof(method_oper_t));
00186 mo->method = method;
00187 mo->oper = oper;
00188 key = method;
00189
00190 hash_table_insert(&proto->method_oper, &key, &mo->link);
00191 }
00192
00193 oper_t *proto_get_oper(proto_t *proto, int method)
00194 {
00195 unsigned long key;
00196 link_t *item;
00197 method_oper_t *mo;
00198
00199 key = method;
00200 item = hash_table_find(&proto->method_oper, &key);
00201 if (item == NULL) return NULL;
00202
00203 mo = hash_table_get_instance(item, method_oper_t, link);
00204 return mo->oper;
00205 }
00206
00207 static void oper_struct_init(oper_t *oper, const char *name)
00208 {
00209 oper->name = name;
00210 }
00211
00212 oper_t *oper_new(const char *name, int argc, val_type_t *arg_types,
00213 val_type_t rv_type, int respc, val_type_t *resp_types)
00214 {
00215 oper_t *o;
00216 int i;
00217
00218 o = malloc(sizeof(oper_t));
00219 oper_struct_init(o, name);
00220
00221 o->argc = argc;
00222 for (i = 0; i < argc; i++)
00223 o->arg_type[i] = arg_types[i];
00224
00225 o->rv_type = rv_type;
00226
00227 o->respc = respc;
00228 for (i = 0; i < respc; i++)
00229 o->resp_type[i] = resp_types[i];
00230
00231 return o;
00232 }
00233