1 21 package org.apache.derby.impl.store.raw.data; 22 23 import org.apache.derby.iapi.store.raw.RecordHandle; 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 26 import java.io.IOException ; 27 import java.io.EOFException ; 28 29 import java.io.ObjectInput ; 30 import java.io.OutputStream ; 31 32 import org.apache.derby.iapi.services.io.ArrayInputStream; 33 import org.apache.derby.iapi.services.io.CompressedNumber; 34 35 import java.io.InputStream ; 36 37 114 public final class StoredFieldHeader 115 { 116 117 121 122 private static final int FIELD_INITIAL = 0x00; 125 public static final int FIELD_NULL = 0x01; 126 public static final int FIELD_OVERFLOW = 0x02; 127 private static final int FIELD_NOT_NULLABLE = 0x04; 128 public static final int FIELD_EXTENSIBLE = 0x08; 129 public static final int FIELD_TAGGED = 0x10; 130 protected static final int FIELD_FIXED = 0x20; 131 132 public static final int FIELD_NONEXISTENT = (FIELD_NOT_NULLABLE | FIELD_NULL); 133 134 135 public static final int STORED_FIELD_HEADER_STATUS_SIZE = 1; 136 137 141 142 147 public static final boolean isNull(int status) { 148 return ((status & FIELD_NULL) == FIELD_NULL); 149 } 150 151 public static final boolean isOverflow(int status) { 152 return ((status & FIELD_OVERFLOW) == FIELD_OVERFLOW); 153 } 154 155 public static final boolean isNonexistent(int status) { 156 return ((status & FIELD_NONEXISTENT) == FIELD_NONEXISTENT); 157 } 158 159 public static final boolean isExtensible(int status) { 160 return ((status & FIELD_EXTENSIBLE) == FIELD_EXTENSIBLE); 161 } 162 163 public static final boolean isNullorNonExistent(int status) { 164 return ((status & FIELD_NULL) != 0); 167 } 168 169 public static final boolean isTagged(int status) { 170 return ((status & FIELD_TAGGED) == FIELD_TAGGED); 173 } 174 175 public static final boolean isFixed(int status) { 176 return ((status & FIELD_FIXED) == FIELD_FIXED); 177 } 178 179 public static final boolean isNullable(int status) { 180 return ((status & FIELD_NOT_NULLABLE) == 0); 181 } 182 183 public static final int size( 184 int status, 185 int fieldDataLength, 186 int fieldDataSize) 187 { 188 189 if ((status & (FIELD_NULL | FIELD_FIXED)) == 0) 190 { 191 193 199 if (fieldDataLength <= 200 CompressedNumber.MAX_COMPRESSED_INT_ONE_BYTE) 201 { 202 return(2); 204 } 205 else if (fieldDataLength <= 206 CompressedNumber.MAX_COMPRESSED_INT_TWO_BYTES) 207 { 208 return(3); 210 } 211 else 212 { 213 return(5); 215 } 216 } 217 else if ((status & FIELD_NULL) != 0) 218 { 219 221 return(1); 222 } 223 else 224 { 225 227 return((fieldDataSize > 2) ? 5 : 3); 228 } 229 } 230 231 232 236 237 public final static int setInitial() { 238 return FIELD_INITIAL; 239 } 240 241 public final static int setNull(int status, boolean isNull) { 242 if (isNull) 243 status |= FIELD_NULL; 244 else 245 status &= ~FIELD_NULL; 246 return status; 247 } 248 249 public final static int setOverflow(int status, boolean isOverflow) { 250 if (isOverflow) 251 status |= FIELD_OVERFLOW; 252 else 253 status &= ~FIELD_OVERFLOW; 254 return status; 255 } 256 257 public final static int setNonexistent(int status) { 258 status |= FIELD_NONEXISTENT; 259 return status; 260 } 261 262 public final static int setExtensible(int status, boolean isExtensible) { 263 if (isExtensible) 264 status |= FIELD_EXTENSIBLE; 265 else 266 status &= ~FIELD_EXTENSIBLE; 267 return status; 268 } 269 270 public final static int setTagged(int status, boolean isTagged) { 271 272 if (SanityManager.DEBUG) 273 SanityManager.ASSERT(isExtensible(status), 274 "a field cannot be set to tagged if it is not extensible"); 275 276 if (isTagged) 277 status |= FIELD_TAGGED; 278 else 279 status &= ~FIELD_TAGGED; 280 return status; 281 } 282 283 public final static int setFixed(int status, boolean isFixed) { 284 if (isFixed) 285 status |= FIELD_FIXED; 286 else 287 status &= ~FIELD_FIXED; 288 return status; 289 } 290 291 295 296 302 public static final int write( 303 OutputStream out, 304 int status, 305 int fieldDataLength, 306 int fieldDataSize) 307 throws IOException 308 { 309 int len = 1; 310 311 out.write(status); 312 313 if (isNull(status)) 314 return len; 315 316 if (isFixed(status)) 317 { 318 if (fieldDataSize > 2) 321 { 322 int diffLen = 323 fieldDataSize - 324 CompressedNumber.writeInt(out, fieldDataLength); 325 326 for (int i = diffLen; i > 0; i--) 327 out.write(0); 328 len += fieldDataSize; } 330 else 331 { 332 out.write((fieldDataLength >>> 8) & 0xFF); 334 out.write((fieldDataLength >>> 0) & 0xFF); 335 len += 2; } 337 338 343 } 344 else 345 { 346 349 len += CompressedNumber.writeInt(out, fieldDataLength); 350 } 351 352 return len; 353 } 354 355 359 360 366 public static final int readStatus(ObjectInput in) 367 throws IOException 368 { 369 int status; 370 371 if ((status = in.read()) >= 0) 372 return status; 373 else 374 throw new EOFException (); 375 } 376 377 public static final int readStatus( 378 byte[] page, 379 int offset) 380 { 381 return(page[offset]); 382 } 383 384 403 public static final int readTotalFieldLength( 404 byte[] data, 405 int offset) 406 throws IOException 407 { 408 if (SanityManager.DEBUG) 409 { 410 413 if (isFixed(data[offset])) 414 SanityManager.THROWASSERT("routine does not handle FIXED."); 415 } 416 417 if (((data[offset++]) & FIELD_NULL) != FIELD_NULL) 418 { 419 int value = data[offset]; 420 421 if ((value & ~0x3f) == 0) 422 { 423 427 return(value + 2); 429 } 430 else if ((value & 0x80) == 0) 431 { 432 434 if (SanityManager.DEBUG) 435 { 436 SanityManager.ASSERT((value & 0x40) == 0x40); 437 } 438 439 445 447 return((((value & 0x3f) << 8) | (data[offset + 1] & 0xff)) + 3); 448 } 449 else 450 { 451 453 if (SanityManager.DEBUG) 454 { 455 SanityManager.ASSERT((value & 0x80) == 0x80); 456 } 457 458 464 465 return( 467 (((value & 0x7f) << 24) | 468 ((data[offset + 1] & 0xff) << 16) | 469 ((data[offset + 2] & 0xff) << 8) | 470 (data[offset + 3] & 0xff)) + 5); 471 } 472 } 473 else 474 { 475 return(1); 476 } 477 } 478 479 480 public static final int readFieldLengthAndSetStreamPosition( 481 byte[] data, 482 int offset, 483 int status, 484 int fieldDataSize, 485 ArrayInputStream ais) 486 throws IOException 487 { 488 if ((status & (FIELD_NULL | FIELD_FIXED)) == 0) 489 { 490 493 int value = data[offset++]; 494 495 if ((value & ~0x3f) == 0) 496 { 497 499 503 505 } 506 else if ((value & 0x80) == 0) 507 { 508 510 if (SanityManager.DEBUG) 511 { 512 SanityManager.ASSERT((value & 0x40) == 0x40); 513 } 514 515 521 value = (((value & 0x3f) << 8) | (data[offset++] & 0xff)); 522 523 } 524 else 525 { 526 528 if (SanityManager.DEBUG) 529 { 530 SanityManager.ASSERT((value & 0x80) == 0x80); 531 } 532 533 539 540 value = 542 (((value & 0x7f) << 24) | 543 ((data[offset++] & 0xff) << 16) | 544 ((data[offset++] & 0xff) << 8) | 545 (data[offset++] & 0xff)); 546 } 547 548 ais.setPosition(offset); 549 550 return(value); 551 } 552 else if ((status & FIELD_NULL) != 0) 553 { 554 ais.setPosition(offset); 555 return(0); 556 } 557 else 558 { 559 int fieldDataLength; 560 561 563 if (fieldDataSize <= 2) 564 { 565 fieldDataLength = 567 ((data[offset++] & 0xff) << 8) | (data[offset++] & 0xff); 568 } 569 else 570 { 571 573 fieldDataLength = data[offset]; 574 575 if ((fieldDataLength & ~0x3f) == 0) 576 { 577 579 583 585 } 586 else if ((fieldDataLength & 0x80) == 0) 587 { 588 590 if (SanityManager.DEBUG) 591 { 592 SanityManager.ASSERT((fieldDataLength & 0x40) == 0x40); 593 } 594 595 601 fieldDataLength = 602 (((fieldDataLength & 0x3f) << 8) | 603 (data[offset + 1] & 0xff)); 604 605 } 606 else 607 { 608 610 if (SanityManager.DEBUG) 611 { 612 SanityManager.ASSERT((fieldDataLength & 0x80) == 0x80); 613 } 614 615 622 fieldDataLength = 623 (((fieldDataLength & 0x7f) << 24) | 624 ((data[offset + 1] & 0xff) << 16) | 625 ((data[offset + 2] & 0xff) << 8) | 626 (data[offset + 3] & 0xff)); 627 } 628 629 offset = offset + fieldDataSize; 630 } 631 632 ais.setPosition(offset); 633 return(fieldDataLength); 634 } 635 636 637 } 638 639 645 public static final int readFieldDataLength( 646 ObjectInput in, 647 int status, 648 int fieldDataSize) 649 throws IOException 650 { 651 652 if ((status & (FIELD_NULL | FIELD_FIXED)) == 0) 653 { 654 return(CompressedNumber.readInt(in)); 656 } 657 else if ((status & FIELD_NULL) != 0) 658 { 659 return(0); 661 } 662 else 663 { 664 int fieldDataLength; 665 666 668 if (fieldDataSize <= 2) 669 { 670 int ch1 = in.read(); 672 int ch2 = in.read(); 673 if ((ch1 | ch2) < 0) 674 throw new EOFException (); 675 676 fieldDataLength = ((ch1 << 8) + (ch2 << 0)); 677 } 678 else 679 { 680 fieldDataLength = 681 CompressedNumber.readInt(in); 682 683 int diffLen = 684 fieldDataSize - 685 CompressedNumber.sizeInt(fieldDataLength); 686 687 if (diffLen != 0) 688 in.skipBytes(diffLen); 689 } 690 691 return(fieldDataLength); 692 } 693 } 694 695 696 public static String toDebugString(int status) 697 { 698 if (SanityManager.DEBUG) 699 { 700 StringBuffer str = new StringBuffer (100); 701 if (isNull(status)) str.append("Null "); 702 if (isOverflow(status)) str.append("Overflow "); 703 if (isNonexistent(status)) str.append("Nonexistent "); 704 if (isExtensible(status)) str.append("Extensible "); 705 if (isTagged(status)) str.append("Tagged "); 706 if (isFixed(status)) str.append("Fixed "); 707 if (isNullable(status)) str.append("Nullable "); 708 if (str.length() == 0) 709 str.append("INITIAL "); 710 711 return str.toString(); 712 } 713 return null; 714 } 715 } 716 | Popular Tags |