1 /* 2 * Copyright (C) 2020 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 package com.android.server.soundtrigger_middleware; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.lang.reflect.Array; 23 import java.util.Collection; 24 import java.util.Map; 25 26 /** 27 * A collection of pretty-print utilities for data objects. 28 */ 29 class ObjectPrinter { 30 /** Default maximum elements to print in a collection. */ 31 static public final int kDefaultMaxCollectionLength = 16; 32 33 /** 34 * Pretty-prints an object. 35 * 36 * @param obj The object to print. 37 * @param maxCollectionLength Whenever encountering collections, maximum number of elements to 38 * print. 39 * @return A string representing the object. 40 */ print(@ullable Object obj, int maxCollectionLength)41 static String print(@Nullable Object obj, int maxCollectionLength) { 42 StringBuilder builder = new StringBuilder(); 43 print(builder, obj, maxCollectionLength); 44 return builder.toString(); 45 } 46 47 /** 48 * Same as {@link #print(StringBuilder, Object, int)} with default max length. 49 * 50 * @param builder StringBuilder to print into. 51 * @param obj The object to print. 52 */ print(@onNull StringBuilder builder, @Nullable Object obj)53 static void print(@NonNull StringBuilder builder, @Nullable Object obj) { 54 print(builder, obj, kDefaultMaxCollectionLength); 55 } 56 57 /** 58 * A version of {@link #print(Object, int)} that uses a {@link StringBuilder}. 59 * 60 * @param builder StringBuilder to print into. 61 * @param obj The object to print. 62 * @param maxCollectionLength Whenever encountering collections, maximum number of elements to 63 * print. 64 */ print(@onNull StringBuilder builder, @Nullable Object obj, int maxCollectionLength)65 static void print(@NonNull StringBuilder builder, @Nullable Object obj, 66 int maxCollectionLength) { 67 try { 68 if (obj == null) { 69 builder.append("null"); 70 return; 71 } 72 if (obj instanceof Boolean) { 73 builder.append(obj); 74 return; 75 } 76 if (obj instanceof Number) { 77 builder.append(obj); 78 return; 79 } 80 if (obj instanceof Character) { 81 builder.append('\''); 82 builder.append(obj); 83 builder.append('\''); 84 return; 85 } 86 if (obj instanceof String) { 87 builder.append('"'); 88 builder.append(obj.toString()); 89 builder.append('"'); 90 return; 91 } 92 93 Class cls = obj.getClass(); 94 95 if (Collection.class.isAssignableFrom(cls)) { 96 Collection collection = (Collection) obj; 97 builder.append("[ "); 98 int length = collection.size(); 99 boolean isLong = false; 100 int i = 0; 101 for (Object child : collection) { 102 if (i > 0) { 103 builder.append(", "); 104 } 105 if (i >= maxCollectionLength) { 106 isLong = true; 107 break; 108 } 109 print(builder, child, maxCollectionLength); 110 ++i; 111 } 112 if (isLong) { 113 builder.append("... (+"); 114 builder.append(length - maxCollectionLength); 115 builder.append(" entries)"); 116 } 117 builder.append(" ]"); 118 return; 119 } 120 121 if (Map.class.isAssignableFrom(cls)) { 122 Map<?, ?> map = (Map<?, ?>) obj; 123 builder.append("< "); 124 int length = map.size(); 125 boolean isLong = false; 126 int i = 0; 127 for (Map.Entry<?, ?> child : map.entrySet()) { 128 if (i > 0) { 129 builder.append(", "); 130 } 131 if (i >= maxCollectionLength) { 132 isLong = true; 133 break; 134 } 135 print(builder, child.getKey(), maxCollectionLength); 136 builder.append(": "); 137 print(builder, child.getValue(), maxCollectionLength); 138 ++i; 139 } 140 if (isLong) { 141 builder.append("... (+"); 142 builder.append(length - maxCollectionLength); 143 builder.append(" entries)"); 144 } 145 builder.append(" >"); 146 return; 147 } 148 149 if (cls.isArray()) { 150 builder.append("[ "); 151 int length = Array.getLength(obj); 152 boolean isLong = false; 153 for (int i = 0; i < length; ++i) { 154 if (i > 0) { 155 builder.append(", "); 156 } 157 if (i >= maxCollectionLength) { 158 isLong = true; 159 break; 160 } 161 print(builder, Array.get(obj, i), maxCollectionLength); 162 } 163 if (isLong) { 164 builder.append("... (+"); 165 builder.append(length - maxCollectionLength); 166 builder.append(" entries)"); 167 } 168 builder.append(" ]"); 169 return; 170 } 171 172 builder.append(obj); 173 } catch (Exception e) { 174 throw new RuntimeException(e); 175 } 176 } 177 } 178