Coverage Report - org.jaudiotagger.audio.asf.data.GUID
 
Classes in this File Line Coverage Branch Coverage Complexity
GUID
84%
114/135
63%
28/44
2.389
 
 1  
 /*
 2  
  * Entagged Audio Tag library
 3  
  * Copyright (c) 2004-2005 Christian Laireiter <liree@web.de>
 4  
  * 
 5  
  * This library is free software; you can redistribute it and/or
 6  
  * modify it under the terms of the GNU Lesser General Public
 7  
  * License as published by the Free Software Foundation; either
 8  
  * version 2.1 of the License, or (at your option) any later version.
 9  
  *  
 10  
  * This library is distributed in the hope that it will be useful,
 11  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  
  * Lesser General Public License for more details.
 14  
  * 
 15  
  * You should have received a copy of the GNU Lesser General Public
 16  
  * License along with this library; if not, write to the Free Software
 17  
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 18  
  */
 19  
 package org.jaudiotagger.audio.asf.data;
 20  
 
 21  
 import org.jaudiotagger.audio.asf.util.Utils;
 22  
 
 23  
 import java.util.Arrays;
 24  
 import java.util.HashMap;
 25  
 import java.util.Map;
 26  
 import java.util.regex.Pattern;
 27  
 
 28  
 /**
 29  
  * This class is used for representation of GUIDs and as a reference list of all
 30  
  * Known GUIDs. <br>
 31  
  * 
 32  
  * @author Christian Laireiter
 33  
  */
 34  4
 public final class GUID {
 35  
 
 36  
     /**
 37  
      * This constant defines the GUID for stream chunks describing audio
 38  
      * streams, indicating the the audio stream has no error concealment. <br>
 39  
      */
 40  4
     public final static GUID GUID_AUDIO_ERROR_CONCEALEMENT_ABSENT = new GUID(
 41  
             new int[] { 0x40, 0xA4, 0xF1, 0x49, 0xCE, 0x4E, 0xD0, 0x11, 0xA3,
 42  
                     0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 },
 43  
             "Audio error concealment absent.");
 44  
 
 45  
     /**
 46  
      * This constant defines the GUID for stream chunks describing audio
 47  
      * streams, indicating the the audio stream has interleaved error
 48  
      * concealment. <br>
 49  
      */
 50  4
     public final static GUID GUID_AUDIO_ERROR_CONCEALEMENT_INTERLEAVED = new GUID(
 51  
             new int[] { 0x40, 0xA4, 0xF1, 0x49, 0xCE, 0x4E, 0xD0, 0x11, 0xA3,
 52  
                     0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 },
 53  
             "Interleaved audio error concealment.");
 54  
 
 55  
     /**
 56  
      * This constant stores the GUID indicating that stream type is audio.
 57  
      */
 58  4
     public final static GUID GUID_AUDIOSTREAM = new GUID(new int[] { 0x40,
 59  
             0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80,
 60  
             0x5F, 0x5C, 0x44, 0x2B }, " Audio stream");
 61  
 
 62  
     /**
 63  
      * This constant stores the GUID indicating a content branding object.
 64  
      */
 65  4
     public final static GUID GUID_CONTENT_BRANDING = new GUID(new int[] { 0xFA,
 66  
             0xB3, 0x11, 0x22, 0x23, 0xBD, 0xD2, 0x11, 0xB4, 0xB7, 0x00, 0xA0,
 67  
             0xC9, 0x55, 0xFC, 0x6E }, "Content Branding");
 68  
 
 69  
     /**
 70  
      * This is for the Content Encryption Object
 71  
      * 2211B3FB-BD23-11D2-B4B7-00A0C955FC6E, needs to be little-endian.
 72  
      */
 73  4
     public final static GUID GUID_CONTENT_ENCRYPTION = new GUID(new int[] {
 74  
             0xfb, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00,
 75  
             0xa0, 0xc9, 0x55, 0xfc, 0x6e }, "Content Encryption Object");
 76  
 
 77  
     /**
 78  
      * This constant represents the guidData for a chunk which contains Title,
 79  
      * author, copyright, description and rating.
 80  
      */
 81  4
     public final static GUID GUID_CONTENTDESCRIPTION = new GUID(new int[] {
 82  
             0x33, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00,
 83  
             0xAA, 0x00, 0x62, 0xCE, 0x6C }, "Content Description");
 84  
 
 85  
     /**
 86  
      * This constant stores the GUID for Encoding-Info chunks.
 87  
      */
 88  4
     public final static GUID GUID_ENCODING = new GUID(new int[] { 0x40, 0x52,
 89  
             0xD1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xA3, 0xA4, 0x00, 0xA0, 0xC9,
 90  
             0x03, 0x48, 0xF6 }, "Encoding description");
 91  
 
 92  
     /**
 93  
      * This constant defines the GUID for a WMA "Extended Content Description"
 94  
      * chunk. <br>
 95  
      */
 96  4
     public final static GUID GUID_EXTENDED_CONTENT_DESCRIPTION = new GUID(
 97  
             new int[] { 0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97,
 98  
                     0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50 },
 99  
             "Extended Content Description");
 100  
 
 101  
     /**
 102  
      * GUID of ASF file header.
 103  
      */
 104  4
     public final static GUID GUID_FILE = new GUID(new int[] { 0xA1, 0xDC, 0xAB,
 105  
             0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20,
 106  
             0x53, 0x65 }, "File header");
 107  
 
 108  
     /**
 109  
      * This constant defines the GUID of a asf header chunk.
 110  
      */
 111  4
     public final static GUID GUID_HEADER = new GUID(new int[] { 0x30, 0x26,
 112  
             0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00,
 113  
             0x62, 0xce, 0x6c }, "Asf header");
 114  
 
 115  
     /**
 116  
      * This constant stores a GUID whose functionality is unknown.
 117  
      */
 118  4
     public final static GUID GUID_HEADER_EXTENSION = new GUID(new int[] { 0xB5,
 119  
             0x03, 0xBF, 0x5F, 0x2E, 0xA9, 0xCF, 0x11, 0x8E, 0xE3, 0x00, 0xC0,
 120  
             0x0C, 0x20, 0x53, 0x65 }, "Header Extension");
 121  
 
 122  
     /**
 123  
      * This constant stores the GUID indicating the asf language list object.<br>
 124  
      */
 125  4
     public final static GUID GUID_LANGUAGE_LIST = new GUID(new int[] { 0xa9,
 126  
             0x46, 0x43, 0x7c, 0xe0, 0xef, 0xfc, 0x4b, 0xb2, 0x29, 0x39, 0x3e,
 127  
             0xde, 0x41, 0x5c, 0x85 }, "Language List");
 128  
 
 129  
     /**
 130  
      * This constant stores the length of GUIDs used with ASF streams. <br>
 131  
      */
 132  
     public final static int GUID_LENGTH = 16;
 133  
 
 134  
     /**
 135  
      * This constant stores the GUID indicating the asf metadata object.<br>
 136  
      */
 137  4
     public final static GUID GUID_METADATA = new GUID(new int[] { 0xea, 0xcb,
 138  
             0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44,
 139  
             0xfa, 0x4c, 0xca }, "Metadata");
 140  
 
 141  
     /**
 142  
      * This constant stores the GUID indicating the asf metadata library object.<br>
 143  
      */
 144  4
     public final static GUID GUID_METADATA_LIBRARY = new GUID(new int[] { 0x94,
 145  
             0x1c, 0x23, 0x44, 0x98, 0x94, 0xd1, 0x49, 0xa1, 0x41, 0x1d, 0x13,
 146  
             0x4e, 0x45, 0x70, 0x54 }, "Metadata Library");
 147  
 
 148  
     /**
 149  
      * The GUID String values format.<br>
 150  
      */
 151  4
     private final static Pattern GUID_PATTERN = Pattern
 152  
             .compile(
 153  
                     "[a-f0-9]{8}\\-[a-f0-9]{4}\\-[a-f0-9]{4}\\-[a-f0-9]{4}\\-[a-f0-9]{12}",
 154  
                     Pattern.CASE_INSENSITIVE);
 155  
 
 156  
     /**
 157  
      * This constant stores the GUID indicating a stream object.
 158  
      */
 159  4
     public final static GUID GUID_STREAM = new GUID(new int[] { 0x91, 0x07,
 160  
             0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C,
 161  
             0x20, 0x53, 0x65 }, "Stream");
 162  
 
 163  
     /**
 164  
      * This constant stores a GUID indicating a "stream bitrate properties"
 165  
      * chunk.
 166  
      */
 167  4
     public final static GUID GUID_STREAM_BITRATE_PROPERTIES = new GUID(
 168  
             new int[] { 0xCE, 0x75, 0xF8, 0x7B, 0x8D, 0x46, 0xD1, 0x11, 0x8D,
 169  
                     0x82, 0x00, 0x60, 0x97, 0xC9, 0xA2, 0xB2 },
 170  
             "Stream bitrate properties");
 171  
 
 172  
     /**
 173  
      * This map is used, to get the description of a GUID instance, which has
 174  
      * been created by reading.<br>
 175  
      * The map comparison is done against the {@link GUID#guidData} field. But
 176  
      * only the {@link #KNOWN_GUIDS} have a description set.
 177  
      */
 178  
     private final static Map<GUID, GUID> GUID_TO_CONFIGURED;
 179  
 
 180  
     /**
 181  
      * This constant represents a GUID implementation which can be used for
 182  
      * generic implementations, which have to provide a GUID, but do not really
 183  
      * require a specific GUID to work.
 184  
      */
 185  4
     public final static GUID GUID_UNSPECIFIED = new GUID(new int[] { 0x00,
 186  
             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 187  
             0x00, 0x00, 0x00, 0x00 }, "Unspecified");
 188  
 
 189  
     /**
 190  
      * This constant stores the GUID indicating that stream type is video.
 191  
      */
 192  4
     public final static GUID GUID_VIDEOSTREAM = new GUID(new int[] { 0xC0,
 193  
             0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80,
 194  
             0x5F, 0x5C, 0x44, 0x2B }, "Video stream");
 195  
 
 196  
     /**
 197  
      * This field stores all known GUIDs.
 198  
      */
 199  
     public final static GUID[] KNOWN_GUIDS;
 200  
 
 201  
     /**
 202  
      * This constant stores the GUID for a &quot;script command object&quot;.<br>
 203  
      */
 204  4
     public final static GUID SCRIPT_COMMAND_OBJECT = new GUID(new int[] { 0x30,
 205  
             0x1a, 0xfb, 0x1e, 0x62, 0x0b, 0xd0, 0x11, 0xa3, 0x9b, 0x00, 0xa0,
 206  
             0xc9, 0x03, 0x48, 0xf6 }, "Script Command Object");
 207  
 
 208  
     static {
 209  4
         KNOWN_GUIDS = new GUID[] { GUID_AUDIO_ERROR_CONCEALEMENT_ABSENT,
 210  
                 GUID_CONTENTDESCRIPTION, GUID_AUDIOSTREAM, GUID_ENCODING,
 211  
                 GUID_FILE, GUID_HEADER, GUID_STREAM,
 212  
                 GUID_EXTENDED_CONTENT_DESCRIPTION, GUID_VIDEOSTREAM,
 213  
                 GUID_HEADER_EXTENSION, GUID_STREAM_BITRATE_PROPERTIES,
 214  
                 SCRIPT_COMMAND_OBJECT, GUID_CONTENT_ENCRYPTION,
 215  
                 GUID_CONTENT_BRANDING, GUID_UNSPECIFIED, GUID_METADATA_LIBRARY,
 216  
                 GUID_METADATA, GUID_LANGUAGE_LIST };
 217  4
         GUID_TO_CONFIGURED = new HashMap<GUID, GUID>(KNOWN_GUIDS.length);
 218  76
         for (final GUID curr : KNOWN_GUIDS) {
 219  
             assert !GUID_TO_CONFIGURED.containsKey(curr) : "Double definition: \""
 220  
                     + GUID_TO_CONFIGURED.get(curr).getDescription()
 221  72
                     + "\" <-> \"" + curr.getDescription() + "\"";
 222  72
             GUID_TO_CONFIGURED.put(curr, curr);
 223  
         }
 224  4
     }
 225  
 
 226  
     /**
 227  
      * This method checks if the given <code>value</code> is matching the GUID
 228  
      * specification of ASF streams. <br>
 229  
      * 
 230  
      * @param value
 231  
      *            possible GUID.
 232  
      * @return <code>true</code> if <code>value</code> matches the specification
 233  
      *         of a GUID.
 234  
      */
 235  
     public static boolean assertGUID(final int[] value) {
 236  8464
         return value != null && value.length == GUID.GUID_LENGTH;
 237  
     }
 238  
 
 239  
     /**
 240  
      * This method looks up a GUID instance from {@link #KNOWN_GUIDS} which
 241  
      * matches the value of the given GUID.
 242  
      * 
 243  
      * @param orig
 244  
      *            GUID to look up.
 245  
      * @return a GUID instance from {@link #KNOWN_GUIDS} if available.
 246  
      *         <code>null</code> else.
 247  
      */
 248  
     public static GUID getConfigured(final GUID orig) {
 249  
         // safe against null
 250  152
         return GUID_TO_CONFIGURED.get(orig);
 251  
     }
 252  
 
 253  
     /**
 254  
      * This method searches a GUID in {@link #KNOWN_GUIDS}which is equal to the
 255  
      * given <code>guidData</code> and returns its description. <br>
 256  
      * This method is useful if a GUID was read out of a file and no
 257  
      * identification has been done yet.
 258  
      * 
 259  
      * @param guid
 260  
      *            GUID, which description is needed.
 261  
      * @return description of the GUID if found. Else <code>null</code>
 262  
      */
 263  
     public static String getGuidDescription(final GUID guid) {
 264  4
         String result = null;
 265  4
         if (guid == null) {
 266  0
             throw new IllegalArgumentException("Argument must not be null.");
 267  
         }
 268  4
         if (getConfigured(guid) != null) {
 269  4
             result = getConfigured(guid).getDescription();
 270  
         }
 271  4
         return result;
 272  
     }
 273  
 
 274  
     /**
 275  
      * This method parses a String as GUID.<br>
 276  
      * The format is like the one in the ASF specification.<br>
 277  
      * An Example: <code>C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA</code><br>
 278  
      * 
 279  
      * @param guid
 280  
      *            the string to parse.
 281  
      * @return the GUID.
 282  
      * @throws GUIDFormatException
 283  
      *             If the GUID has an invalid format.
 284  
      */
 285  
     public static GUID parseGUID(final String guid) throws GUIDFormatException {
 286  92
         if (guid == null) {
 287  0
             throw new GUIDFormatException("null");
 288  
         }
 289  92
         if (!GUID_PATTERN.matcher(guid).matches()) {
 290  8
             throw new GUIDFormatException("Invalid guidData format.");
 291  
         }
 292  84
         final int[] bytes = new int[GUID_LENGTH];
 293  
         /*
 294  
          * Don't laugh, but did not really come up with a nicer solution today
 295  
          */
 296  84
         final int[] arrayIndices = { 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12,
 297  
                 13, 14, 15 };
 298  84
         int arrayPointer = 0;
 299  1764
         for (int i = 0; i < guid.length(); i++) {
 300  1680
             if (guid.charAt(i) == '-') {
 301  336
                 continue;
 302  
             }
 303  1344
             bytes[arrayIndices[arrayPointer++]] = Integer.parseInt(guid
 304  
                     .substring(i, i + 2), 16);
 305  1344
             i++;
 306  
         }
 307  84
         return new GUID(bytes);
 308  
     }
 309  
 
 310  
     /**
 311  
      * Stores an optionally description of the GUID.
 312  
      */
 313  8464
     private String description = "";
 314  
 
 315  
     /**
 316  
      * An instance of this class stores the value of the wrapped GUID in this
 317  
      * field. <br>
 318  
      */
 319  8464
     private int[] guidData = null;
 320  
 
 321  
     /**
 322  
      * Stores the hash code of the object.<br>
 323  
      * <code>&quot;-1&quot;</code> if not determined yet.
 324  
      */
 325  
     private int hash;
 326  
 
 327  
     /**
 328  
      * Creates an instance and assigns given <code>value</code>.<br>
 329  
      * 
 330  
      * @param value
 331  
      *            GUID, which should be assigned. (will be converted to int[])
 332  
      */
 333  324
     public GUID(final byte[] value) {
 334  324
         assert value != null;
 335  324
         final int[] tmp = new int[value.length];
 336  5444
         for (int i = 0; i < value.length; i++) {
 337  5120
             tmp[i] = (0xFF & value[i]);
 338  
         }
 339  324
         setGUID(tmp);
 340  320
     }
 341  
 
 342  
     /**
 343  
      * Creates an instance and assigns given <code>value</code>.<br>
 344  
      * 
 345  
      * @param value
 346  
      *            GUID, which should be assigned.
 347  
      */
 348  8140
     public GUID(final int[] value) {
 349  8140
         setGUID(value);
 350  8140
     }
 351  
 
 352  
     /**
 353  
      * Creates an instance like {@link #GUID(int[])}and sets the optional
 354  
      * description. <br>
 355  
      * 
 356  
      * @param value
 357  
      *            GUID, which should be assigned.
 358  
      * @param desc
 359  
      *            Description for the GUID.
 360  
      */
 361  
     public GUID(final int[] value, final String desc) {
 362  76
         this(value);
 363  76
         if (desc == null) {
 364  0
             throw new IllegalArgumentException("Argument must not be null.");
 365  
         }
 366  76
         this.description = desc;
 367  76
     }
 368  
 
 369  
     /**
 370  
      * Creates an instance like {@link #GUID(int[])} and sets the optional
 371  
      * description. (the int[] is obtained by {@link GUID#parseGUID(String)}) <br>
 372  
      * 
 373  
      * @param guidString
 374  
      *            GUID, which should be assigned.
 375  
      * @param desc
 376  
      *            Description for the GUID.
 377  
      */
 378  
     public GUID(final String guidString, final String desc) {
 379  0
         this(parseGUID(guidString).getGUID());
 380  0
         if (desc == null) {
 381  0
             throw new IllegalArgumentException("Argument must not be null.");
 382  
         }
 383  0
         this.description = desc;
 384  0
     }
 385  
 
 386  
     /**
 387  
      * This method compares two objects. If the given Object is a {@link GUID},
 388  
      * the stored GUID values are compared. <br>
 389  
      * 
 390  
      * @see java.lang.Object#equals(java.lang.Object)
 391  
      */
 392  
     @Override
 393  
     public boolean equals(final Object obj) {
 394  91619
         boolean result = false;
 395  91619
         if (obj instanceof GUID) {
 396  91227
             final GUID other = (GUID) obj;
 397  91227
             result = Arrays.equals(this.getGUID(), other.getGUID());
 398  
         }
 399  91619
         return result;
 400  
     }
 401  
 
 402  
     /**
 403  
      * This method returns the GUID as an array of bytes. <br>
 404  
      * 
 405  
      * @return The GUID as a byte array.
 406  
      * @see #getGUID()
 407  
      */
 408  
     public byte[] getBytes() {
 409  2630
         final byte[] result = new byte[this.guidData.length];
 410  44710
         for (int i = 0; i < result.length; i++) {
 411  42080
             result[i] = (byte) (this.guidData[i] & 0xFF);
 412  
         }
 413  2630
         return result;
 414  
     }
 415  
 
 416  
     /**
 417  
      * @return Returns the description.
 418  
      */
 419  
     public String getDescription() {
 420  322
         return this.description;
 421  
     }
 422  
 
 423  
     /**
 424  
      * This method returns the GUID of this object. <br>
 425  
      * 
 426  
      * @return stored GUID.
 427  
      */
 428  
     public int[] getGUID() {
 429  182454
         final int[] copy = new int[this.guidData.length];
 430  182454
         System.arraycopy(this.guidData, 0, copy, 0, this.guidData.length);
 431  182454
         return copy;
 432  
     }
 433  
 
 434  
     /**
 435  
      * Convenience method to get 2digit hex values of each byte.
 436  
      * 
 437  
      * @param bytes
 438  
      *            bytes to convert.
 439  
      * @return each byte as 2 digit hex.
 440  
      */
 441  
     private String[] getHex(final byte[] bytes) {
 442  208
         final String[] result = new String[bytes.length];
 443  208
         final StringBuilder tmp = new StringBuilder();
 444  3536
         for (int i = 0; i < bytes.length; i++) {
 445  3328
             tmp.delete(0, tmp.length());
 446  3328
             tmp.append(Integer.toHexString(0xFF & bytes[i]));
 447  3328
             if (tmp.length() == 1) {
 448  680
                 tmp.insert(0, "0");
 449  
             }
 450  3328
             result[i] = tmp.toString();
 451  
         }
 452  208
         return result;
 453  
     }
 454  
 
 455  
     /**
 456  
      * {@inheritDoc}
 457  
      */
 458  
     @Override
 459  
     public int hashCode() {
 460  25120
         if (this.hash == -1) {
 461  0
             int tmp = 0;
 462  0
             for (final int curr : getGUID()) {
 463  0
                 tmp = tmp * 31 + curr;
 464  
             }
 465  0
             this.hash = tmp;
 466  
         }
 467  25120
         return this.hash;
 468  
     }
 469  
 
 470  
     /**
 471  
      * This method checks if the currently stored GUID ({@link #guidData}) is
 472  
      * correctly filled. <br>
 473  
      * 
 474  
      * @return <code>true</code> if it is.
 475  
      */
 476  
     public boolean isValid() {
 477  0
         return assertGUID(getGUID());
 478  
     }
 479  
 
 480  
     /**
 481  
      * This method gives a hex formatted representation of {@link #getGUID()}
 482  
      * 
 483  
      * @return hex formatted representation.
 484  
      */
 485  
     public String prettyPrint() {
 486  0
         final StringBuilder result = new StringBuilder();
 487  0
         String descr = getDescription();
 488  0
         if (Utils.isBlank(descr)) {
 489  0
             descr = getGuidDescription(this);
 490  
         }
 491  0
         if (!Utils.isBlank(descr)) {
 492  0
             result.append("Description: ").append(descr).append(
 493  
                     Utils.LINE_SEPARATOR).append("   ");
 494  
         }
 495  0
         result.append(this.toString());
 496  0
         return result.toString();
 497  
     }
 498  
 
 499  
     /**
 500  
      * This method saves a copy of the given <code>value</code> as the
 501  
      * represented value of this object. <br>
 502  
      * The given value is checked with {@link #assertGUID(int[])}.<br>
 503  
      * 
 504  
      * @param value
 505  
      *            GUID to assign.
 506  
      */
 507  
     private void setGUID(final int[] value) {
 508  8464
         if (assertGUID(value)) {
 509  8460
             this.guidData = new int[GUID_LENGTH];
 510  8460
             System.arraycopy(value, 0, this.guidData, 0, GUID_LENGTH);
 511  
         } else {
 512  4
             throw new IllegalArgumentException(
 513  
                     "The given guidData doesn't match the GUID specification.");
 514  
         }
 515  8460
     }
 516  
 
 517  
     /**
 518  
      * {@inheritDoc}
 519  
      */
 520  
     @Override
 521  
     public String toString() {
 522  
         // C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA
 523  
         // 0xea, 0xcb,0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa,
 524  
         // 0x8c, 0x44,0xfa, 0x4c, 0xca
 525  208
         final StringBuilder result = new StringBuilder();
 526  208
         final String[] bytes = getHex(getBytes());
 527  208
         result.append(bytes[3]);
 528  208
         result.append(bytes[2]);
 529  208
         result.append(bytes[1]);
 530  208
         result.append(bytes[0]);
 531  208
         result.append('-');
 532  208
         result.append(bytes[5]);
 533  208
         result.append(bytes[4]);
 534  208
         result.append('-');
 535  208
         result.append(bytes[7]);
 536  208
         result.append(bytes[6]);
 537  208
         result.append('-');
 538  208
         result.append(bytes[8]);
 539  208
         result.append(bytes[9]);
 540  208
         result.append('-');
 541  208
         result.append(bytes[10]);
 542  208
         result.append(bytes[11]);
 543  208
         result.append(bytes[12]);
 544  208
         result.append(bytes[13]);
 545  208
         result.append(bytes[14]);
 546  208
         result.append(bytes[15]);
 547  208
         return result.toString();
 548  
     }
 549  
 
 550  
 }