1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "print_log.h"
17
18 #include <stdint.h>
19 #include <stdio.h>
20
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24
25 #define LINE_BYTE_COUNT 16
26 #define FORMAT_PRINT_BUFFER LOGD
27
28 #define CHAR_ZERO '0'
29 #define CHAR_A 'A'
30 #define NUM_ZERO 0
31 #define NUM_ONE 1
32 #define NUM_TWO 2
33 #define NUM_THREE 3
34 #define NUM_FOUR 4
35 #define NUM_NINE 9
36 #define NUM_TEN 10
37 #define NUM_FIFTEEN 15
38 #define HALF_BYTE_MASK 0x0F
39 #define NUM_PRINTABLE_BEGIN 0x20
40 #define NUM_PRINTABLE_END 0x7E
41 #define BITS_PER_BYTE 8
42 #define BITS_PER_HEX 4
43
Int2char(uint8_t c)44 static char Int2char(uint8_t c)
45 {
46 // c >= NUM_ZERO comparison is always true due to limited range of data type
47 if (c <= NUM_NINE) {
48 return (char)(c + CHAR_ZERO);
49 } else if (c >= NUM_TEN && c <= NUM_FIFTEEN) {
50 return (char)(c - NUM_TEN + CHAR_A);
51 } else {
52 return 0;
53 }
54 }
55
PrintLine(const uint8_t * ptr,int32_t len,uint32_t offset)56 static void PrintLine(const uint8_t *ptr, int32_t len, uint32_t offset)
57 {
58 int i;
59 char x1;
60 char x2;
61 char str[NUM_NINE + LINE_BYTE_COUNT * NUM_FOUR + NUM_ONE] = {0};
62 char *out = str + NUM_NINE;
63 uint32_t t;
64
65 for (i = 0; i < BITS_PER_BYTE; i++) {
66 t = offset << (i * BITS_PER_HEX);
67 t = t >> ((BITS_PER_BYTE - 1) * BITS_PER_HEX);
68 str[i] = Int2char(t);
69 }
70 str[BITS_PER_BYTE] = ' ';
71 for (i = 0; i < len; i++) {
72 uint8_t c = ptr[i];
73 x1 = Int2char(c >> NUM_FOUR);
74 x2 = Int2char(c & HALF_BYTE_MASK);
75 out[i * NUM_THREE] = x1;
76 out[i * NUM_THREE + NUM_ONE] = x2;
77 out[i * NUM_THREE + NUM_TWO] = ' ';
78 }
79 for (i = len; i < LINE_BYTE_COUNT; i++) {
80 out[i * NUM_THREE] = out[i * NUM_THREE + NUM_ONE] = out[i * NUM_THREE + NUM_TWO] = ' ';
81 }
82 for (i = 0; i < len; i++) {
83 if (ptr[i] >= NUM_PRINTABLE_BEGIN && ptr[i] <= NUM_PRINTABLE_END) {
84 out[LINE_BYTE_COUNT * NUM_THREE + i] = ptr[i];
85 } else {
86 out[LINE_BYTE_COUNT * NUM_THREE + i] = '.';
87 }
88 }
89 FORMAT_PRINT_BUFFER("%s", str);
90 }
91
PrintBuffer(const char * tag,const uint8_t * ptr,int32_t len)92 void PrintBuffer(const char *tag, const uint8_t *ptr, int32_t len)
93 {
94 int i = 0;
95 const uint8_t *linePtr = ptr;
96 uint32_t offset = 0;
97
98 FORMAT_PRINT_BUFFER("PrintBuffer tag = %s, len = %d, 0x%x", tag, len, len);
99 while (i < len) {
100 int currentLineByteCount = (int)(len - i);
101 if (currentLineByteCount >= LINE_BYTE_COUNT) {
102 PrintLine(linePtr, LINE_BYTE_COUNT, offset);
103 i += LINE_BYTE_COUNT;
104 } else {
105 PrintLine(linePtr, currentLineByteCount, offset);
106 i += currentLineByteCount;
107 }
108 linePtr += LINE_BYTE_COUNT;
109 offset += LINE_BYTE_COUNT;
110 }
111 }
112
113 #ifdef __cplusplus
114 }
115 #endif
116