public void setPosition()

in src/main/java/org/mariadb/jdbc/internal/com/read/resultset/rowprotocol/BinaryRowProtocol.java [99:278]


  public void setPosition(int newIndex) {

    // check NULL-Bitmap that indicate if field is null
    if ((buf[1 + (newIndex + 2) / 8] & (1 << ((newIndex + 2) % 8))) != 0) {
      this.lastValueNull = BIT_LAST_FIELD_NULL;
      return;
    }

    // if not must parse data until reading the desired field
    if (index != newIndex) {
      int internalPos = this.pos;
      if (index == -1 || index > newIndex) {
        // if there wasn't previous non-null read field, or if last field was after searched index,
        // position is set on first field position.
        index = 0;
        internalPos = 1 + (columnInformationLength + 9) / 8; // 0x00 header + NULL-Bitmap length
      } else {
        // start at previous non-null field position if was before searched index
        index++;
        internalPos += length;
      }

      for (; index <= newIndex; index++) {
        if ((buf[1 + (index + 2) / 8] & (1 << ((index + 2) % 8))) == 0) {
          if (index != newIndex) {
            // skip bytes
            switch (columnDefinition[index].getColumnType()) {
              case BIGINT:
              case DOUBLE:
                internalPos += 8;
                break;

              case INTEGER:
              case MEDIUMINT:
              case FLOAT:
                internalPos += 4;
                break;

              case SMALLINT:
              case YEAR:
                internalPos += 2;
                break;

              case TINYINT:
                internalPos += 1;
                break;

              default:
                int type = this.buf[internalPos++] & 0xff;
                switch (type) {
                  case 251:
                    break;

                  case 252:
                    internalPos +=
                        2
                            + (0xffff
                                & (((buf[internalPos] & 0xff)
                                    + ((buf[internalPos + 1] & 0xff) << 8))));
                    break;

                  case 253:
                    internalPos +=
                        3
                            + (0xffffff
                                & ((buf[internalPos] & 0xff)
                                    + ((buf[internalPos + 1] & 0xff) << 8)
                                    + ((buf[internalPos + 2] & 0xff) << 16)));
                    break;

                  case 254:
                    internalPos +=
                        8
                            + ((buf[internalPos] & 0xff)
                                + ((long) (buf[internalPos + 1] & 0xff) << 8)
                                + ((long) (buf[internalPos + 2] & 0xff) << 16)
                                + ((long) (buf[internalPos + 3] & 0xff) << 24)
                                + ((long) (buf[internalPos + 4] & 0xff) << 32)
                                + ((long) (buf[internalPos + 5] & 0xff) << 40)
                                + ((long) (buf[internalPos + 6] & 0xff) << 48)
                                + ((long) (buf[internalPos + 7] & 0xff) << 56));
                    break;

                  default:
                    internalPos += type;
                    break;
                }
                break;
            }
          } else {
            // read asked field position and length
            switch (columnDefinition[index].getColumnType()) {
              case BIGINT:
              case DOUBLE:
                this.pos = internalPos;
                length = 8;
                this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                return;

              case INTEGER:
              case MEDIUMINT:
              case FLOAT:
                this.pos = internalPos;
                length = 4;
                this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                return;

              case SMALLINT:
              case YEAR:
                this.pos = internalPos;
                length = 2;
                this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                return;

              case TINYINT:
                this.pos = internalPos;
                length = 1;
                this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                return;

              default:
                // field with variable length
                int type = this.buf[internalPos++] & 0xff;
                switch (type) {
                  case 251:
                    // null length field
                    // must never occur
                    // null value are set in NULL-Bitmap, not send with a null length indicator.
                    throw new IllegalStateException(
                        "null data is encoded in binary protocol but NULL-Bitmap is not set");

                  case 252:
                    // length is encoded on 3 bytes (0xfc header + 2 bytes indicating length)
                    length =
                        0xffff & ((buf[internalPos++] & 0xff) + ((buf[internalPos++] & 0xff) << 8));
                    this.pos = internalPos;
                    this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                    return;

                  case 253:
                    // length is encoded on 4 bytes (0xfd header + 3 bytes indicating length)
                    length =
                        0xffffff
                            & ((buf[internalPos++] & 0xff)
                                + ((buf[internalPos++] & 0xff) << 8)
                                + ((buf[internalPos++] & 0xff) << 16));
                    this.pos = internalPos;
                    this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                    return;

                  case 254:
                    // length is encoded on 9 bytes (0xfe header + 8 bytes indicating length)
                    length =
                        (int)
                            ((buf[internalPos++] & 0xff)
                                + ((long) (buf[internalPos++] & 0xff) << 8)
                                + ((long) (buf[internalPos++] & 0xff) << 16)
                                + ((long) (buf[internalPos++] & 0xff) << 24)
                                + ((long) (buf[internalPos++] & 0xff) << 32)
                                + ((long) (buf[internalPos++] & 0xff) << 40)
                                + ((long) (buf[internalPos++] & 0xff) << 48)
                                + ((long) (buf[internalPos++] & 0xff) << 56));
                    this.pos = internalPos;
                    this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                    return;

                  default:
                    // length is encoded on 1 bytes (is then less than 251)
                    length = type;
                    this.pos = internalPos;
                    this.lastValueNull = BIT_LAST_FIELD_NOT_NULL;
                    return;
                }
            }
          }
        }
      }
    }
    this.lastValueNull = length == NULL_LENGTH ? BIT_LAST_FIELD_NULL : BIT_LAST_FIELD_NOT_NULL;
  }