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.util; 019 020import org.apache.yetus.audience.InterfaceAudience; 021import org.apache.yetus.audience.InterfaceStability; 022 023/** 024 * Extends the basic {@link SimpleByteRange} implementation with position support. {@code position} 025 * is considered transient, not fundamental to the definition of the range, and does not participate 026 * in {@link #compareTo(ByteRange)}, {@link #hashCode()}, or {@link #equals(Object)}. 027 * {@code Position} is retained by copy operations. 028 */ 029@InterfaceAudience.Private 030@InterfaceStability.Evolving 031public abstract class AbstractPositionedByteRange extends AbstractByteRange 032 implements PositionedByteRange { 033 /** 034 * The current index into the range. Like {@link java.nio.ByteBuffer} position, it points to the 035 * next value that will be read/written in the array. It provides the appearance of being 036 * 0-indexed, even though its value is calculated according to offset. 037 * <p> 038 * Position is considered transient and does not participate in {@link #equals(Object)} or 039 * {@link #hashCode()} comparisons. 040 * </p> 041 */ 042 protected int position = 0; 043 044 protected int limit = 0; 045 046 @Override 047 public PositionedByteRange set(int capacity) { 048 this.position = 0; 049 super.set(capacity); 050 this.limit = capacity; 051 return this; 052 } 053 054 @Override 055 public PositionedByteRange set(byte[] bytes) { 056 this.position = 0; 057 super.set(bytes); 058 this.limit = bytes.length; 059 return this; 060 } 061 062 @Override 063 public PositionedByteRange set(byte[] bytes, int offset, int length) { 064 this.position = 0; 065 super.set(bytes, offset, length); 066 limit = length; 067 return this; 068 } 069 070 /** 071 * Update the beginning of this range. {@code offset + length} may not be greater than 072 * {@code bytes.length}. Resets {@code position} to 0. the new start of this range. 073 * @return this. 074 */ 075 @Override 076 public PositionedByteRange setOffset(int offset) { 077 this.position = 0; 078 super.setOffset(offset); 079 return this; 080 } 081 082 /** 083 * Update the length of this range. {@code offset + length} should not be greater than 084 * {@code bytes.length}. If {@code position} is greater than the new {@code length}, sets 085 * {@code position} to {@code length}. The new length of this range. 086 * @return this. 087 */ 088 @Override 089 public PositionedByteRange setLength(int length) { 090 this.position = Math.min(position, length); 091 super.setLength(length); 092 return this; 093 } 094 095 @Override 096 public int getPosition() { 097 return position; 098 } 099 100 @Override 101 public PositionedByteRange setPosition(int position) { 102 this.position = position; 103 return this; 104 } 105 106 @Override 107 public int getRemaining() { 108 return length - position; 109 } 110 111 @Override 112 public byte peek() { 113 return bytes[offset + position]; 114 } 115 116 @Override 117 public byte get() { 118 return get(position++); 119 } 120 121 @Override 122 public PositionedByteRange get(byte[] dst) { 123 if (0 == dst.length) { 124 return this; 125 } 126 127 return this.get(dst, 0, dst.length); // be clear we're calling self, not super 128 } 129 130 @Override 131 public PositionedByteRange get(byte[] dst, int offset, int length) { 132 if (0 == length) { 133 return this; 134 } 135 136 super.get(this.position, dst, offset, length); 137 this.position += length; 138 return this; 139 } 140 141 // java boilerplate 142 143 @Override 144 public PositionedByteRange get(int index, byte[] dst) { 145 super.get(index, dst); 146 return this; 147 } 148 149 @Override 150 public PositionedByteRange get(int index, byte[] dst, int offset, int length) { 151 super.get(index, dst, offset, length); 152 return this; 153 } 154 155 @Override 156 public short getShort() { 157 short s = getShort(position); 158 position += Bytes.SIZEOF_SHORT; 159 return s; 160 } 161 162 @Override 163 public int getInt() { 164 int i = getInt(position); 165 position += Bytes.SIZEOF_INT; 166 return i; 167 } 168 169 @Override 170 public long getLong() { 171 long l = getLong(position); 172 position += Bytes.SIZEOF_LONG; 173 return l; 174 } 175 176 @Override 177 public long getVLong() { 178 long p = getVLong(position); 179 position += getVLongSize(p); 180 return p; 181 } 182 183 @Override 184 public PositionedByteRange setLimit(int limit) { 185 this.limit = limit; 186 return this; 187 } 188 189 @Override 190 public int getLimit() { 191 return this.limit; 192 } 193}