1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package org.apache.hadoop.hbase.types;
19
20 import org.apache.hadoop.hbase.classification.InterfaceAudience;
21 import org.apache.hadoop.hbase.classification.InterfaceStability;
22 import org.apache.hadoop.hbase.util.Order;
23 import org.apache.hadoop.hbase.util.PositionedByteRange;
24
25 import com.google.protobuf.CodedInputStream;
26 import com.google.protobuf.CodedOutputStream;
27 import com.google.protobuf.Message;
28 import org.apache.hadoop.hbase.util.Order;
29 import org.apache.hadoop.hbase.util.PositionedByteRange;
30
31 /**
32 * A base-class for {@link DataType} implementations backed by protobuf. See
33 * {@code PBKeyValue} in {@code hbase-examples} module.
34 */
35 @InterfaceAudience.Public
36 @InterfaceStability.Evolving
37 public abstract class PBType<T extends Message> implements DataType<T> {
38 @Override
39 public boolean isOrderPreserving() {
40 return false;
41 }
42
43 @Override
44 public Order getOrder() {
45 return null;
46 }
47
48 @Override
49 public boolean isNullable() {
50 return false;
51 }
52
53 @Override
54 public boolean isSkippable() {
55 return true;
56 }
57
58 @Override
59 public int encodedLength(T val) {
60 return val.getSerializedSize();
61 }
62
63 /**
64 * Create a {@link CodedInputStream} from a {@link PositionedByteRange}. Be sure to update
65 * {@code src}'s position after consuming from the stream.
66 * <p>For example:
67 * <pre>
68 * Foo.Builder builder = ...
69 * CodedInputStream is = inputStreamFromByteRange(src);
70 * Foo ret = builder.mergeFrom(is).build();
71 * src.setPosition(src.getPosition() + is.getTotalBytesRead());
72 * </pre>
73 */
74 public static CodedInputStream inputStreamFromByteRange(PositionedByteRange src) {
75 return CodedInputStream.newInstance(
76 src.getBytes(),
77 src.getOffset() + src.getPosition(),
78 src.getRemaining());
79 }
80
81 /**
82 * Create a {@link CodedOutputStream} from a {@link PositionedByteRange}. Be sure to update
83 * {@code dst}'s position after writing to the stream.
84 * <p>For example:
85 * <pre>
86 * CodedOutputStream os = outputStreamFromByteRange(dst);
87 * int before = os.spaceLeft(), after, written;
88 * val.writeTo(os);
89 * after = os.spaceLeft();
90 * written = before - after;
91 * dst.setPosition(dst.getPosition() + written);
92 * </pre>
93 */
94 public static CodedOutputStream outputStreamFromByteRange(PositionedByteRange dst) {
95 return CodedOutputStream.newInstance(
96 dst.getBytes(),
97 dst.getOffset() + dst.getPosition(),
98 dst.getRemaining()
99 );
100 }
101 }