bool EventResponse::decode(int version, char* buffer, size_t size) {
  StringRef event_type;
  char* pos = decode_string(buffer, &event_type);

  if (event_type == "TOPOLOGY_CHANGE") {
    event_type_ = CASS_EVENT_TOPOLOGY_CHANGE;

    StringRef topology_change;
    pos = decode_string(pos, &topology_change);
    if (topology_change == "NEW_NODE") {
      topology_change_ = NEW_NODE;
    } else if (topology_change == "REMOVED_NODE") {
      topology_change_ = REMOVED_NODE;
    } else if (topology_change == "MOVED_NODE") {
      topology_change_ = MOVED_NODE;
    } else {
      return false;
    }
    decode_inet(pos, &affected_node_);
  } else if (event_type == "STATUS_CHANGE") {
    event_type_ = CASS_EVENT_STATUS_CHANGE;

    StringRef status_change;
    pos = decode_string(pos, &status_change);
    if (status_change == "UP") {
      status_change_ = UP;
    } else if (status_change == "DOWN") {
      status_change_ = DOWN;
    } else {
      return false;
    }
    decode_inet(pos, &affected_node_);
  } else if (event_type == "SCHEMA_CHANGE") {
    event_type_ = CASS_EVENT_SCHEMA_CHANGE;

    // Version 1+: <change>... (all start with change type)
    StringRef schema_change;
    pos = decode_string(pos, &schema_change);
    if (schema_change == "CREATED") {
      schema_change_ = CREATED;
    } else if (schema_change == "UPDATED") {
      schema_change_ = UPDATED;
    } else if (schema_change == "DROPPED") {
      schema_change_ = DROPPED;
    } else {
      return false;
    }

    if (version <= 2) {
      // Version 1 and 2: ...<keyspace><table> ([string][string])
      pos = decode_string(pos, &keyspace_);
      decode_string(pos, &target_);
      schema_change_target_ = target_.size() == 0 ? KEYSPACE : TABLE;
    } else {
      // Version 3+: ...<target><options>
      // <target> = [string]
      // <options> = [string] OR [string][string]

      StringRef target;
      pos = decode_string(pos, &target);
      if (target == "KEYSPACE") {
        schema_change_target_ = KEYSPACE;
      } else if (target == "TABLE") {
        schema_change_target_ = TABLE;
      } else if (target == "TYPE") {
        schema_change_target_ = TYPE;
      } else if (target == "FUNCTION") {
        schema_change_target_ = FUNCTION;
      } else if (target == "AGGREGATE") {
        schema_change_target_ = AGGREGATE;
      } else {
        return false;
      }

      pos = decode_string(pos, &keyspace_);

      if (schema_change_target_ == TABLE ||
          schema_change_target_ == TYPE) {
        decode_string(pos, &target_);
      } else if (schema_change_target_ == FUNCTION ||
                 schema_change_target_ == AGGREGATE) {
        pos = decode_string(pos, &target_);
        decode_stringlist(pos, arg_types_);
      }
    }
  } else {
    return false;
  }

  return true;
}
Beispiel #2
0
void decode_cell(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, struct cc_type *type, SV *output)
{
    unsigned char *bytes;
    STRLEN bytes_len;

    if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) != 0) {
        sv_setsv(output, &PL_sv_undef);
        return;
    }

    switch (type->type_id) {
        case CC_TYPE_ASCII:
        case CC_TYPE_CUSTOM:
        case CC_TYPE_BLOB:
            decode_blob(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_BOOLEAN:
            decode_boolean(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_VARCHAR:
        case CC_TYPE_TEXT:
            decode_utf8(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_INET:
            decode_inet(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_SET:
        case CC_TYPE_LIST:
            decode_list(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_UUID:
        case CC_TYPE_TIMEUUID:
            decode_uuid(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_FLOAT:
            decode_float(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DOUBLE:
            decode_double(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DECIMAL:
            decode_decimal(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_VARINT:
        case CC_TYPE_BIGINT:
        case CC_TYPE_COUNTER:
        case CC_TYPE_TIMESTAMP:
        case CC_TYPE_SMALLINT:
        case CC_TYPE_TINYINT:
        case CC_TYPE_INT:
            decode_varint(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DATE:
            decode_date(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_TIME:
            decode_time(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_MAP:
            decode_map(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_UDT:
            decode_udt(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_TUPLE:
            decode_tuple(aTHX_ bytes, bytes_len, type, output);
            break;

        default:
            sv_setsv(output, &PL_sv_undef);
            warn("Decoder doesn't yet understand type %d, returning undef instead", type->type_id);
            break;
    }
}