45f601b33900b046104959911e1159b903794907
[tpg/acess2.git] / KernelLand / Modules / Interfaces / UDI / udi_lib / core / layout.c
1 /*
2  * Acess2 UDI Layer
3  * - By John Hodge (thePowersGang)
4  *
5  * udi_lib/core/layout.c
6  * - udi_layout_t related functions
7  */
8 #define DEBUG   1
9 #include <udi.h>
10 #include <acess.h>
11 #include <udi_internal.h>
12
13 // === CODE ===
14 #define alignto(ofs,type) \
15         ofs + ((sizeof(type)-ofs%sizeof(type)) % sizeof(type));
16 #define _PUT(type,vtype) do{\
17         ofs = alignto(ofs,type); \
18         if(buf){\
19                 *(type*)(buf+ofs) = va_arg(*values,vtype);\
20                 LOG(#type" %p %x", buf+ofs, *(type*)(buf+ofs));\
21         }\
22         else if(values) \
23                 va_arg(*values,vtype); \
24         ofs += sizeof(type); \
25 }while(0)
26
27 size_t _udi_marshal_step(void *buf, size_t cur_ofs, const udi_layout_t **layoutp, va_list *values)
28 {
29         size_t  ofs = cur_ofs;
30         const udi_layout_t      *layout = *layoutp;
31         switch(*layout++)
32         {
33         case UDI_DL_UBIT8_T:    _PUT(udi_ubit8_t, UDI_VA_UBIT8_T);      break;
34         case UDI_DL_SBIT8_T:    _PUT(udi_sbit8_t, UDI_VA_SBIT8_T);      break;
35         case UDI_DL_UBIT16_T:   _PUT(udi_ubit16_t, UDI_VA_UBIT16_T);    break;
36         case UDI_DL_SBIT16_T:   _PUT(udi_sbit16_t, UDI_VA_SBIT16_T);    break;
37         case UDI_DL_UBIT32_T:   _PUT(udi_ubit32_t, UDI_VA_UBIT32_T);    break;
38         case UDI_DL_SBIT32_T:   _PUT(udi_sbit32_t, UDI_VA_SBIT16_T);    break;
39         case UDI_DL_BOOLEAN_T:  _PUT(udi_boolean_t, UDI_VA_BOOLEAN_T);  break;
40         case UDI_DL_STATUS_T:   _PUT(udi_status_t, UDI_VA_STATUS_T);    break;
41         
42         case UDI_DL_INDEX_T:    _PUT(udi_index_t, UDI_VA_INDEX_T);      break;
43         
44         case UDI_DL_CHANNEL_T:  _PUT(udi_channel_t, UDI_VA_CHANNEL_T);  break;
45         case UDI_DL_ORIGIN_T:   _PUT(udi_origin_t, UDI_VA_ORIGIN_T);    break;
46
47         case UDI_DL_BUF:
48                 _PUT(udi_buf_t*,UDI_VA_POINTER);
49                 layout += 3;
50                 break;
51         case UDI_DL_CB:
52                 _PUT(udi_cb_t*,UDI_VA_POINTER);
53                 break;
54         case UDI_DL_INLINE_UNTYPED:
55                 _PUT(void*,UDI_VA_POINTER);
56                 break;
57         case UDI_DL_INLINE_DRIVER_TYPED:
58                 _PUT(void*,UDI_VA_POINTER);
59                 break;
60         case UDI_DL_MOVABLE_UNTYPED:
61                 _PUT(void*,UDI_VA_POINTER);
62                 break;
63         
64         case UDI_DL_INLINE_TYPED:
65         case UDI_DL_MOVABLE_TYPED:
66                 _PUT(void*,UDI_VA_POINTER);
67                 while(*layout++ != UDI_DL_END)
68                         ;
69                 break;
70
71         default:
72                 Log_Error("UDI", "_udi_marshal_step - Unknown layout code %i", layout[-1]);
73                 return 0;
74         }
75         *layoutp = layout;
76         return ofs;
77 }
78
79 size_t _udi_marshal_values(void *buf, const udi_layout_t *layout, va_list values)
80 {
81         size_t  ofs = 0;
82         while( *layout != UDI_DL_END )
83         {
84                 ofs = _udi_marshal_step(buf, ofs, &layout, &values);
85                 if( ofs == 0 )
86                         return 0;
87         }
88         return ofs;
89 }

UCC git Repository :: git.ucc.asn.au