Added AROS port of all shell applications:
[cake.git] / rom / utility / packstructuretags.c
blob70cd27a081a27ee883f0e7023ab6c6fbb36d58b8
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Pack a TagList into a structure.
6 Lang: english
7 */
8 #include "intern.h"
10 /*****************************************************************************
12 NAME */
13 #include <utility/tagitem.h>
14 #include <utility/pack.h>
15 #include <proto/utility.h>
17 AROS_LH3(ULONG, PackStructureTags,
19 /* SYNOPSIS */
20 AROS_LHA(APTR , pack, A0),
21 AROS_LHA(ULONG *, packTable, A1),
22 AROS_LHA(struct TagItem *, tagList, A2),
24 /* LOCATION */
25 struct Library *, UtilityBase, 35, Utility)
27 /* FUNCTION
28 This function will scan through the packTable, and for each TagItem
29 described in a packTable entry which can be found in the tagList,
30 the data in the TagItem's ti_Data field will be packed into the
31 structure as described in the packTable.
33 INPUTS
34 pack - The structure to fill in.
35 packTable - Table describing how to pack the structure.
36 See the include file utility/pack.h for
37 information on the format of this table.
38 tagList - List of TagItems containing data.
40 RESULT
41 The number of TagItems packed.
43 NOTES
45 EXAMPLE
47 BUGS
49 SEE ALSO
50 UnpackStructureTags()
52 INTERNALS
54 HISTORY
55 29-10-95 digulla automatically created from
56 utility_lib.fd and clib/utility_protos.h
58 *****************************************************************************/
60 AROS_LIBFUNC_INIT
62 Tag tagBase;
63 UWORD memOff;
64 UWORD tagOff;
65 UBYTE bitOff;
66 struct TagItem * ti;
67 LONG count = 0;
68 union memaccess * memptr;
71 tagBase = *packTable++;
72 for( ; *packTable != 0; packTable++)
74 /* New base tag */
75 if(*packTable == -1)
77 tagBase = *++packTable;
78 continue;
81 /* This entry is not defined for packing */
82 if((*packTable & PSTF_PACK)) continue;
84 tagOff = (*packTable >> 16) & 0x3FF;
86 /* Does the tag we are interested in exist in that list. */
87 ti = FindTagItem(tagBase + tagOff, tagList);
88 if(ti == NULL)
89 continue;
91 memOff = *packTable & 0x1FFF;
92 bitOff = (*packTable & 0xE000) >> 13;
94 memptr = (union memaccess *)((UBYTE *)pack + memOff);
97 If the PSTF_EXISTS bit is 1, then the tagexists says that we
98 set the bit to 1.
100 XXX: Have to see what happens when the Tag doesn't exist.
102 if((*packTable & (PKCTRL_BIT|PSTF_EXISTS)) == (PKCTRL_BIT|PSTF_EXISTS))
104 /* If the PSTF_SIGNED bit is 1, then this is actually FLIPBIT */
105 if(*packTable & PSTF_SIGNED)
106 memptr->ub &= ~(1 << bitOff);
107 else
108 memptr->ub |= (1 << bitOff);
110 count++;
111 continue;
115 The assigning is different for signed and unsigned since
116 ti_Data is not necessarily the same size as the structure field,
117 so we have to let the compiler do sign extension.
119 Bit shifting the packTable entry >> 24, we can do some more
120 instruction space efficient stuff.
122 This used to be done with horrible casting, but using a union
123 is much neater.
125 switch((*packTable >> 24) & 0x98)
127 case (PKCTRL_ULONG >> 24):
128 memptr->ul = ti->ti_Data;
129 break;
131 case (PKCTRL_UWORD >> 24):
132 memptr->uw = ti->ti_Data;
133 break;
135 case (PKCTRL_UBYTE >> 24):
136 memptr->ub = ti->ti_Data;
137 break;
139 case (PKCTRL_LONG >> 24):
140 memptr->sl = ti->ti_Data;
141 break;
143 case (PKCTRL_WORD >> 24):
144 memptr->sw = ti->ti_Data;
145 break;
147 case (PKCTRL_BYTE >> 24):
148 memptr->sb = ti->ti_Data;
149 break;
151 case (PKCTRL_BIT >> 24):
152 if(ti->ti_Data)
153 memptr->ub |= (1L << bitOff);
154 else
155 memptr->ub &= ~(1L << bitOff);
156 break;
158 case (PKCTRL_FLIPBIT >> 24):
159 if(ti->ti_Data)
160 memptr->ub &= ~(1L << bitOff);
161 else
162 memptr->ub |= (1L << bitOff);
163 break;
165 /* We didn't actually pack anything */
166 default:
167 count--;
168 } /* switch() */
169 count++;
170 } /* for() */
172 return count;
174 AROS_LIBFUNC_EXIT
175 } /* PackStructureTags */