19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Debug.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/misc.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ctype.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android {
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic const char indentStr[] =
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"                                                                            "
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project"                                                                            ";
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* stringForIndent(int32_t indentLevel)
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ssize_t off = sizeof(indentStr)-1-(indentLevel*2);
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return indentStr + (off < 0 ? 0 : off);
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void defaultPrintFunc(void* cookie, const char* txt)
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    printf("%s", txt);
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ---------------------------------------------------------------------
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline int isident(int c)
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return isalnum(c) || c == '_';
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline bool isasciitype(char c)
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if( c >= ' ' && c < 127 && c != '\'' && c != '\\' ) return true;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline char makehexdigit(uint32_t val)
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return "0123456789abcdef"[val&0xF];
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* appendhexnum(uint32_t val, char* out)
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for( int32_t i=28; i>=0; i-=4 ) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *out++ = makehexdigit( val>>i );
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out = 0;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return out;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic inline char makeupperhexdigit(uint32_t val)
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return "0123456789ABCDEF"[val&0xF];
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* appendupperhexnum(uint32_t val, char* out)
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for( int32_t i=28; i>=0; i-=4 ) {
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *out++ = makeupperhexdigit( val>>i );
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out = 0;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return out;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* appendcharornum(char c, char* out, bool skipzero = true)
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (skipzero && c == 0) return out;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (isasciitype(c)) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *out++ = c;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return out;
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out++ = '\\';
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out++ = 'x';
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out++ = makehexdigit(c>>4);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *out++ = makehexdigit(c);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return out;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic char* typetostring(uint32_t type, char* out,
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          bool fullContext = true,
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                          bool strict = false)
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* pos = out;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char c[4];
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    c[0] = (char)((type>>24)&0xFF);
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    c[1] = (char)((type>>16)&0xFF);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    c[2] = (char)((type>>8)&0xFF);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    c[3] = (char)(type&0xFF);
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool valid;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if( !strict ) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now even less strict!
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // valid = isasciitype(c[3]);
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        valid = true;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t i = 0;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool zero = true;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (valid && i<3) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c[i] == 0) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!zero) valid = false;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                zero = false;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                //if (!isasciitype(c[i])) valid = false;
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i++;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // if all zeros, not a valid type code.
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (zero) valid = false;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        valid = isident(c[3]) ? true : false;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t i = 0;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bool zero = true;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (valid && i<3) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (c[i] == 0) {
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!zero) valid = false;
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                zero = false;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!isident(c[i])) valid = false;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i++;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if( valid && (!fullContext || c[0] != '0' || c[1] != 'x') ) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if( fullContext ) *pos++ = '\'';
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = appendcharornum(c[0], pos);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = appendcharornum(c[1], pos);
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = appendcharornum(c[2], pos);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pos = appendcharornum(c[3], pos);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if( fullContext ) *pos++ = '\'';
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *pos = 0;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return pos;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if( fullContext ) {
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *pos++ = '0';
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *pos++ = 'x';
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return appendhexnum(type, pos);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid printTypeCode(uint32_t typeCode, debugPrintFunc func, void* cookie)
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buffer[32];
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* end = typetostring(typeCode, buffer);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *end = 0;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    func ? (*func)(cookie, buffer) : defaultPrintFunc(cookie, buffer);
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid printHexData(int32_t indent, const void *buf, size_t length,
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t bytesPerLine, int32_t singleLineBytesCutoff,
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t alignment, bool cStyle,
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    debugPrintFunc func, void* cookie)
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (alignment == 0) {
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (bytesPerLine >= 16) alignment = 4;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (bytesPerLine >= 8) alignment = 2;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else alignment = 1;
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (func == NULL) func = defaultPrintFunc;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    size_t offset;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    unsigned char *pos = (unsigned char *)buf;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (pos == NULL) {
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, "(NULL)");
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (length == 0) {
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, "(empty)");
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((int32_t)length < 0) {
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (singleLineBytesCutoff < 0) func(cookie, "\n");
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char buf[64];
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sprintf(buf, "(bad length: %d)", length);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, buf);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buffer[256];
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static const size_t maxBytesPerLine = (sizeof(buffer)-1-11-4)/(3+1);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bytesPerLine > maxBytesPerLine) bytesPerLine = maxBytesPerLine;
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const bool oneLine = (int32_t)length <= singleLineBytesCutoff;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool newLine = false;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cStyle) {
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        indent++;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, "{\n");
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newLine = true;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (!oneLine) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, "\n");
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newLine = true;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (offset = 0; ; offset += bytesPerLine, pos += bytesPerLine) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long remain = length;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* c = buffer;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!oneLine && !cStyle) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sprintf(c, "0x%08x: ", (int)offset);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c += 12;
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t index;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        size_t word;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (word = 0; word < bytesPerLine; ) {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_LITTLE_ENDIAN
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t startIndex = word+(alignment-(alignment?1:0));
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const ssize_t dir = -1;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const size_t startIndex = word;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            const ssize_t dir = 1;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!cStyle) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (index == 0 && word > 0 && alignment > 0) {
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = ' ';
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (remain-- > 0) {
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const unsigned char val = *(pos+startIndex+(index*dir));
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = makehexdigit(val>>4);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = makehexdigit(val);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if (!oneLine) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = ' ';
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = ' ';
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (remain > 0) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (index == 0 && word > 0) {
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            *c++ = ',';
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            *c++ = ' ';
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (index == 0) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            *c++ = '0';
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            *c++ = 'x';
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        const unsigned char val = *(pos+startIndex+(index*dir));
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = makehexdigit(val>>4);
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *c++ = makehexdigit(val);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        remain--;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            word += index;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!cStyle) {
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            remain = length;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *c++ = ' ';
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *c++ = '\'';
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (index = 0; index < bytesPerLine; index++) {
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (remain-- > 0) {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    const unsigned char val = pos[index];
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *c++ = (val >= ' ' && val < 127) ? val : '.';
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (!oneLine) {
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    *c++ = ' ';
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *c++ = '\'';
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (length > bytesPerLine) *c++ = '\n';
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (remain > 0) *c++ = ',';
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *c++ = '\n';
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (newLine && indent) func(cookie, stringForIndent(indent));
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *c = 0;
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, buffer);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        newLine = true;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (length <= bytesPerLine) break;
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        length -= bytesPerLine;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (cStyle) {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (indent > 0) func(cookie, stringForIndent(indent-1));
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        func(cookie, "};");
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319