proto.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 

Generated on Thu Jun 2 07:45:43 2011 for HelenOS/USB by  doxygen 1.4.7