~mir-team/mir/in-process-egl+input-conglomeration

« back to all changes in this revision

Viewing changes to 3rd_party/android-input/android_pristine/frameworks/native/libs/utils/Debug.cpp

Merged trunk and fixed issues

Show diffs side-by-side

added added

removed removed

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