001/** 002 * GRANITE DATA SERVICES 003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S. 004 * 005 * This file is part of the Granite Data Services Platform. 006 * 007 * Granite Data Services is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * Granite Data Services is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this library; if not, write to the Free Software 019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 020 * USA, or see <http://www.gnu.org/licenses/>. 021 */ 022package org.granite.messaging.jmf.codec.std.impl.util; 023 024import java.io.IOException; 025import java.io.OutputStream; 026 027import org.granite.messaging.jmf.InputContext; 028import org.granite.messaging.jmf.OutputContext; 029 030/** 031 * @author Franck WOLFF 032 */ 033public class LongUtil { 034 035 // ------------------------------------------------------------------------ 036 037 public static void encodeLong(OutputContext ctx, long v) throws IOException { 038 final OutputStream os = ctx.getOutputStream(); 039 040 os.write((int)(v >>> 56)); 041 os.write((int)(v >>> 48)); 042 os.write((int)(v >>> 40)); 043 os.write((int)(v >>> 32)); 044 os.write((int)(v >>> 24)); 045 os.write((int)(v >>> 16)); 046 os.write((int)(v >>> 8)); 047 os.write((int)v); 048 } 049 050 public static long decodeLong(InputContext ctx) throws IOException { 051 return ( 052 ctx.safeReadLong() << 56 | 053 ctx.safeReadLong() << 48 | 054 ctx.safeReadLong() << 40 | 055 ctx.safeReadLong() << 32 | 056 ctx.safeReadLong() << 24 | 057 ctx.safeReadLong() << 16 | 058 ctx.safeReadLong() << 8 | 059 ctx.safeReadLong() 060 ); 061 } 062 063 // ------------------------------------------------------------------------ 064 065 public static int significantLongBytesCount0(long v) { 066 if (v < 0L) 067 return 7; 068 if (v <= 0xFFFFFFFFL) { 069 if (v <= 0xFFFFL) 070 return (v <= 0xFFL ? 0 : 1); 071 return (v <= 0xFFFFFFL ? 2 : 3); 072 } 073 if (v <= 0xFFFFFFFFFFFFL) 074 return (v <= 0xFFFFFFFFFFL ? 4 : 5); 075 return (v <= 0xFFFFFFFFFFFFFFL ? 6 : 7); 076 } 077 078 public static void encodeLong(OutputContext ctx, long v, int significantLongBytesCount0) throws IOException { 079 final OutputStream os = ctx.getOutputStream(); 080 081 switch (significantLongBytesCount0) { 082 case 7: 083 os.write((int)(v >>> 56)); 084 case 6: 085 os.write((int)(v >>> 48)); 086 case 5: 087 os.write((int)(v >>> 40)); 088 case 4: 089 os.write((int)(v >>> 32)); 090 case 3: 091 os.write((int)(v >>> 24)); 092 case 2: 093 os.write((int)(v >>> 16)); 094 case 1: 095 os.write((int)(v >>> 8)); 096 case 0: 097 os.write((int)v); 098 } 099 } 100 101 public static long decodeLong(InputContext ctx, int significantLongBytesCount0) throws IOException { 102 long v = 0L; 103 104 switch (significantLongBytesCount0) { 105 case 7: 106 v |= ctx.safeReadLong() << 56; 107 case 6: 108 v |= ctx.safeReadLong() << 48; 109 case 5: 110 v |= ctx.safeReadLong() << 40; 111 case 4: 112 v |= ctx.safeReadLong() << 32; 113 case 3: 114 v |= ctx.safeReadLong() << 24; 115 case 2: 116 v |= ctx.safeReadLong() << 16; 117 case 1: 118 v |= ctx.safeReadLong() << 8; 119 case 0: 120 v |= ctx.safeReadLong(); 121 } 122 123 return v; 124 } 125 126 // ------------------------------------------------------------------------ 127 128 public static final long MIN_1_BYTES_VARIABLE_LONG = -0x40L; 129 public static final long MAX_1_BYTES_VARIABLE_LONG = 0x3FL; 130 131 public static final long MIN_2_BYTES_VARIABLE_LONG = -0x2040L; 132 public static final long MAX_2_BYTES_VARIABLE_LONG = 0x203FL; 133 134 public static final long MIN_3_BYTES_VARIABLE_LONG = -0x102040L; 135 public static final long MAX_3_BYTES_VARIABLE_LONG = 0x10203FL; 136 137 public static final long MIN_4_BYTES_VARIABLE_LONG = -0x8102040L; 138 public static final long MAX_4_BYTES_VARIABLE_LONG = 0x810203FL; 139 140 public static final long MIN_5_BYTES_VARIABLE_LONG = -0x408102040L; 141 public static final long MAX_5_BYTES_VARIABLE_LONG = 0x40810203FL; 142 143 public static final long MIN_6_BYTES_VARIABLE_LONG = -0x20408102040L; 144 public static final long MAX_6_BYTES_VARIABLE_LONG = 0x2040810203FL; 145 146 public static final long MIN_7_BYTES_VARIABLE_LONG = -0x1020408102040L; 147 public static final long MAX_7_BYTES_VARIABLE_LONG = 0x102040810203FL; 148 149 public static final long MIN_8_BYTES_VARIABLE_LONG = -0x81020408102040L; 150 public static final long MAX_8_BYTES_VARIABLE_LONG = 0x8102040810203FL; 151 152 // ------------------------------------------------------------------------ 153 154 public static void encodeVariableLong(OutputContext ctx, long v) throws IOException { 155 encodeVariableUnsignedLong(ctx, (v << 1) ^ (v >> 63)); 156 } 157 158 public static long decodeVariableLong(InputContext ctx) throws IOException { 159 long v = decodeVariableUnsignedLong(ctx); 160 return ((v & 0x1L) == 0 ? (v >>> 1) : (-1L ^ (v >>> 1))); 161 } 162 163 // ------------------------------------------------------------------------ 164 165 public static void encodeVariableUnsignedLong(OutputContext ctx, long v) throws IOException { 166 final OutputStream os = ctx.getOutputStream(); 167 168 if (v >= 0 && v < 0x102040810204080L) { 169 170 if (v < 0x10204080L) { 171 if (v < 0x4080L) { 172 if (v < 0x80L) 173 os.write((int)v); 174 else { 175 v -= 0x80L; 176 os.write(0x80 | (int)v); 177 os.write((int)(v >>> 7)); 178 } 179 } 180 else if (v < 0x204080L) { 181 v -= 0x4080L; 182 os.write(0x80 | (int)v); 183 os.write(0x80 | (int)(v >>> 7)); 184 os.write((int)(v >>> 14)); 185 } 186 else { 187 v -= 0x204080L; 188 os.write(0x80 | (int)v); 189 os.write(0x80 | (int)(v >>> 7)); 190 os.write(0x80 | (int)(v >>> 14)); 191 os.write((int)(v >>> 21)); 192 } 193 } 194 else if (v < 0x40810204080L){ 195 if (v < 0x810204080L) { 196 v -= 0x10204080L; 197 os.write(0x80 | (int)v); 198 os.write(0x80 | (int)(v >>> 7)); 199 os.write(0x80 | (int)(v >>> 14)); 200 os.write(0x80 | (int)(v >>> 21)); 201 os.write((int)(v >>> 28)); 202 } 203 else { 204 v -= 0x810204080L; 205 os.write(0x80 | (int)v); 206 os.write(0x80 | (int)(v >>> 7)); 207 os.write(0x80 | (int)(v >>> 14)); 208 os.write(0x80 | (int)(v >>> 21)); 209 os.write(0x80 | (int)(v >>> 28)); 210 os.write((int)(v >>> 35)); 211 } 212 } 213 else if (v < 0x2040810204080L) { 214 v -= 0x40810204080L; 215 os.write(0x80 | (int)v); 216 os.write(0x80 | (int)(v >>> 7)); 217 os.write(0x80 | (int)(v >>> 14)); 218 os.write(0x80 | (int)(v >>> 21)); 219 os.write(0x80 | (int)(v >>> 28)); 220 os.write(0x80 | (int)(v >>> 35)); 221 os.write((int)(v >>> 42)); 222 } 223 else { 224 v -= 0x2040810204080L; 225 os.write(0x80 | (int)v); 226 os.write(0x80 | (int)(v >>> 7)); 227 os.write(0x80 | (int)(v >>> 14)); 228 os.write(0x80 | (int)(v >>> 21)); 229 os.write(0x80 | (int)(v >>> 28)); 230 os.write(0x80 | (int)(v >>> 35)); 231 os.write(0x80 | (int)(v >>> 42)); 232 os.write((int)(v >>> 49)); 233 } 234 } 235 else { 236 os.write(0x80 | (int)v); 237 os.write(0x80 | (int)(v >>> 7)); 238 os.write(0x80 | (int)(v >>> 14)); 239 os.write(0x80 | (int)(v >>> 21)); 240 os.write(0x80 | (int)(v >>> 28)); 241 os.write(0x80 | (int)(v >>> 35)); 242 os.write(0x80 | (int)(v >>> 42)); 243 os.write(0x80 | (int)(v >>> 49)); 244 os.write((int)(v >>> 56)); 245 } 246 } 247 248 public static long decodeVariableUnsignedLong(InputContext ctx) throws IOException { 249 long v = ctx.safeReadLong(); 250 251 if ((v & 0x80L) != 0) { 252 v = (v & 0x7FL) | (ctx.safeReadLong() << 7); 253 254 if ((v & 0x4000L) != 0) { 255 v = (v & 0x3FFFL) | (ctx.safeReadLong() << 14); 256 257 if ((v & 0x200000L) != 0) { 258 v = (v & 0x1FFFFFL) | (ctx.safeReadLong() << 21); 259 260 if ((v & 0x10000000L) != 0) { 261 v = (v & 0xFFFFFFFL) | (ctx.safeReadLong() << 28); 262 263 if ((v & 0x800000000L) != 0) { 264 v = (v & 0x7FFFFFFFFL) | (ctx.safeReadLong() << 35); 265 266 if ((v & 0x40000000000L) != 0) { 267 v = (v & 0x3FFFFFFFFFFL) | (ctx.safeReadLong() << 42); 268 269 if ((v & 0x2000000000000L) != 0) { 270 v = (v & 0x1FFFFFFFFFFFFL) | (ctx.safeReadLong() << 49); 271 272 if ((v & 0x100000000000000L) != 0) 273 v = (v & 0xFFFFFFFFFFFFFFL) | (ctx.safeReadLong() << 56); 274 else 275 v += 0x2040810204080L; 276 } 277 else 278 v += 0x40810204080L; 279 } 280 else 281 v += 0x810204080L; 282 } 283 else 284 v += 0x10204080L; 285 } 286 else 287 v += 0x204080L; 288 } 289 else 290 v += 0x4080L; 291 } 292 else 293 v += 0x80L; 294 } 295 296 return v; 297 } 298}