/*
* Licensed to 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.protocols.postgres.types;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.logging.Loggers;
import org.jboss.netty.buffer.ChannelBuffer;
import javax.annotation.Nonnull;
import java.nio.charset.StandardCharsets;
public abstract class PGType {
static final int INT32_BYTE_SIZE = Integer.SIZE / 8;
private final static Logger LOGGER = Loggers.getLogger(PGType.class);
private final int oid;
private final int typeLen;
private final int typeMod;
private final String typName;
PGType(int oid, int typeLen, int typeMod, @Nonnull String typName) {
this.oid = oid;
this.typeLen = typeLen;
this.typeMod = typeMod;
this.typName = typName;
}
public int oid() {
return oid;
}
public int typeLen() {
return typeLen;
}
public int typeMod() {
return typeMod;
}
public String typName() {
return typName;
}
public int typElem() {
return 0;
}
public String typDelim() {
return ",";
}
/**
* Write the value as text into the buffer.
* <p>
* Format:
* <pre>
* | int32 len (excluding len itself) | byte<b>N</b> value onto the buffer
* </pre>
*
* @return the number of bytes written. (4 (int32) + N)
*/
public int writeAsText(ChannelBuffer buffer, @Nonnull Object value) {
byte[] bytes = encodeAsUTF8Text(value);
buffer.writeInt(bytes.length);
buffer.writeBytes(bytes);
return INT32_BYTE_SIZE + bytes.length;
}
public Object readTextValue(ChannelBuffer buffer, int valueLength) {
byte[] bytes = new byte[valueLength];
buffer.readBytes(bytes);
try {
return decodeUTF8Text(bytes);
} catch (Throwable t) {
if (LOGGER.isWarnEnabled()) {
LOGGER.warn("decodeUTF8Text failed. input={} type={}",
new String(bytes, StandardCharsets.UTF_8), typName);
}
throw t;
}
}
/**
* Write the value as binary into the buffer.
* <p>
* Format:
* <pre>
* | int32 len (excluding len itself) | byte<b>N</b> value onto the buffer
* </pre>
*
* @return the number of bytes written. (4 (int32) + N)
*/
public abstract int writeAsBinary(ChannelBuffer buffer, @Nonnull Object value);
public abstract Object readBinaryValue(ChannelBuffer buffer, int valueLength);
/**
* Return the UTF8 encoded text representation of the value
*/
abstract byte[] encodeAsUTF8Text(@Nonnull Object value);
/**
* Convert a UTF8 encoded text representation into the actual value
*/
abstract Object decodeUTF8Text(byte[] bytes);
}