/**
* Copyright 2007-2015, Kaazing Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kaazing.specification.wse.internal;
public enum Encoding {
UTF8 {
public byte[] encode(byte[] decoded) {
return encodeBinaryAsText(decoded);
}
public byte[] decode(byte[] encoded) {
return decodeTextAsBinary(encoded);
}
};
public abstract byte[] encode(byte[] decoded);
public abstract byte[] decode(byte[] encoded);
private static byte[] encodeBinaryAsText(byte[] decodedArray) {
int decodedArrayPosition = 0;
byte[] encodedArray = decodedArray;
int candidateEncodedArrayLength = decodedArray.length;
int encodedDataLength = 0;
for (; decodedArrayPosition < decodedArray.length; decodedArrayPosition++) {
byte decodedValue = decodedArray[decodedArrayPosition];
if ((decodedValue & 0x80) != 0) {
// high bit set, requires multi-byte representation in UTF8
candidateEncodedArrayLength++;
byte[] tempArray = new byte[candidateEncodedArrayLength];
System.arraycopy(encodedArray, 0, tempArray, 0,
encodedDataLength);
byte encodedByte0 = (byte) ((((decodedValue & 0xff) >> 6) & 0x03) | 0xc0);
byte encodedByte1 = (byte) (decodedValue & 0xbf);
tempArray[encodedDataLength++] = encodedByte0;
tempArray[encodedDataLength++] = encodedByte1;
encodedArray = tempArray;
} else if (encodedArray != null) {
encodedArray[encodedDataLength++] = decodedValue;
}
}
return encodedArray;
}
private static byte[] decodeTextAsBinary(byte[] encodedArray) {
int encodedArrayPosition = 0;
byte[] candidateDecodedArray = new byte[encodedArray.length];
int decodedDataLength = 0;
for (; encodedArrayPosition < encodedArray.length; encodedArrayPosition++) {
byte encodedByte1 = encodedArray[encodedArrayPosition];
if ((encodedByte1 & 0x80) != 0) {
byte encodedByte2 = encodedArray[++encodedArrayPosition];
byte decodedByte = (byte) ((encodedByte1 << 6) | (encodedByte2 & 0x3f));
candidateDecodedArray[decodedDataLength++] = decodedByte;
} else {
candidateDecodedArray[decodedDataLength++] = encodedByte1;
}
}
byte[] decodedArray;
if (decodedDataLength == encodedArray.length) {
decodedArray = candidateDecodedArray;
} else {
decodedArray = new byte[decodedDataLength];
System.arraycopy(candidateDecodedArray, 0, decodedArray, 0,
decodedDataLength);
}
return decodedArray;
}
}