Top level make file improvements and simplifications.
[AROS.git] / rom / utility / unpackstructuretags.c
blobdab065d325753f2a601b43f00a6d45c172c1384d
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: UnpackStructureTags - unpack structure to values in TagList.
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, UnpackStructureTags,
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, 36, Utility)
27 /* FUNCTION
28 For each table entry, if the matching tag is found in the tagList,
29 then the data in the structure will be placed in the memory pointed
30 to by the tags ti_Data.
32 Note: The value contained in ti_Data must be a *POINTER* to a
33 IPTR.
35 INPUTS
36 pack - Pointer to the memory area to be unpacked.
37 packTable - Table describing the unpacking operation.
38 See the include file <utility/pack.h> for
39 more information on this table.
40 tagList - List of TagItems to unpack into.
42 RESULT
43 The number of Tags unpacked.
45 NOTES
46 PSTF_EXISTS has no effect on this function.
48 EXAMPLE
50 BUGS
52 SEE ALSO
53 PackStructureTags(), FindTagItem()
55 INTERNALS
57 HISTORY
58 29-10-95 digulla automatically created from
59 utility_lib.fd and clib/utility_protos.h
61 *****************************************************************************/
63 AROS_LIBFUNC_INIT
65 Tag tagBase;
66 UWORD memOff;
67 UWORD tagOff;
68 UBYTE bitOff;
69 struct TagItem * ti;
70 LONG count = 0;
71 union memaccess * memptr;
73 tagBase = *packTable++;
74 for( ; *packTable != 0; packTable++)
76 /* New base tag */
77 if(*packTable == -1)
79 tagBase = *++packTable;
80 continue;
83 /* This entry is not defined for unpacking */
84 if((*packTable & PSTF_UNPACK)) continue;
86 tagOff = (*packTable >> 16) & 0x3FF;
88 /* Does the tag we are interested in exist in that list. */
89 ti = FindTagItem(tagBase + tagOff, tagList);
90 if(ti == NULL)
91 continue;
93 memOff = *packTable & 0x1FFF;
94 bitOff = (*packTable & 0xE000) >> 13;
95 memptr = (union memaccess *)((UBYTE *)pack + memOff);
98 The assigning is different for signed and unsigned since
99 ti_Data is not necessarily the same size as the structure field,
100 so we have to let the compiler do sign extension.
102 switch(*packTable & 0x98000000)
104 case PKCTRL_ULONG:
105 *(IPTR *)ti->ti_Data = (IPTR)memptr->ul;
106 break;
108 case PKCTRL_UWORD:
109 *(IPTR *)ti->ti_Data = (IPTR)memptr->uw;
110 break;
112 case PKCTRL_UBYTE:
113 *(IPTR *)ti->ti_Data = (IPTR)memptr->ub;
114 break;
116 case PKCTRL_LONG:
117 *(IPTR *)ti->ti_Data = (IPTR)memptr->sl;
118 break;
120 case PKCTRL_WORD:
121 *(IPTR *)ti->ti_Data = (IPTR)memptr->sw;
122 break;
124 case PKCTRL_BYTE:
125 *(IPTR *)ti->ti_Data = (IPTR)memptr->sb;
126 break;
128 case PKCTRL_BIT:
129 if( memptr->ub & (1 << bitOff) )
130 *(IPTR *)ti->ti_Data = TRUE;
131 else
132 *(IPTR *)ti->ti_Data = FALSE;
133 break;
135 case PKCTRL_FLIPBIT:
136 if( memptr->ub & (1 << bitOff) )
137 *(IPTR *)ti->ti_Data = FALSE;
138 else
139 *(IPTR *)ti->ti_Data = TRUE;
140 break;
142 /* We didn't actually pack anything */
143 default:
144 count--;
146 } /* switch() */
148 count++;
150 } /* for() */
152 return count;
154 AROS_LIBFUNC_EXIT
155 } /* UnpackStructureTags */