001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.types;
019
020import org.apache.hadoop.hbase.util.Order;
021import org.apache.hadoop.hbase.util.PositionedByteRange;
022import org.apache.yetus.audience.InterfaceAudience;
023
024import org.apache.hbase.thirdparty.com.google.protobuf.CodedInputStream;
025import org.apache.hbase.thirdparty.com.google.protobuf.CodedOutputStream;
026import org.apache.hbase.thirdparty.com.google.protobuf.Message;
027
028/**
029 * A base-class for {@link DataType} implementations backed by protobuf. See {@link PBCell}.
030 * <p/>
031 * Notice that, in hbase we always uses our own shaded version of protobuf, but you are free to use
032 * the original version of protobuf in your own project.
033 */
034@InterfaceAudience.Private
035public abstract class PBType<T extends Message> implements DataType<T> {
036  @Override
037  public boolean isOrderPreserving() {
038    return false;
039  }
040
041  @Override
042  public Order getOrder() {
043    return null;
044  }
045
046  @Override
047  public boolean isNullable() {
048    return false;
049  }
050
051  @Override
052  public boolean isSkippable() {
053    return true;
054  }
055
056  @Override
057  public int encodedLength(T val) {
058    return val.getSerializedSize();
059  }
060
061  /**
062   * Create a {@link CodedInputStream} from a {@link PositionedByteRange}. Be sure to update
063   * {@code src}'s position after consuming from the stream.
064   * <p/>
065   * For example:
066   *
067   * <pre>
068   * Foo.Builder builder = ...
069   * CodedInputStream is = inputStreamFromByteRange(src);
070   * Foo ret = builder.mergeFrom(is).build();
071   * src.setPosition(src.getPosition() + is.getTotalBytesRead());
072   * </pre>
073   */
074  public static CodedInputStream inputStreamFromByteRange(PositionedByteRange src) {
075    return CodedInputStream.newInstance(src.getBytes(), src.getOffset() + src.getPosition(),
076      src.getRemaining());
077  }
078
079  /**
080   * Create a {@link CodedOutputStream} from a {@link PositionedByteRange}. Be sure to update
081   * {@code dst}'s position after writing to the stream.
082   * <p/>
083   * For example:
084   *
085   * <pre>
086   * CodedOutputStream os = outputStreamFromByteRange(dst);
087   * int before = os.spaceLeft(), after, written;
088   * val.writeTo(os);
089   * after = os.spaceLeft();
090   * written = before - after;
091   * dst.setPosition(dst.getPosition() + written);
092   * </pre>
093   */
094  public static CodedOutputStream outputStreamFromByteRange(PositionedByteRange dst) {
095    return CodedOutputStream.newInstance(dst.getBytes(), dst.getOffset() + dst.getPosition(),
096      dst.getRemaining());
097  }
098}