Debug.cpp revision 0ae8c14b4b915b318250484eff9a18700cd934c3
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Debug.h>
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/misc.h>
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <ctype.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic const char indentStr[] =
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project"                                                                            "
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project"                                                                            ";
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectconst char* stringForIndent(int32_t indentLevel)
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return indentStr + (off < 0 ? 0 : off);
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void defaultPrintFunc(void* cookie, const char* txt)
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    printf("%s", txt);
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline int isident(int c)
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return isalnum(c) || c == '_';
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline bool isasciitype(char c)
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return false;
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline char makehexdigit(uint32_t val)
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return "0123456789abcdef"[val&0xF];
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* appendhexnum(uint32_t val, char* out)
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for( int32_t i=28; i>=0; i-=4 ) {
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *out++ = makehexdigit( val>>i );
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out = 0;
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return out;
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic inline char makeupperhexdigit(uint32_t val)
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return "0123456789ABCDEF"[val&0xF];
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* appendupperhexnum(uint32_t val, char* out)
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for( int32_t i=28; i>=0; i-=4 ) {
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *out++ = makeupperhexdigit( val>>i );
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out = 0;
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return out;
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* appendcharornum(char c, char* out, bool skipzero = true)
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (skipzero && c == 0) return out;
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (isasciitype(c)) {
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *out++ = c;
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return out;
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out++ = '\\';
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out++ = 'x';
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out++ = makehexdigit(c>>4);
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *out++ = makehexdigit(c);
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return out;
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic char* typetostring(uint32_t type, char* out,
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                          bool fullContext = true,
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                          bool strict = false)
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char* pos = out;
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char c[4];
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[0] = (char)((type>>24)&0xFF);
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[1] = (char)((type>>16)&0xFF);
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[2] = (char)((type>>8)&0xFF);
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[3] = (char)(type&0xFF);
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool valid;
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if( !strict ) {
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // now even less strict!
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // valid = isasciitype(c[3]);
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        valid = true;
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t i = 0;
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bool zero = true;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        while (valid && i<3) {
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c[i] == 0) {
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!zero) valid = false;
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                zero = false;
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                //if (!isasciitype(c[i])) valid = false;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            i++;
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        // if all zeros, not a valid type code.
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (zero) valid = false;
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else {
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        valid = isident(c[3]) ? true : false;
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        int32_t i = 0;
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        bool zero = true;
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        while (valid && i<3) {
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (c[i] == 0) {
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!zero) valid = false;
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            } else {
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                zero = false;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!isident(c[i])) valid = false;
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            i++;
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if( fullContext ) *pos++ = '\'';
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pos = appendcharornum(c[0], pos);
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pos = appendcharornum(c[1], pos);
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pos = appendcharornum(c[2], pos);
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        pos = appendcharornum(c[3], pos);
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if( fullContext ) *pos++ = '\'';
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *pos = 0;
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return pos;
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if( fullContext ) {
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *pos++ = '0';
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *pos++ = 'x';
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return appendhexnum(type, pos);
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[32];
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char* end = typetostring(typeCode, buffer);
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    *end = 0;
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid printHexData(int32_t indent, const void *buf, size_t length,
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t bytesPerLine, int32_t singleLineBytesCutoff,
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t alignment, bool cStyle,
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    debugPrintFunc func, void* cookie)
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (alignment == 0) {
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (bytesPerLine >= 16) alignment = 4;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else if (bytesPerLine >= 8) alignment = 2;
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        else alignment = 1;
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (func == NULL) func = defaultPrintFunc;
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    size_t offset;
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    unsigned char *pos = (unsigned char *)buf;
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (pos == NULL) {
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, "(NULL)");
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (length == 0) {
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, "(empty)");
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if ((int32_t)length < 0) {
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char buf[64];
2020ae8c14b4b915b318250484eff9a18700cd934c3Andrew Hsieh        sprintf(buf, "(bad length: %zu)", length);
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, buf);
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    char buffer[256];
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool newLine = false;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (cStyle) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        indent++;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, "{\n");
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        newLine = true;
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    } else if (!oneLine) {
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, "\n");
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        newLine = true;
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        long remain = length;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        char* c = buffer;
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!oneLine && !cStyle) {
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            sprintf(c, "0x%08x: ", (int)offset);
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            c += 12;
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        size_t index;
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        size_t word;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (word = 0; word < bytesPerLine; ) {
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#ifdef HAVE_LITTLE_ENDIAN
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const size_t startIndex = word+(alignment-(alignment?1:0));
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const ssize_t dir = -1;
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#else
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const size_t startIndex = word;
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            const ssize_t dir = 1;
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (!cStyle) {
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (index == 0 && word > 0 && alignment > 0) {
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = ' ';
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (remain-- > 0) {
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        const unsigned char val = *(pos+startIndex+(index*dir));
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = makehexdigit(val>>4);
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = makehexdigit(val);
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    } else if (!oneLine) {
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = ' ';
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = ' ';
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (remain > 0) {
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        if (index == 0 && word > 0) {
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            *c++ = ',';
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            *c++ = ' ';
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        }
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        if (index == 0) {
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            *c++ = '0';
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            *c++ = 'x';
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        }
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        const unsigned char val = *(pos+startIndex+(index*dir));
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = makehexdigit(val>>4);
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        *c++ = makehexdigit(val);
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        remain--;
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            word += index;
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (!cStyle) {
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            remain = length;
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            *c++ = ' ';
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            *c++ = '\'';
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (index = 0; index < bytesPerLine; index++) {
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (remain-- > 0) {
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    const unsigned char val = pos[index];
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *c++ = (val >= ' ' && val < 127) ? val : '.';
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else if (!oneLine) {
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    *c++ = ' ';
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            *c++ = '\'';
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (length > bytesPerLine) *c++ = '\n';
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (remain > 0) *c++ = ',';
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            *c++ = '\n';
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (newLine && indent) func(cookie, stringForIndent(indent));
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        *c = 0;
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, buffer);
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        newLine = true;
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (length <= bytesPerLine) break;
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        length -= bytesPerLine;
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (cStyle) {
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (indent > 0) func(cookie, stringForIndent(indent-1));
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        func(cookie, "};");
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319