/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017-2018 Yegor Bugayenko
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package org.cactoos.bytes;

import java.io.IOException;
import org.cactoos.Bytes;
import org.cactoos.Text;

/**
 * Decodes origin {@link Text} using the hex encoding scheme.
 *
 * @author Alexander Menshikov (sharplermc@gmail.com)
 * @version $Id$
 * @since 0.29
 * @checkstyle MagicNumberCheck (500 lines)
 */
public final class HexBytes implements Bytes {
    /**
     * Origin hex text.
     */
    private final Text origin;

    /**
     * Ctor.
     *
     * @param origin Hex text.
     */
    public HexBytes(final Text origin) {
        this.origin = origin;
    }

    @Override public byte[] asBytes() throws IOException {
        final String hex = this.origin.asString();
        if ((hex.length() & 1) == 1) {
            throw new IOException("Length of hex text is odd");
        }
        final byte[] result = new byte[hex.length() / 2];
        int index = 0;
        while (index < hex.length()) {
            final int most = Character.digit(hex.charAt(index), 16);
            final int less = Character.digit(hex.charAt(index + 1), 16);
            if (less == -1 || most == -1) {
                throw new IOException(
                    new StringBuilder()
                        .append("Unexpected character in hex string '")
                        .append(
                            hex.charAt(index + 1)
                        ).append('\'').toString()
                );
            }
            result[index >>> 1] = (byte) ((most << 4) + less);
            index += 2;
        }
        return result;
    }
}

@@ -1305,16 +1305,24 @@
  the hex
+adecimal
  encodin
@@ -1536,24 +1536,32 @@
 * Origin hex
+adecimal
  text.%0A     
@@ -1647,16 +1647,24 @@
 igin Hex
+adecimal
  text.%0A 
@@ -1945,16 +1945,24 @@
 h of hex
+adecimal
  text is
@@ -2128,27 +2128,24 @@
  most = 
-Character.d
+checkedD
 igit(hex
@@ -2158,20 +2158,16 @@
 t(index)
-, 16
 );%0A     
@@ -2194,19 +2194,16 @@
 s = 
-Character.d
+checkedD
 igit
@@ -2228,12 +2228,8 @@
 + 1)
-, 16
 );%0A 
@@ -2243,91 +2243,91 @@
     
-if (less == -1 %7C%7C most == -1) %7B%0A                throw new IOException(%0A    
+result%5Bindex %3E%3E%3E 1%5D = (byte) ((most %3C%3C 4) + less);%0A            index += 2;%0A
         
     
@@ -2322,24 +2322,26 @@
         
+%7D%0A
         
 new Stri
@@ -2336,251 +2336,479 @@
     
-new StringBuilder()
+return result;
 %0A    
+%7D%0A%0A
     
+/**%0A
      
-           .append(%22Unexpected character in hex string '%22)%0A                        .append(
+* Wrap around %7B@link Character#digit(char, int)%7D.%0A     *%0A     * @param character Hexadecimal character.%0A     * @return Numeric Value of the hex character.%0A     * @throws IOException If fails.
 %0A     
+*/%0A
     
-                   hex.charAt(index + 1)%0A                        ).append('%5C'').toString()%0A                );
+private static int checkedDigit(final char character) throws IOException %7B%0A        final int result = Character.digit(character, 16);%0A        if (result == -1) %7B%0A            throw new IOException(%0A                new StringBuilder()
 %0A   
@@ -2811,27 +2811,24 @@
 %0A           
- %7D%0A
             
@@ -2828,84 +2828,132 @@
     
-   result%5Bindex %3E%3E%3E 1%5D = (byte) ((most %3C%3C 4) + less);%0A            index += 2
+.append(%22Unexpected character in hex string '%22)%0A                    .append(character).append('%5C'').toString()%0A            )
 ;%0A  

fix exception message