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; }
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; } }