/* * Copyright 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.media; import android.system.ErrnoException; import android.system.Os; import android.util.Log; import java.io.Closeable; import java.io.FileDescriptor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Package private utility class for ExifInterface. */ class ExifInterfaceUtils { private static final String TAG = "ExifInterface"; /** * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed. * Returns the total number of bytes transferred. */ public static int copy(InputStream in, OutputStream out) throws IOException { int total = 0; byte[] buffer = new byte[8192]; int c; while ((c = in.read(buffer)) != -1) { total += c; out.write(buffer, 0, c); } return total; } /** * Copies the given number of the bytes from {@code in} to {@code out}. Neither stream is * closed. */ public static void copy(InputStream in, OutputStream out, int numBytes) throws IOException { int remainder = numBytes; byte[] buffer = new byte[8192]; while (remainder > 0) { int bytesToRead = Math.min(remainder, 8192); int bytesRead = in.read(buffer, 0, bytesToRead); if (bytesRead != bytesToRead) { throw new IOException("Failed to copy the given amount of bytes from the input" + "stream to the output stream."); } remainder -= bytesRead; out.write(buffer, 0, bytesRead); } } /** * Convert given int[] to long[]. If long[] is given, just return it. * Return null for other types of input. */ public static long[] convertToLongArray(Object inputObj) { if (inputObj instanceof int[]) { int[] input = (int[]) inputObj; long[] result = new long[input.length]; for (int i = 0; i < input.length; i++) { result[i] = input[i]; } return result; } else if (inputObj instanceof long[]) { return (long[]) inputObj; } return null; } /** * Convert given byte array to hex string. */ public static String byteArrayToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 2); for (int i = 0; i < bytes.length; i++) { sb.append(String.format("%02x", bytes[i])); } return sb.toString(); } /** * Checks if the start of the first byte array is equal to the second byte array. */ public static boolean startsWith(byte[] cur, byte[] val) { if (cur == null || val == null) return false; if (cur.length < val.length) return false; if (cur.length == 0 || val.length == 0) return false; for (int i = 0; i < val.length; i++) { if (cur[i] != val[i]) return false; } return true; } /** * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null. */ public static void closeQuietly(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (RuntimeException rethrown) { throw rethrown; } catch (Exception ignored) { } } } /** * Closes a file descriptor that has been duplicated. */ public static void closeFileDescriptor(FileDescriptor fd) { try { Os.close(fd); } catch (ErrnoException ex) { Log.e(TAG, "Error closing fd.", ex); } } }