1 /* 2 * Copyright 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 android.media; 18 19 import android.system.ErrnoException; 20 import android.system.Os; 21 import android.util.Log; 22 23 import java.io.Closeable; 24 import java.io.FileDescriptor; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.io.OutputStream; 28 29 /** 30 * Package private utility class for ExifInterface. 31 */ 32 class ExifInterfaceUtils { 33 private static final String TAG = "ExifInterface"; 34 35 /** 36 * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed. 37 * Returns the total number of bytes transferred. 38 */ copy(InputStream in, OutputStream out)39 public static int copy(InputStream in, OutputStream out) throws IOException { 40 int total = 0; 41 byte[] buffer = new byte[8192]; 42 int c; 43 while ((c = in.read(buffer)) != -1) { 44 total += c; 45 out.write(buffer, 0, c); 46 } 47 return total; 48 } 49 50 /** 51 * Copies the given number of the bytes from {@code in} to {@code out}. Neither stream is 52 * closed. 53 */ copy(InputStream in, OutputStream out, int numBytes)54 public static void copy(InputStream in, OutputStream out, int numBytes) throws IOException { 55 int remainder = numBytes; 56 byte[] buffer = new byte[8192]; 57 while (remainder > 0) { 58 int bytesToRead = Math.min(remainder, 8192); 59 int bytesRead = in.read(buffer, 0, bytesToRead); 60 if (bytesRead != bytesToRead) { 61 throw new IOException("Failed to copy the given amount of bytes from the input" 62 + "stream to the output stream."); 63 } 64 remainder -= bytesRead; 65 out.write(buffer, 0, bytesRead); 66 } 67 } 68 69 /** 70 * Convert given int[] to long[]. If long[] is given, just return it. 71 * Return null for other types of input. 72 */ convertToLongArray(Object inputObj)73 public static long[] convertToLongArray(Object inputObj) { 74 if (inputObj instanceof int[]) { 75 int[] input = (int[]) inputObj; 76 long[] result = new long[input.length]; 77 for (int i = 0; i < input.length; i++) { 78 result[i] = input[i]; 79 } 80 return result; 81 } else if (inputObj instanceof long[]) { 82 return (long[]) inputObj; 83 } 84 return null; 85 } 86 87 /** 88 * Convert given byte array to hex string. 89 */ byteArrayToHexString(byte[] bytes)90 public static String byteArrayToHexString(byte[] bytes) { 91 StringBuilder sb = new StringBuilder(bytes.length * 2); 92 for (int i = 0; i < bytes.length; i++) { 93 sb.append(String.format("%02x", bytes[i])); 94 } 95 return sb.toString(); 96 } 97 98 /** 99 * Checks if the start of the first byte array is equal to the second byte array. 100 */ startsWith(byte[] cur, byte[] val)101 public static boolean startsWith(byte[] cur, byte[] val) { 102 if (cur == null || val == null) return false; 103 if (cur.length < val.length) return false; 104 if (cur.length == 0 || val.length == 0) return false; 105 for (int i = 0; i < val.length; i++) { 106 if (cur[i] != val[i]) return false; 107 } 108 return true; 109 } 110 111 /** 112 * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null. 113 */ closeQuietly(Closeable closeable)114 public static void closeQuietly(Closeable closeable) { 115 if (closeable != null) { 116 try { 117 closeable.close(); 118 } catch (RuntimeException rethrown) { 119 throw rethrown; 120 } catch (Exception ignored) { 121 } 122 } 123 } 124 125 /** 126 * Closes a file descriptor that has been duplicated. 127 */ closeFileDescriptor(FileDescriptor fd)128 public static void closeFileDescriptor(FileDescriptor fd) { 129 try { 130 Os.close(fd); 131 } catch (ErrnoException ex) { 132 Log.e(TAG, "Error closing fd.", ex); 133 } 134 } 135 } 136