/**************************************************************************** * Copyright (C) 2016-2019 Maschell * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . ****************************************************************************/ package de.mas.wiiu.jnus.utils; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.xml.sax.ErrorHandler; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import de.mas.wiiu.jnus.Settings; import lombok.extern.java.Log; @Log public final class Utils { private Utils() { // Utility class } public static long align(long numToRound, int multiple) { if ((multiple > 0) && ((multiple & (multiple - 1)) == 0)) { return alignPower2(numToRound, multiple); } else { return alignGeneric(numToRound, multiple); } } private static long alignGeneric(long numToRound, int multiple) { int isPositive = 0; if (numToRound >= 0) { isPositive = 1; } return ((numToRound + isPositive * (multiple - 1)) / multiple) * multiple; } private static long alignPower2(long numToRound, int multiple) { if (!((multiple > 0) && ((multiple & (multiple - 1)) == 0))) return 0L; return (numToRound + (multiple - 1)) & ~(multiple - 1); } public static String ByteArrayToString(byte[] ba) { if (ba == null) return null; StringBuilder hex = new StringBuilder(ba.length * 2); for (byte b : ba) { hex.append(String.format("%02X", b)); } return hex.toString(); } public static byte[] StringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16)); } return data; } public static boolean createDir(String path) { if (path == null || path.isEmpty()) { return false; } File pathFile = new File(path); if (!pathFile.exists()) { boolean success = new File(path).mkdirs(); if (!success) { log.fine("Creating directory \"" + path + "\" failed."); return false; } } else if (!pathFile.isDirectory()) { log.info("\"" + path + "\" already exists but is no directoy"); return false; } return true; } public static void deleteDir(File path) { if (path == null || !path.exists()) return; for (File file : path.listFiles()) { if (file.isDirectory()) deleteDir(file); file.delete(); } path.delete(); } public static String replaceStringInStringEscaped(String input, String replace, String replaceWith) { return input.replaceAll(Pattern.quote(replace), Matcher.quoteReplacement(replaceWith)); } public static boolean checkXML(InputSource in) { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setValidating(false); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); builder.setErrorHandler(new ErrorHandler() { @Override public void warning(SAXParseException exception) throws SAXException { throw exception; } @Override public void error(SAXParseException exception) throws SAXException { throw exception; } @Override public void fatalError(SAXParseException exception) throws SAXException { throw exception; } }); builder.parse(in); return true; } catch (Exception e) { return false; } } public static boolean checkXML(InputStream in) { return checkXML(new InputSource(in)); } public static boolean checkXML(byte[] data) { return checkXML(new ByteArrayInputStream(data)); } public static boolean checkXML(File file) { return checkXML(new InputSource(file.getAbsolutePath())); } public static void sleep(long millis) { try { Thread.sleep(millis); } catch (InterruptedException e) { } } public static long StringToLong(String s) { try { BigInteger bi = new BigInteger(s, 16); return bi.longValue(); } catch (NumberFormatException e) { System.err.println("Invalid Title ID"); return 0L; } } public static void setGlobalLogLevel(Level level) { Arrays.stream(LogManager.getLogManager().getLogger("").getHandlers()).forEach(h -> h.setLevel(level)); } public static boolean checkFileExists(String path) { return new File(path).exists(); } /** * Pings a HTTP URL. This effectively sends a HEAD request and returns true if the response code is in the 200-399 range. * * @param url * The HTTP URL to be pinged. * @param timeout * The timeout in millis for both the connection timeout and the response read timeout. Note that the total timeout is effectively two times the * given timeout. * @return true if the given HTTP URL has returned response code 200-399 on a HEAD request within the given timeout, otherwise * false. */ public static boolean pingURL(String url, int timeout) { try { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("User-Agent", Settings.USER_AGENT); connection.setConnectTimeout(timeout); connection.setReadTimeout(timeout); int responseCode = connection.getResponseCode(); return (200 <= responseCode && responseCode <= 399); } catch (IOException exception) { return false; } } public static Long getLastModifiedURL(String url, int timeout) throws IOException { HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestProperty("User-Agent", Settings.USER_AGENT); connection.setConnectTimeout(timeout); connection.setReadTimeout(timeout); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { InputStream inputStream = connection.getInputStream(); byte[] buffer = new byte[0x10]; inputStream.read(buffer); inputStream.close(); } else { return null; } Long dateTime = connection.getLastModified(); if (200 <= responseCode && responseCode <= 399) { return dateTime; } return null; } }