1/* 2 * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26struct unpacker; 27 28#define INT_MAX_VALUE ((int)0x7FFFFFFF) 29#define INT_MIN_VALUE ((int)0x80000000) 30 31#define CODING_SPEC(B, H, S, D) ((B)<<20|(H)<<8|(S)<<4|(D)<<0) 32#define CODING_B(x) ((x)>>20 & 0xF) 33#define CODING_H(x) ((x)>>8 & 0xFFF) 34#define CODING_S(x) ((x)>>4 & 0xF) 35#define CODING_D(x) ((x)>>0 & 0xF) 36 37#define CODING_INIT(B, H, S, D) \ 38 { CODING_SPEC(B, H, S, D) , 0, 0, 0, 0, 0, 0, 0, 0} 39 40// For debugging purposes, some compilers do not like this and will complain. 41// #define long do_not_use_C_long_types_use_jlong_or_int 42// Use of the type "long" is problematic, do not use it. 43 44struct coding { 45 int spec; // B,H,S,D 46 47 // Handy values derived from the spec: 48 int B() { return CODING_B(spec); } 49 int H() { return CODING_H(spec); } 50 int S() { return CODING_S(spec); } 51 int D() { return CODING_D(spec); } 52 int L() { return 256-CODING_H(spec); } 53 int min, max; 54 int umin, umax; 55 char isSigned, isSubrange, isFullRange, isMalloc; 56 57 coding* init(); // returns self or null if error 58 coding* initFrom(int spec_) { 59 assert(this->spec == 0); 60 this->spec = spec_; 61 return init(); 62 } 63 64 static coding* findBySpec(int spec); 65 static coding* findBySpec(int B, int H, int S=0, int D=0); 66 static coding* findByIndex(int irregularCodingIndex); 67 68 static uint parse(byte* &rp, int B, int H); 69 static uint parse_lgH(byte* &rp, int B, int H, int lgH); 70 static void parseMultiple(byte* &rp, int N, byte* limit, int B, int H); 71 72 uint parse(byte* &rp) { 73 return parse(rp, CODING_B(spec), CODING_H(spec)); 74 } 75 void parseMultiple(byte* &rp, int N, byte* limit) { 76 parseMultiple(rp, N, limit, CODING_B(spec), CODING_H(spec)); 77 } 78 79 bool canRepresent(int x) { return (x >= min && x <= max); } 80 bool canRepresentUnsigned(int x) { return (x >= umin && x <= umax); } 81 82 int sumInUnsignedRange(int x, int y); 83 84 int readFrom(byte* &rpVar, int* dbase); 85 void readArrayFrom(byte* &rpVar, int* dbase, int length, int* values); 86 void skipArrayFrom(byte* &rpVar, int length) { 87 readArrayFrom(rpVar, (int*)NULL, length, (int*)NULL); 88 } 89 90#ifndef PRODUCT 91 const char* string(); 92#endif 93 94 void free(); // free self if isMalloc 95 96 // error handling 97 static void abort(const char* msg = null) { unpack_abort(msg); } 98}; 99 100enum coding_method_kind { 101 cmk_ERROR, 102 cmk_BHS, 103 cmk_BHS0, 104 cmk_BHS1, 105 cmk_BHSD1, 106 cmk_BHS1D1full, // isFullRange 107 cmk_BHS1D1sub, // isSubRange 108 109 // special cases hand-optimized (~50% of all decoded values) 110 cmk_BYTE1, //(1,256) 6% 111 cmk_CHAR3, //(3,128) 7% 112 cmk_UNSIGNED5, //(5,64) 13% 113 cmk_DELTA5, //(5,64,1,1) 5% 114 cmk_BCI5, //(5,4) 18% 115 cmk_BRANCH5, //(5,4,2) 4% 116//cmk_UNSIGNED5H16, //(5,16) 5% 117//cmk_UNSIGNED2H4, //(2,4) 6% 118//cmk_DELTA4H8, //(4,8,1,1) 10% 119//cmk_DELTA3H16, //(3,16,1,1) 9% 120 cmk_BHS_LIMIT, 121 122 cmk_pop, 123 cmk_pop_BHS0, 124 cmk_pop_BYTE1, 125 cmk_pop_LIMIT, 126 127 cmk_LIMIT 128}; 129 130enum { 131 BYTE1_spec = CODING_SPEC(1, 256, 0, 0), 132 CHAR3_spec = CODING_SPEC(3, 128, 0, 0), 133 UNSIGNED4_spec = CODING_SPEC(4, 256, 0, 0), 134 UNSIGNED5_spec = CODING_SPEC(5, 64, 0, 0), 135 SIGNED5_spec = CODING_SPEC(5, 64, 1, 0), 136 DELTA5_spec = CODING_SPEC(5, 64, 1, 1), 137 UDELTA5_spec = CODING_SPEC(5, 64, 0, 1), 138 MDELTA5_spec = CODING_SPEC(5, 64, 2, 1), 139 BCI5_spec = CODING_SPEC(5, 4, 0, 0), 140 BRANCH5_spec = CODING_SPEC(5, 4, 2, 0) 141}; 142 143enum { 144 B_MAX = 5, 145 C_SLOP = B_MAX*10 146}; 147 148struct coding_method; 149 150// iterator under the control of a meta-coding 151struct value_stream { 152 // current coding of values or values 153 coding c; // B,H,S,D,etc. 154 coding_method_kind cmk; // type of decoding needed 155 byte* rp; // read pointer 156 byte* rplimit; // final value of read pointer 157 int sum; // partial sum of all values so far (D=1 only) 158 coding_method* cm; // coding method that defines this stream 159 160 void init(byte* band_rp, byte* band_limit, coding* defc); 161 void init(byte* band_rp, byte* band_limit, int spec) 162 { init(band_rp, band_limit, coding::findBySpec(spec)); } 163 164 void setCoding(coding* c); 165 void setCoding(int spec) { setCoding(coding::findBySpec(spec)); } 166 167 // Parse and decode a single value. 168 int getInt(); 169 170 // Parse and decode a single byte, with no error checks. 171 int getByte() { 172 assert(cmk == cmk_BYTE1); 173 assert(rp < rplimit); 174 return *rp++ & 0xFF; 175 } 176 177 // Used only for asserts. 178 bool hasValue(); 179 180 void done() { assert(!hasValue()); } 181 182 // Sometimes a value stream has an auxiliary (but there are never two). 183 value_stream* helper() { 184 assert(hasHelper()); 185 return this+1; 186 } 187 bool hasHelper(); 188 189 // error handling 190 // inline void abort(const char* msg); 191 // inline void aborting(); 192}; 193 194struct coding_method { 195 value_stream vs0; // initial state snapshot (vs.meta==this) 196 197 coding_method* next; // what to do when we run out of bytes 198 199 // these fields are used for pop codes only: 200 int* fValues; // favored value array 201 int fVlength; // maximum favored value token 202 coding_method* uValues; // unfavored value stream 203 204 // pointer to outer unpacker, for error checks etc. 205 unpacker* u; 206 207 // Initialize a value stream. 208 void reset(value_stream* state); 209 210 // Parse a band header, size a band, and initialize for further action. 211 // band_rp advances (but not past band_limit), and meta_rp advances. 212 // The mode gives context, such as "inside a pop". 213 // The defc and N are the incoming parameters to a meta-coding. 214 // The value sink is used to collect output values, when desired. 215 void init(byte* &band_rp, byte* band_limit, 216 byte* &meta_rp, int mode, 217 coding* defc, int N, 218 intlist* valueSink); 219 220 // error handling 221 void abort(const char* msg) { unpack_abort(msg, u); } 222 bool aborting() { return unpack_aborting(u); } 223}; 224 225//inline void value_stream::abort(const char* msg) { cm->abort(msg); } 226//inline void value_stream::aborting() { cm->aborting(); } 227