1/*
2 * layout_dump.c -
3 *
4 * Written by Eryk Vershen
5 */
6
7/*
8 * Copyright 1996,1997 by Apple Computer, Inc.
9 *              All Rights Reserved
10 *
11 * Permission to use, copy, modify, and distribute this software and
12 * its documentation for any purpose and without fee is hereby granted,
13 * provided that the above copyright notice appears in all copies and
14 * that both the copyright notice and this permission notice appear in
15 * supporting documentation.
16 *
17 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE.
20 *
21 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
22 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
24 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
25 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 */
27
28// for printf()
29#include <stdio.h>
30// for strlen()
31#include <string.h>
32#include <inttypes.h>
33#include "layout_dump.h"
34
35
36/*
37 * Defines
38 */
39
40
41/*
42 * Types
43 */
44
45
46/*
47 * Global Constants
48 */
49uint8_t bitmasks[] = {
50    0x01, 0x03, 0x07, 0x0F,
51    0x1F, 0x3F, 0x7F, 0xFF
52};
53
54
55/*
56 * Global Variables
57 */
58
59
60/*
61 * Forward declarations
62 */
63
64
65/*
66 * Routines
67 */
68void
69dump_using_layout(void *buffer, layout *desc)
70{
71    layout *entry;
72    int byte_length;
73    long    value;
74    int max_name;
75    int i;
76
77    max_name = 0;
78    for (entry = desc; entry->format != kEnd; entry++) {
79	value = strlen(entry->name);
80	if (value > max_name) {
81	    max_name = value;
82	}
83    }
84
85
86    for (entry = desc; entry->format != kEnd; entry++) {
87
88	if (entry->format != kBit) {
89	    printf("%*s: ", max_name, entry->name);
90
91	    byte_length = entry->bit_length / 8;
92
93	    if (entry->bit_offset != 0 || (entry->bit_length % 8) != 0) {
94		printf("entry %d, can't handle bitfields yet.\n", (int)(entry - desc));
95		continue;
96	    }
97
98	    value = 0;
99	    for (i = entry->byte_offset; byte_length > 0;i++) {
100		value = value << 8;
101		value |= ((uint8_t *)buffer)[i];
102		byte_length--;
103	    }
104	} else {
105	    if (entry->bit_offset < 0 || entry->bit_offset > 8) {
106		printf("entry %d, bad bit offset (%d).\n", (int)(entry - desc), entry->bit_offset);
107		continue;
108	    } else if (entry->bit_length <= 0
109		    || entry->bit_length > (entry->bit_offset + 1)) {
110		printf("entry %d, bad bit length (%d,%d).\n", (int)(entry - desc),
111			entry->bit_offset, entry->bit_length);
112		continue;
113	    }
114	    value = (((uint8_t *)buffer)[entry->byte_offset]
115		    & bitmasks[entry->bit_offset])
116		    >> ((entry->bit_offset + 1) - entry->bit_length);
117	}
118
119	switch (entry->format) {
120	case kHex:
121	    printf("0x%x\n", (uint32_t) value);
122	    break;
123	case kDec:
124	    byte_length = entry->bit_length / 8;
125	    switch (byte_length) {
126	    case 4: printf("%"PRId32"\n", (int32_t)value); break;
127	    case 2: printf("%"PRId16"\n", (int16_t)value); break;
128	    case 1: printf("%"PRId8"\n", (int8_t)value); break;
129	    }
130	    break;
131	case kUns:
132	    byte_length = entry->bit_length / 8;
133	    switch (byte_length) {
134	    case 4: printf("%"PRIu32"\n", (uint32_t)value); break;
135	    case 2: printf("%"PRIu16"\n", (uint16_t)value); break;
136	    case 1: printf("%"PRIu8"\n", (uint8_t)value); break;
137	    }
138	    break;
139	case kBit:
140	    if (value) {
141		printf("%*s  %s\n", max_name, "", entry->name);
142	    }
143	    break;
144	default:
145	    printf("entry %d, unknown format (%d).\n", (int)(entry - desc), entry->format);
146	    break;
147	}
148    }
149}
150
151
152void
153DumpRawBuffer(uint8_t *bufferPtr, int length )
154{
155	register int            i;
156	int                     lineStart;
157	int                     lineLength;
158	short                   c;
159
160#define kLineSize   16
161	for (lineStart = 0; lineStart < length; lineStart += lineLength) {
162	    lineLength = kLineSize;
163	    if (lineStart + lineLength > length)
164		lineLength = length - lineStart;
165	    printf("%03x %3d:", lineStart, lineStart);
166	    for (i = 0; i < lineLength; i++)
167		printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
168	    for (; i < kLineSize; i++)
169		printf("   ");
170	    printf("  ");
171	    for (i = 0; i < lineLength; i++) {
172		c = bufferPtr[lineStart + i] & 0xFF;
173		if (c > ' ' && c < '~')
174		    printf("%c", c);
175		else {
176		    printf(".");
177		}
178	    }
179	    printf("\n");
180	}
181}
182