/** * 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; import java.util.ArrayList; import java.util.List; import java.util.Random; import org.kaazing.k3po.lang.el.Function; import org.kaazing.k3po.lang.el.spi.FunctionMapperSpi; public final class Functions { private static final Random RANDOM = new Random(); private static final byte[] allBytes = new byte[256]; private static final Byte BYTE_7F = new Byte((byte) 0x7f); static { for (int i = 0; i < 256; i++) { allBytes[i] = (byte) i; } } @Function public static byte[] uniqueId() { byte[] bytes = new byte[16]; RANDOM.nextBytes(bytes); return Base64.encode(bytes); } @Function public static byte[] allBytes() { byte[] bytes = new byte[256]; for (int i = 0; i < 256; i++) { bytes[i] = (byte) i; } return bytes; } @Function public static byte[] randomBytes(int length) { byte[] bytes = new byte[length]; for (int i = 0; i < length; i++) { bytes[i] = (byte) RANDOM.nextInt(0x100); } return bytes; } @Function public static byte[] randomBytesIncludingNumberOfEscapedBytes(int length, int numberOfEscapedBytesToInclude) { byte[] bytes = new byte[length]; byte[] escapedBytes = {0b00000000, 0b00001101, 0b00001010, 0b01111111}; for (int i = 0; i < length; i++) { if ((length - i) / 2 < numberOfEscapedBytesToInclude) { bytes[i] = escapedBytes[RANDOM.nextInt(escapedBytes.length)]; numberOfEscapedBytesToInclude--; } else { byte randomByte = (byte) RANDOM.nextInt(100); switch (randomByte) { case 0b00000000: case 0b00001101: case 0b00001010: case 0b01111111: if (numberOfEscapedBytesToInclude > 0) { bytes[i] = randomByte; numberOfEscapedBytesToInclude--; } else { i--; } break; default: bytes[i] = randomByte; } } } return bytes; } @Function public static byte[] convertEscapedUtf8BytesToEscapedWindows1252(byte[] in) { byte[] out = new byte[in.length]; for (int i = 0; i < in.length; i++) { out[i] = in[i] == 0x00 ? 0x30 : in[i]; } return out; } @Function public static byte[] decodeUtf8Bytes(byte[] bytes) { return Encoding.UTF8.decode(bytes); } @Function public static byte[] encodeBytesAsUtf8(byte[] bytes) { return Encoding.UTF8.encode(bytes); } @Function public static byte[] escapeBytesForUtf8(byte[] bytes) { List<Byte> listOfEscapedBytes = new ArrayList<Byte>(); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; switch (b) { case 0x00: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x00)); break; case 0x0a: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x6e)); break; case 0x0d: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x72)); break; case 0x7f: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(BYTE_7F); break; default: listOfEscapedBytes.add(new Byte(b)); } } bytes = new byte[listOfEscapedBytes.size()]; for (int i = 0; i < listOfEscapedBytes.size(); i++) { bytes[i] = listOfEscapedBytes.get(i); } return bytes; } @Function public static byte[] escapeBytesForWindows1252(byte[] bytes) { List<Byte> listOfEscapedBytes = new ArrayList<Byte>(); for (int i = 0; i < bytes.length; i++) { byte b = bytes[i]; switch (b) { case 0x00: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x30)); break; case 0x0a: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x6e)); break; case 0x0d: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(new Byte((byte) 0x72)); break; case 0x7f: listOfEscapedBytes.add(BYTE_7F); listOfEscapedBytes.add(BYTE_7F); break; default: listOfEscapedBytes.add(new Byte(b)); } } bytes = new byte[listOfEscapedBytes.size()]; for (int i = 0; i < listOfEscapedBytes.size(); i++) { bytes[i] = listOfEscapedBytes.get(i); } return bytes; } @Function public static byte[] padding(int size) { if ((size & 1) != 0) { size += 1; } byte[] padding = new byte[size + 2]; padding[0] = 0x01; for (int i = 1; i < padding.length - 2; i += 2) { padding[i] = 0x30; padding[i + 1] = 0x30; } padding[padding.length - 1] = (byte) 0xFF; return padding; } @Function public static int randomInt(int upperBound) { return RANDOM.nextInt(upperBound); } @Function public static String asString(int value) { return Integer.toString(value); } @Function public static String append(String... strings) { StringBuilder result = new StringBuilder(); for (String string : strings) { result.append(string); } return result.toString(); } public static class Mapper extends FunctionMapperSpi.Reflective { public Mapper() { super(Functions.class); } @Override public String getPrefixName() { return "wse"; } } private Functions() { // utility } }