View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.imaging;
18  
19  import java.io.IOException;
20  import java.io.PrintWriter;
21  import java.io.StringWriter;
22  import java.util.ArrayList;
23  import java.util.List;
24  import java.util.logging.Level;
25  import java.util.logging.Logger;
26  
27  /**
28   * Provides information about the compliance of a specified data source (byte array, file, etc.) to an image format.
29   */
30  public class FormatCompliance {
31  
32      private static final Logger LOGGER = Logger.getLogger(FormatCompliance.class.getName());
33  
34      public static FormatCompliance getDefault() {
35          return new FormatCompliance("ignore", false);
36      }
37  
38      private final boolean failOnError;
39      private final String description;
40  
41      private final List<String> comments = new ArrayList<>();
42  
43      public FormatCompliance(final String description) {
44          this.description = description;
45          this.failOnError = false;
46      }
47  
48      public FormatCompliance(final String description, final boolean failOnError) {
49          this.description = description;
50          this.failOnError = failOnError;
51      }
52  
53      public void addComment(final String comment) throws ImagingException {
54          comments.add(comment);
55          if (failOnError) {
56              throw new ImagingException(comment);
57          }
58      }
59  
60      public void addComment(final String comment, final int value) throws ImagingException {
61          addComment(comment + ": " + getValueDescription(value));
62      }
63  
64      public boolean checkBounds(final String name, final int min, final int max, final int actual) throws ImagingException {
65          if (actual < min || actual > max) {
66              addComment(name + ": " + "bounds check: " + min + " <= " + actual + " <= " + max + ": false");
67              return false;
68          }
69  
70          return true;
71      }
72  
73      public boolean compare(final String name, final int valid, final int actual) throws ImagingException {
74          return compare(name, new int[] { valid, }, actual);
75      }
76  
77      public boolean compare(final String name, final int[] valid, final int actual) throws ImagingException {
78          for (final int element : valid) {
79              if (actual == element) {
80                  return true;
81              }
82          }
83  
84          final StringBuilder result = new StringBuilder(43);
85          result.append(name);
86          result.append(": Unexpected value: (valid: ");
87          if (valid.length > 1) {
88              result.append('{');
89          }
90          for (int i = 0; i < valid.length; i++) {
91              if (i > 0) {
92                  result.append(", ");
93              }
94              result.append(getValueDescription(valid[i]));
95          }
96          if (valid.length > 1) {
97              result.append('}');
98          }
99          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 }