/* * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. Crate 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. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial agreement. */ package io.crate.types; import com.google.common.collect.Ordering; import io.crate.Streamer; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.unit.TimeValue; import java.io.IOException; import java.util.Locale; import java.util.Map; public class StringType extends DataType<BytesRef> implements DataTypeFactory, Streamer<BytesRef> { public static final int ID = 4; public static final StringType INSTANCE = new StringType(); public static final BytesRef T = new BytesRef("t"); public static final BytesRef F = new BytesRef("f"); protected StringType() { } @Override public int id() { return ID; } @Override public String getName() { return "string"; } @Override public Streamer<BytesRef> streamer() { return this; } @Override public BytesRef value(Object value) { if (value == null) { return null; } if (value instanceof BytesRef) { return (BytesRef) value; } if (value instanceof String) { return new BytesRef((String) value); } if (value instanceof Boolean) { if ((boolean) value) { return T; } else { return F; } } if (value instanceof Map || value.getClass().isArray()) { throw new IllegalArgumentException( String.format(Locale.ENGLISH, "Cannot cast %s to type string", value)); } if (value instanceof TimeValue) { return new BytesRef(((TimeValue) value).getStringRep()); } return new BytesRef(value.toString()); } @Override public int compareValueTo(BytesRef val1, BytesRef val2) { return Ordering.natural().nullsFirst().compare(val1, val2); } @Override public DataType<?> create() { return INSTANCE; } @Override public BytesRef readValueFrom(StreamInput in) throws IOException { int length = in.readVInt() - 1; if (length == -1) { return null; } return in.readBytesRef(length); } @Override public void writeValueTo(StreamOutput out, Object v) throws IOException { // .writeBytesRef isn't used here because it will convert null values to empty bytesRefs // to distinguish between null and an empty bytesRef // 1 is always added to the length so that // 0 is null // 1 is 0 // ... if (v == null) { out.writeVInt(0); } else { BytesRef bytesRef = (BytesRef) v; out.writeVInt(bytesRef.length + 1); out.writeBytes(bytesRef.bytes, bytesRef.offset, bytesRef.length); } } }