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