1 24 25 package com.mckoi.database; 26 27 import com.mckoi.database.global.*; 28 import com.mckoi.util.BigNumber; 29 import java.util.zip.*; 30 import java.util.Date ; 31 import java.math.*; 32 import java.io.*; 33 34 41 42 final class DataCellSerialization extends ByteArrayOutputStream 43 implements CellInput { 44 45 49 private Deflater deflater; 50 private Inflater inflater; 51 private byte[] compress_buf; 52 private int compress_length; 53 54 57 private boolean use_compressed; 58 59 62 private short type; 63 64 67 private boolean is_null; 68 69 72 DataCellSerialization() { 73 super(1024); 74 } 75 76 77 81 int skipSerialization(CellInput din) throws IOException { 82 int len = din.readInt(); 83 return len - 4; 84 } 85 86 89 Object readSerialization(CellInput din) throws IOException { 90 91 count = 0; 92 93 int len = din.readInt(); 95 short s = din.readShort(); 96 type = (short) (s & 0x0FFF); 97 is_null = (s & 0x02000) != 0; 98 use_compressed = (s & 0x04000) != 0; 99 100 if (use_compressed) { 102 int uncompressed_len = din.readInt(); 104 if (buf.length < uncompressed_len) { 105 buf = new byte[uncompressed_len]; 106 } 107 108 compress_length = len - 4 - 2 - 4; 110 if (compress_buf == null || compress_buf.length < compress_length) { 111 compress_buf = new byte[compress_length]; 112 } 113 din.readFully(compress_buf, 0, compress_length); 114 115 if (inflater == null) { 116 inflater = new Inflater(); 117 } 118 inflater.reset(); 119 inflater.setInput(compress_buf, 0, compress_length); 120 int inflate_count; 121 try { 122 inflate_count = inflater.inflate(buf, 0, uncompressed_len); 123 } 124 catch (DataFormatException e) { 125 throw new RuntimeException (e.getMessage()); 126 } 127 128 din = this; 129 130 } 131 132 return readFromCellInput(din); 133 } 134 135 138 private BigNumber createBigNumber(byte[] buf, int scale, byte state) { 139 return BigNumber.fromData(buf, scale, state); 141 } 142 143 148 private Object readFromCellInput(CellInput din) throws IOException { 149 150 if (is_null) { 152 return null; 153 } 154 else { 155 if (type == Types.DB_NUMERIC) { 158 int scale = din.readShort(); 159 int num_len = din.readInt(); 160 byte[] buf = new byte[num_len]; 161 din.readFully(buf, 0, num_len); 162 163 return createBigNumber(buf, scale, (byte) 0); 164 } 165 else if (type == Types.DB_NUMERIC_EXTENDED) { 166 byte state = din.readByte(); 167 int scale = din.readShort(); 168 int num_len = din.readInt(); 169 byte[] buf = new byte[num_len]; 170 din.readFully(buf, 0, num_len); 171 172 return createBigNumber(buf, scale, state); 173 } 174 else if (type == Types.DB_STRING) { 175 int str_length = din.readInt(); 176 if (str_length == 0) { 178 return ""; 179 } 180 181 String dastr = din.readChars(str_length); 182 return dastr.intern(); 184 } 185 else if (type == Types.DB_BOOLEAN) { 186 if (din.readByte() == 0) { 187 return Boolean.FALSE; 188 } 189 else { 190 return Boolean.TRUE; 191 } 192 } 193 else if (type == Types.DB_TIME) { 194 return new java.util.Date (din.readLong()); 195 } 196 else if (type == Types.DB_BLOB) { 197 int blob_length = din.readInt(); 198 if (blob_length == 0) { 200 return EMPTY_BYTE_LONG_OBJECT; 201 } 202 203 byte[] buf = new byte[blob_length]; 204 din.readFully(buf, 0, blob_length); 205 206 return new ByteLongObject(buf); 207 } 208 else if (type == Types.DB_OBJECT) { 209 int blob_length = din.readInt(); 210 211 byte[] buf = new byte[blob_length]; 212 din.readFully(buf, 0, blob_length); 213 214 return new ByteLongObject(buf); 215 } 216 else { 217 throw new Error ("Don't understand type: " + type); 218 } 219 220 } 221 222 } 223 224 227 void writeSerialization(DataOutputStream out) throws IOException { 228 int len = use_compressed ? (compress_length + 4) : count; 229 len += 4 + 2; 231 out.writeInt(len); 232 short s = type; 233 if (is_null) { 234 s |= 0x02000; 235 } 236 if (use_compressed) { 237 s |= 0x04000; 238 } 239 out.writeShort(s); 240 241 if (use_compressed) { 243 out.writeInt(count); 245 out.write(compress_buf, 0, compress_length); 246 } 247 else { 248 out.write(buf, 0, count); 249 } 250 251 } 253 254 257 void setToSerialize(TObject cell) throws IOException { 258 259 is_null = false; 260 count = 0; 261 use_compressed = false; 262 263 TType ttype = cell.getTType(); 264 if (ttype instanceof TStringType) { 265 type = Types.DB_STRING; 266 } 267 else if (ttype instanceof TNumericType) { 268 type = Types.DB_NUMERIC_EXTENDED; 271 } 272 else if (ttype instanceof TBooleanType) { 273 type = Types.DB_BOOLEAN; 274 } 275 else if (ttype instanceof TDateType) { 276 type = Types.DB_TIME; 277 } 278 else if (ttype instanceof TBinaryType) { 279 type = Types.DB_BLOB; 280 } 281 else if (ttype instanceof TJavaObjectType) { 282 type = Types.DB_OBJECT; 283 } 284 else { 285 throw new Error ("Couldn't handle type: " + ttype.getClass()); 286 } 287 288 if (cell.isNull()) { 289 is_null = true; 290 return; 291 } 292 293 Object ob = cell.getObject(); 294 295 writeToBuffer(cell); 297 298 300 TType type = cell.getTType(); 302 if (type instanceof TStringType || 303 type instanceof TBinaryType || 304 type instanceof TJavaObjectType) { 305 int length = count; 306 if (length > 150) { 308 309 if (deflater == null) { 310 deflater = new Deflater(); 311 } 312 313 deflater.setInput(buf, 0, length); 314 deflater.finish(); 315 316 if (compress_buf == null || compress_buf.length < length) { 317 compress_buf = new byte[length]; 318 } 319 compress_length = deflater.deflate(compress_buf); 320 deflater.reset(); 321 322 if (compress_length < length) { 323 use_compressed = true; 324 } 325 } 326 } 327 328 } 329 330 333 private void writeToBuffer(TObject cell) throws IOException { 334 335 Object ob = cell.getObject(); 336 337 if (ob instanceof BigNumber) { 338 BigNumber ddc = (BigNumber) ob; 339 byte[] buf = ddc.toByteArray(); 340 writeByte(ddc.getState()); 341 writeShort((short) ddc.getScale()); 342 writeInt(buf.length); 343 write(buf); 344 } 345 else if (ob instanceof String ) { 346 String str = (String ) ob; 347 writeInt(str.length()); 348 writeChars(str); 349 } 350 else if (ob instanceof Boolean ) { 351 Boolean bool = (Boolean ) ob; 352 writeByte((byte) (bool.booleanValue() ? 1 : 0)); 353 } 354 else if (ob instanceof java.util.Date ) { 355 Date date = (Date ) ob; 356 writeLong(date.getTime()); 357 } 358 else if (ob instanceof ByteLongObject) { 359 ByteLongObject blob = (ByteLongObject) ob; 360 writeInt(blob.length()); 361 write(blob.getByteArray()); 362 } 363 else { 364 throw new Error ("Don't know how to serialize class " + ob.getClass()); 365 } 366 367 } 368 369 public final void writeBoolean(boolean v) throws IOException { 370 write(v ? 1 : 0); 371 } 372 373 public final void writeByte(int v) throws IOException { 374 write(v); 375 } 376 377 public final void writeShort(int v) throws IOException { 378 write((v >>> 8) & 0xFF); 379 write((v >>> 0) & 0xFF); 380 } 381 382 public final void writeChar(int v) throws IOException { 383 write((v >>> 8) & 0xFF); 384 write((v >>> 0) & 0xFF); 385 } 386 387 public final void writeInt(int v) throws IOException { 388 write((v >>> 24) & 0xFF); 389 write((v >>> 16) & 0xFF); 390 write((v >>> 8) & 0xFF); 391 write((v >>> 0) & 0xFF); 392 } 393 394 public final void writeLong(long v) throws IOException { 395 write((int)(v >>> 56) & 0xFF); 396 write((int)(v >>> 48) & 0xFF); 397 write((int)(v >>> 40) & 0xFF); 398 write((int)(v >>> 32) & 0xFF); 399 write((int)(v >>> 24) & 0xFF); 400 write((int)(v >>> 16) & 0xFF); 401 write((int)(v >>> 8) & 0xFF); 402 write((int)(v >>> 0) & 0xFF); 403 } 404 405 public final void writeChars(String s) throws IOException { 406 int len = s.length(); 407 for (int i = 0 ; i < len ; ++i) { 408 int v = s.charAt(i); 409 write((v >>> 8) & 0xFF); 410 write((v >>> 0) & 0xFF); 411 } 412 } 413 414 415 416 418 public int read() throws IOException { 419 return buf[count++] & 0x0FF; 420 } 421 422 public int read(byte b[], int off, int len) throws IOException { 423 if (len <= 0) { 424 return 0; 425 } 426 System.arraycopy(buf, count, b, off, len); 427 count += len; 428 return len; 429 } 430 431 public long skip(long n) throws IOException { 432 if (n < 0) { 433 return 0; 434 } 435 count += n; 436 return n; 437 } 438 439 public int available() throws IOException { 440 throw new Error ("Not supported"); 441 } 442 443 public void mark(int readAheadLimit) throws IOException { 444 throw new Error ("Not supported"); 445 } 446 447 452 public void close() throws IOException { 453 throw new Error ("Not supported"); 454 } 455 456 457 459 public void readFully(byte[] b) throws IOException { 460 read(b, 0, b.length); 461 } 462 463 public void readFully(byte b[], int off, int len) throws IOException { 464 read(b, off, len); 465 } 466 467 public int skipBytes(int n) throws IOException { 468 return (int) skip(n); 469 } 470 471 public boolean readBoolean() throws IOException { 472 return (read() != 0); 473 } 474 475 public byte readByte() throws IOException { 476 return (byte) read(); 477 } 478 479 public int readUnsignedByte() throws IOException { 480 return read(); 481 } 482 483 public short readShort() throws IOException { 484 int ch1 = read(); 485 int ch2 = read(); 486 return (short)((ch1 << 8) + (ch2 << 0)); 487 } 488 489 public int readUnsignedShort() throws IOException { 490 int ch1 = read(); 491 int ch2 = read(); 492 return (ch1 << 8) + (ch2 << 0); 493 } 494 495 public char readChar() throws IOException { 496 int ch1 = read(); 497 int ch2 = read(); 498 return (char)((ch1 << 8) + (ch2 << 0)); 499 } 500 501 private char[] char_buffer; 502 503 public String readChars(int length) throws IOException { 504 if (length <= 8192) { 505 if (char_buffer == null) { 506 char_buffer = new char[8192]; 507 } 508 for (int i = 0; i < length; ++i) { 509 char_buffer[i] = readChar(); 510 } 511 return new String (char_buffer, 0, length); 512 } 513 else { 514 StringBuffer chrs = new StringBuffer (length); 515 for (int i = length; i > 0; --i) { 516 chrs.append(readChar()); 517 } 518 return new String (chrs); 519 } 520 } 521 522 public int readInt() throws IOException { 523 int ch1 = read(); 524 int ch2 = read(); 525 int ch3 = read(); 526 int ch4 = read(); 527 return (int)((ch1 << 24) + (ch2 << 16) + 528 (ch3 << 8) + (ch4 << 0)); 529 } 530 531 public long readLong() throws IOException { 532 return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL); 533 } 534 535 public float readFloat() throws IOException { 536 return Float.intBitsToFloat(readInt()); 537 } 538 539 public double readDouble() throws IOException { 540 return Double.longBitsToDouble(readLong()); 541 } 542 543 public String readLine() throws IOException { 544 throw new Error ("Not implemented."); 545 } 546 547 public String readUTF() throws IOException { 548 throw new Error ("Not implemented."); 549 } 550 551 553 556 private static final ByteLongObject EMPTY_BYTE_LONG_OBJECT = 557 new ByteLongObject(new byte[0]); 558 559 } 560 | Popular Tags |