1 package com.quadcap.sql.types; 2 3 40 41 import java.io.ByteArrayInputStream ; 42 import java.io.Externalizable ; 43 import java.io.IOException ; 44 import java.io.InputStream ; 45 import java.io.ObjectInput ; 46 import java.io.ObjectOutput ; 47 48 import com.quadcap.sql.io.ExternalizeProxy; 49 50 import com.quadcap.util.Debug; 51 import com.quadcap.util.Util; 52 53 58 public class ValueOctets extends Value implements Externalizable , ExternalizeProxy { 59 60 int length; 61 byte[] val; 62 63 66 public ValueOctets() {} 67 68 71 public ValueOctets(String s) { 72 int slen = s.length() - 3; 73 if (s.charAt(0) == 'X') { 74 this.length = slen * 4; 75 this.val = new byte[(this.length + 7)/ 8]; 76 int i = 0; 77 int p = 2; 78 if ((slen & 1) == 1) { 79 val[i++] = (byte)Character.digit(s.charAt(p++), 16); 80 } 81 while (i < val.length) { 82 val[i] = (byte)(Character.digit(s.charAt(p++), 16) << 4); 83 val[i] += (byte)Character.digit(s.charAt(p++), 16); 84 i++; 85 } 86 } else { 87 this.length = slen * 1; 88 this.val = new byte[(this.length + 7)/ 8]; 89 for (int i = 0; i < slen; i++) { 90 int t = (i % 8); 91 val[i/8] |= Character.digit(s.charAt(i+2), 2) << t; 92 } 93 } 94 } 95 96 99 public ValueOctets(byte[] val) { 100 init(val); 101 } 102 103 void init(byte[] v) { 104 this.val = new byte[v.length]; 105 this.length = v.length * 8; 106 System.arraycopy(v, 0, val, 0, val.length); 107 } 108 109 112 public ValueOctets(byte[] val, int length) { 113 if (length <= 0) length = val.length * 8; 114 this.length = length; 115 this.val = new byte[(length + 7)/8]; 116 System.arraycopy(val, 0, this.val, 0, 117 Math.min(val.length, this.val.length)); 118 } 119 120 123 public String toString() { 124 StringBuffer sb = new StringBuffer (); 125 int cnt = length / 8; 126 int i = 0; 127 int mod = length % 8; 128 if (mod > 0) { 129 int tmp = val[i++]; 130 if (mod > 4) { 131 sb.append(Character.forDigit((tmp >> 4) & 0xf, 16)); 132 } 133 sb.append(Character.forDigit(tmp & 0xf, 16)); 134 } 135 while (i < cnt) { 136 int tmp = val[i++]; 137 sb.append(Character.forDigit((tmp >> 4) & 0xf, 16)); 138 sb.append(Character.forDigit(tmp & 0xf, 16)); 139 } 140 return sb.toString(); 141 } 142 143 146 public Value unop(int op) throws ValueException { 147 switch (op) { 148 case Op.NULL: 149 return ValueBoolean.falseBoolean; 150 default: 151 throw new ValueException("Unary op: " + Op.toString(op) + 152 " not implemented for this type"); 153 } 154 } 155 156 159 public Value binop(int op, Value l) throws ValueException { 160 return l.binop(op, this); 161 } 162 163 166 public Value binop(int op, ValueNull r) throws ValueException { 167 switch (op) { 168 case Op.EQ: 169 case Op.NE: 170 case Op.LT: 171 case Op.LE: 172 case Op.GT: 173 case Op.GE: 174 return ValueUnknown.valueUnknown; 175 case Op.COMPARE: 176 return r.valCmpNull(); 177 default: 178 throw badBinop(op, r); 179 } 180 } 181 182 185 public Value binop(int op, ValueOctets r) throws ValueException { 186 switch (op) { 187 case Op.EQ: 188 return new ValueBoolean(0 == Util.compareBytes(val, r.val)); 189 case Op.NE: 190 return new ValueBoolean(0 != Util.compareBytes(val, r.val)); 191 case Op.LT: 192 return new ValueBoolean(0 > Util.compareBytes(val, r.val)); 193 case Op.LE: 194 return new ValueBoolean(0 >= Util.compareBytes(val, r.val)); 195 case Op.GT: 196 return new ValueBoolean(0 < Util.compareBytes(val, r.val)); 197 case Op.GE: 198 return new ValueBoolean(0 <= Util.compareBytes(val, r.val)); 199 case Op.COMPARE: 200 return new ValueInteger(Util.compareBytes(val, r.val)); 201 default: 202 throw badBinop(op, this, r); 203 } 204 } 205 206 209 public void readExternal(ObjectInput in) 210 throws IOException , ClassNotFoundException 211 { 212 length = in.readInt(); 213 int cnt = in.readInt(); 214 val = new byte[cnt]; 215 int rcnt = in.read(val); 216 } 217 218 221 public void writeExternal(ObjectOutput out) 222 throws IOException 223 { 224 out.writeInt(length); 225 out.writeInt(val.length); 226 out.write(val); 227 } 228 229 232 public Object readObject(ObjectInput in) 233 throws IOException , ClassNotFoundException 234 { 235 ValueOctets v = new ValueOctets(); 236 v.readExternal(in); 237 return v; 238 } 239 240 243 public void writeObject(ObjectOutput out, Object object) 244 throws IOException 245 { 246 ((ValueOctets)object).writeExternal(out); 247 } 248 249 252 public Object asJavaObject() { 253 return val; 254 } 255 256 259 public void fromJavaObject(Object obj) throws ValueException { 260 if (obj instanceof byte[]) { 261 init((byte[])obj); 262 } else { 263 throw new ValueException("bad type: " + obj); 264 } 265 } 266 267 270 public final byte[] getBytes() { 271 return val; 272 } 273 274 277 public final int getLength() { return length; } 278 279 282 public final InputStream getBinaryStream() { 283 return new ByteArrayInputStream (val); 284 } 285 286 289 public Value convert(TypeBinary type) throws ValueException { 290 if (length != type.getMax()) { 291 return new ValueOctets(val, type.getMax()); 292 } 293 return this; 294 } 295 296 299 public Value convert(TypeVarBinary type) throws ValueException { 300 if (length > type.getMax()) { 301 return new ValueOctets(val, type.getMax()); 302 } 303 return this; 304 } 305 306 309 public Value convert(TypeBlob type) throws ValueException { 310 int blobLen = (length + 7) / 8; 311 byte[] blobVal = val; 312 if (blobLen != blobVal.length) { 313 blobVal = new byte[blobLen]; 314 System.arraycopy(val, 0, blobVal, 0, blobLen); 315 } 316 return new ValueBlob(blobVal); 317 } 318 319 322 public Value convert(TypeBoolean type) throws ValueException { 323 for (int i = 0; i < val.length; i++) { 324 if (val[i] != 0) return ValueBoolean.trueBoolean; 325 } 326 return ValueBoolean.falseBoolean; 327 } 328 329 332 public Value convert(TypeVarChar type) throws ValueException { 333 String s = new String (val, 0, (length+7)/8); 334 if (type.getMax() > 0 && s.length() > type.getMax()) { 335 s = s.substring(0, type.getMax()); 337 } 338 return new ValueString(s); 339 } 340 341 344 public Value convert(TypeChar type) throws ValueException { 345 String s = new String (val, 0, (length+7)/8); 346 if (type.getMax() > 0 && s.length() > type.getMax()) { 347 s = s.substring(0, type.getMax()); 349 } 350 while (s.length() < type.getMax()) { 351 s = s + " "; 352 } 353 return new ValueString(s); 354 } 355 356 359 public Type getType() { 360 return new TypeBinary(length); 361 } 362 363 366 public void serializeKey(KeyStream out) throws IOException { 367 out.write(val); 368 } 369 } 370 | Popular Tags |