001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging; 018 019import java.io.IOException; 020import java.io.PrintWriter; 021import java.io.StringWriter; 022import java.util.ArrayList; 023import java.util.List; 024import java.util.logging.Level; 025import java.util.logging.Logger; 026 027/** 028 * Provides information about the compliance of a specified data source (byte array, file, etc.) to an image format. 029 */ 030public class FormatCompliance { 031 032 private static final Logger LOGGER = Logger.getLogger(FormatCompliance.class.getName()); 033 034 public static FormatCompliance getDefault() { 035 return new FormatCompliance("ignore", false); 036 } 037 038 private final boolean failOnError; 039 private final String description; 040 041 private final List<String> comments = new ArrayList<>(); 042 043 public FormatCompliance(final String description) { 044 this.description = description; 045 this.failOnError = false; 046 } 047 048 public FormatCompliance(final String description, final boolean failOnError) { 049 this.description = description; 050 this.failOnError = failOnError; 051 } 052 053 public void addComment(final String comment) throws ImagingException { 054 comments.add(comment); 055 if (failOnError) { 056 throw new ImagingException(comment); 057 } 058 } 059 060 public void addComment(final String comment, final int value) throws ImagingException { 061 addComment(comment + ": " + getValueDescription(value)); 062 } 063 064 public boolean checkBounds(final String name, final int min, final int max, final int actual) throws ImagingException { 065 if (actual < min || actual > max) { 066 addComment(name + ": " + "bounds check: " + min + " <= " + actual + " <= " + max + ": false"); 067 return false; 068 } 069 070 return true; 071 } 072 073 public boolean compare(final String name, final int valid, final int actual) throws ImagingException { 074 return compare(name, new int[] { valid, }, actual); 075 } 076 077 public boolean compare(final String name, final int[] valid, final int actual) throws ImagingException { 078 for (final int element : valid) { 079 if (actual == element) { 080 return true; 081 } 082 } 083 084 final StringBuilder result = new StringBuilder(43); 085 result.append(name); 086 result.append(": Unexpected value: (valid: "); 087 if (valid.length > 1) { 088 result.append('{'); 089 } 090 for (int i = 0; i < valid.length; i++) { 091 if (i > 0) { 092 result.append(", "); 093 } 094 result.append(getValueDescription(valid[i])); 095 } 096 if (valid.length > 1) { 097 result.append('}'); 098 } 099 result.append(", actual: ").append(getValueDescription(actual)).append(")"); 100 addComment(result.toString()); 101 return false; 102 } 103 104 public boolean compareBytes(final String name, final byte[] expected, final byte[] actual) throws ImagingException { 105 if (expected.length != actual.length) { 106 addComment(name + ": " + "Unexpected length: (expected: " + expected.length + ", actual: " + actual.length + ")"); 107 return false; 108 } 109 for (int i = 0; i < expected.length; i++) { 110 // System.out.println("expected: " 111 // + getValueDescription(expected[i]) + ", actual: " 112 // + getValueDescription(actual[i]) + ")"); 113 if (expected[i] != actual[i]) { 114 addComment( 115 name + ": " + "Unexpected value: (expected: " + getValueDescription(expected[i]) + ", actual: " + getValueDescription(actual[i]) + ")"); 116 return false; 117 } 118 } 119 120 return true; 121 } 122 123 public void dump() { 124 try (StringWriter sw = new StringWriter(); 125 PrintWriter pw = new PrintWriter(sw)) { 126 dump(pw); 127 pw.flush(); 128 sw.flush(); 129 LOGGER.fine(sw.toString()); 130 } catch (final IOException e) { 131 LOGGER.log(Level.SEVERE, e.getMessage(), e); 132 } 133 } 134 135 public void dump(final PrintWriter pw) { 136 pw.println("Format Compliance: " + description); 137 138 if (comments.isEmpty()) { 139 pw.println("\t" + "No comments."); 140 } else { 141 for (int i = 0; i < comments.size(); i++) { 142 pw.println("\t" + (i + 1) + ": " + comments.get(i)); 143 } 144 } 145 pw.println(""); 146 pw.flush(); 147 } 148 149 private String getValueDescription(final int value) { 150 return value + " (" + Integer.toHexString(value) + ")"; 151 } 152 153 @Override 154 public String toString() { 155 final StringWriter sw = new StringWriter(); 156 final PrintWriter pw = new PrintWriter(sw); 157 158 dump(pw); 159 160 return sw.getBuffer().toString(); 161 } 162}