blob: 2511b1b44357d8d0a6eb30de7e862fcd36673fe9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.ratis.examples.arithmetic.expression;
import static org.apache.ratis.util.ProtoUtils.toByteString;
import org.apache.ratis.examples.arithmetic.Evaluable;
import org.apache.ratis.protocol.Message;
import org.apache.ratis.util.Preconditions;
public interface Expression extends Evaluable {
enum Type {
NULL, VARIABLE, DOUBLE, BINARY, UNARY;
byte byteValue() {
return (byte) ordinal();
}
private static final Type[] VALUES = Type.values();
static Type valueOf(byte b) {
Preconditions.assertTrue(b >= 0);
Preconditions.assertTrue(b < VALUES.length);
return VALUES[b];
}
}
int toBytes(byte[] buf, int offset);
int length();
final class Utils {
private Utils() {}
public static Message toMessage(final Expression e) {
final byte[] buf = new byte[e.length()];
final int length = e.toBytes(buf, 0);
Preconditions.assertTrue(length == buf.length);
return Message.valueOf(toByteString(buf), () -> "Message:" + e);
}
public static Expression double2Expression(Double d) {
return d == null? NullValue.getInstance(): new DoubleValue(d);
}
public static Expression bytes2Expression(byte[] buf, int offset) {
final Type type = Type.valueOf(buf[offset]);
switch(type) {
case NULL: return NullValue.getInstance();
case DOUBLE: return new DoubleValue(buf, offset);
case VARIABLE: return new Variable(buf, offset);
case BINARY: return new BinaryExpression(buf, offset);
case UNARY: return new UnaryExpression(buf, offset);
default:
throw new AssertionError("Unknown expression type " + type);
}
}
public static int int2bytes(int v, byte[] buf, int offset) {
buf[offset ] = (byte) (v >>> 24);
buf[offset + 1] = (byte) (v >>> 16);
buf[offset + 2] = (byte) (v >>> 8);
buf[offset + 3] = (byte) (v);
return 4;
}
public static int long2bytes(long v, byte[] buf, int offset) {
int2bytes((int)(v >>> 32), buf, offset);
int2bytes((int) v , buf, offset + 4);
return 8;
}
public static int double2bytes(double d, byte[] buf, int offset) {
final long v = Double.doubleToRawLongBits(d);
return long2bytes(v, buf, offset);
}
public static int bytes2int(byte[] buf, int offset) {
return ((int) buf[offset] << 24)
+ ((0xFF & buf[offset + 1]) << 16)
+ ((0xFF & buf[offset + 2]) << 8)
+ (0xFF & buf[offset + 3]);
}
public static long bytes2long(byte[] buf, int offset) {
return ((long)bytes2int(buf, offset) << 32)
+ (0xFFFFFFFFL & bytes2int(buf, offset + 4));
}
public static double bytes2double(byte[] buf, int offset) {
final long v = bytes2long(buf, offset);
return Double.longBitsToDouble(v);
}
}
}