1 /*
2  * Copyright 2013-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15 package com.amazonaws.util;
16
17 /**
18  * Codec internal utilities
19  * 
20  * @author Hanson Char
21  */

22 public enum CodecUtils {
23     ;
24     /**
25      * Transforms the given string into the given destination byte array
26      * truncating each character into a byte and skipping carriage returns and
27      * line feeds if any.
28      * <p>
29      * dmurray: "It so happens that we're currently only calling this method
30      * with src.length == dest.length, in which case it works, but we could
31      * theoretically get away with passing a smaller dest if we knew ahead of
32      * time that src contained some number of spaces. In that case it looks like
33      * this implementation would truncate the result."
34      * <p>
35      * hchar:
36      * "Yes, but the truncation is the intentional behavior of this internal 
37      * routine in that case."
38      * 
39      * @param singleOctets
40      *            non-null string containing only single octet characters
41      * @param dest
42      *            destination byte array
43      * 
44      * @return the actual length of the destination byte array holding data
45      * @throws IllegalArgumentException
46      *             if the input string contains any multi-octet character
47      */

48     static int sanitize(final String singleOctets, byte[] dest) {
49         final int capacity = dest.length;
50         final char[] src = singleOctets.toCharArray();
51         int limit=0;
52
53         for (int i=0; i < capacity; i++) {
54             final char c = src[i];
55             
56             if (c == '\r' || c == '\n' || c == ' ')
57                 continue;
58             if (c > Byte.MAX_VALUE)
59                 throw new IllegalArgumentException("Invalid character found at position " + i + for " + singleOctets);
60             dest[limit++] = (byte)c;
61         }
62         return limit;
63     }
64     
65     /**
66      * Returns a byte array representing the given string,
67      * truncating each character into a byte directly.
68      * 
69      * @throws IllegalArgumentException if the input string contains any multi-octet character
70      */

71     public static byte[] toBytesDirect(final String singleOctets) {
72         final char[] src = singleOctets.toCharArray();
73         final byte[] dest = new byte[src.length];
74         
75         for (int i=0; i < dest.length; i++) {
76             final char c = src[i];
77             
78             if (c > Byte.MAX_VALUE)
79                 throw new IllegalArgumentException("Invalid character found at position " + i + for " + singleOctets);
80             dest[i] = (byte)c;
81         }
82         return dest;
83     }
84
85     /**
86      * Returns a string representing the given byte array,
87      * treating each byte as a single octet character.
88      */

89     public static String toStringDirect(final byte[] bytes) {
90         final char[] dest = new char[bytes.length];
91         int i=0;
92         
93         for (byte b: bytes)
94             dest[i++] = (char)b;
95         
96         return new String(dest);
97     }
98     
99     /** 
100      * Sanity check the last decoded position is a possible value.
101      * 
102      * @throws IllegalArgumentException if the given decoded position is
103      * not a possible value produced via the respective encoding 
104      */

105     static void sanityCheckLastPos(int pos, int mask) {
106         if ((pos & mask) != 0) {
107             throw new IllegalArgumentException
108                 ("Invalid last non-pad character detected");
109         }
110     }
111 }