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.timezone.location.tools.dump; 18 19 import com.android.timezone.location.storage.util.Visitor; 20 21 import java.io.File; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.OutputStreamWriter; 25 import java.io.PrintWriter; 26 import java.nio.charset.StandardCharsets; 27 28 /** Helper methods for dumping data to files. */ 29 final class DumpUtils { 30 DumpUtils()31 private DumpUtils() { 32 } 33 createPrintWriter(File file)34 static PrintWriter createPrintWriter(File file) throws Visitor.VisitException { 35 try { 36 OutputStreamWriter utf8Writer = new OutputStreamWriter( 37 new FileOutputStream(file), StandardCharsets.UTF_8); 38 return new PrintWriter(utf8Writer); 39 } catch (IOException e) { 40 throw new Visitor.VisitException(e); 41 } 42 } 43 generateDumpFile(File dir, String filePrefix, int blockId, int maxBlockId)44 static File generateDumpFile(File dir, String filePrefix, int blockId, int maxBlockId) { 45 final String fileSuffix = ".txt"; 46 47 int blockIdLength = hexStringLength(maxBlockId); 48 StringBuilder sb = new StringBuilder( 49 filePrefix.length() + blockIdLength + fileSuffix.length()); 50 sb.append(filePrefix); 51 52 String blockIdHex = zeroPadHex(blockIdLength, blockId); 53 sb.append(blockIdHex); 54 sb.append(fileSuffix); 55 return new File(dir, sb.toString()); 56 } 57 hexStringLength(int value)58 static int hexStringLength(int value) { 59 int bitsNeeded = Integer.SIZE - Integer.numberOfLeadingZeros(value); 60 return (bitsNeeded + 3) / 4; 61 } 62 binaryStringLength(int value)63 static int binaryStringLength(int value) { 64 return Integer.SIZE - Integer.numberOfLeadingZeros(value); 65 } 66 zeroPadHex(int length, int value)67 static String zeroPadHex(int length, int value) { 68 String hexString = Integer.toHexString(value); 69 int unpaddedLength = hexString.length(); 70 if (unpaddedLength >= length) { 71 return hexString; 72 } 73 return zeroPad(length, hexString); 74 } 75 zeroPadBinary(int length, int value)76 static String zeroPadBinary(int length, int value) { 77 String binaryString = Integer.toBinaryString(value); 78 int unpaddedLength = binaryString.length(); 79 if (unpaddedLength >= length) { 80 return binaryString; 81 } 82 return zeroPad(length, binaryString); 83 } 84 zeroPad(int length, String unpaddedValue)85 private static String zeroPad(int length, String unpaddedValue) { 86 StringBuilder sb = new StringBuilder(length); 87 int zeroPadding = length - unpaddedValue.length(); 88 for (int i = 0; i < zeroPadding; i++) { 89 sb.append('0'); 90 } 91 sb.append(unpaddedValue); 92 return sb.toString(); 93 } 94 } 95