Tuple* Tuple::tuple_dup(STATE) { native_int fields = num_fields(); Tuple* tup = state->vm()->new_young_tuple_dirty(fields); if(likely(tup)) { for(native_int i = 0; i < fields; i++) { Object *obj = field[i]; // fields equals size so bounds checking is unecessary tup->field[i] = obj; // Because tup is promised to be a young object, // we can elide the write barrier usage. } return tup; } // Otherwise, use slower creation path that might create // a mature object. tup = create(state, fields); for(native_int i = 0; i < fields; i++) { Object *obj = field[i]; // fields equals size so bounds checking is unecessary tup->field[i] = obj; tup->write_barrier(state, obj); } return tup; }
Object* Tuple::put(STATE, native_int idx, Object* val) { assert(idx >= 0 && idx < num_fields()); this->field[idx] = val; if(val->reference_p()) write_barrier(state, val); return val; }
Object* at(STATE, size_t index) { if(num_fields() <= index) { Exception::object_bounds_exceeded_error(state, this, index); return NULL; } return field[index]; }
/* The Tuple#at primitive. */ Object* Tuple::at_prim(STATE, Fixnum* index_obj) { native_int index = index_obj->to_native(); if(index < 0 || num_fields() <= index) { return bounds_exceeded_error(state, "Tuple::at_prim", index); } return field[index]; }
Object* Tuple::put(STATE, native_int idx, Object* val) { if(idx < 0 || idx >= num_fields()) { rubinius::bug("Invalid tuple index"); } field[idx] = val; write_barrier(state, val); return val; }
Object* RTuple::at_prim(STATE, Fixnum* idx) { native_int index = idx->to_native(); if(index < 0 || num_fields() <= index) { return bounds_exceeded_error(state, "RTuple::at_prim", index); } return MemoryHandle::object(reinterpret_cast<VALUE>(field[index])); }
Object* Tuple::put(STATE, size_t idx, Object* val) { if(num_fields() <= idx) { Exception::object_bounds_exceeded_error(state, this, idx); } this->field[idx] = val; if(val->reference_p()) write_barrier(state, val); return val; }
Tuple* Tuple::bounds_exceeded_error(STATE, const char* method, int index) { std::ostringstream msg; msg << method; msg << ": index " << index << " out of bounds for size " << num_fields(); Exception::object_bounds_exceeded_error(state, msg.str().c_str()); return 0; }
static int parse_msg_type(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) { int is_err, remaining_fields; if((*t_size = strcspn(*ndx, ":")) < 1) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_MISSING); if(*t_size > MAX_SPA_MESSAGE_TYPE_SIZE) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_TOOBIG); strlcpy(tbuf, *ndx, *t_size+1); ctx->message_type = strtol_wrapper(tbuf, 0, FKO_LAST_MSG_TYPE-1, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL); /* Now that we have a valid type, ensure that the total * number of SPA fields is also valid for the type */ remaining_fields = num_fields(*ndx); switch(ctx->message_type) { /* optional server_auth + digest */ case FKO_COMMAND_MSG: case FKO_ACCESS_MSG: if(remaining_fields > 2) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; /* nat or client timeout + optional server_auth + digest */ case FKO_NAT_ACCESS_MSG: case FKO_LOCAL_NAT_ACCESS_MSG: case FKO_CLIENT_TIMEOUT_ACCESS_MSG: if(remaining_fields > 3) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; /* client timeout + nat + optional server_auth + digest */ case FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG: case FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG: if(remaining_fields > 4) return FKO_ERROR_INVALID_DATA_DECODE_WRONG_NUM_FIELDS; break; default: /* Should not reach here */ return(FKO_ERROR_INVALID_DATA_DECODE_MSGTYPE_DECODEFAIL); } *ndx += *t_size + 1; return FKO_SUCCESS; }
Tuple* Tuple::tuple_dup(STATE) { native_int fields = num_fields(); Tuple* tup = Tuple::create(state, fields); for(native_int i = 0; i < fields; i++) { tup->put(state, i, field[i]); } return tup; }
bool CMySql::fetch_assoc(){ bool res = fetch_row(); if(res){ m_assoc->Clear(); int cnt = num_fields(); for(int i = 0; i < cnt; i++){ m_assoc->add(assoc_str[i] + "=" + STR(Row[i])); } } return res; }
/* The Tuple#put primitive. */ Object* Tuple::put_prim(STATE, Fixnum* index, Object* val) { native_int idx = index->to_native(); if(idx < 0 || num_fields() <= idx) { return bounds_exceeded_error(state, "Tuple::put_prim", idx); } field[idx] = val; write_barrier(state, val); return val; }
Object* Tuple::reverse(STATE, Fixnum* o_start, Fixnum* o_total) { native_int start = o_start->to_native(); native_int total = o_total->to_native(); if(total <= 0 || start < 0 || start >= num_fields()) return this; native_int end = start + total - 1; if(end >= num_fields()) end = num_fields() - 1; Object** pos1 = field + start; Object** pos2 = field + end; register Object* tmp; while(pos1 < pos2) { tmp = *pos1; *pos1++ = *pos2; *pos2-- = tmp; } return this; }
Object* RTuple::put_prim(STATE, Fixnum* idx, Object* val) { native_int index = idx->to_native(); if(index < 0 || num_fields() <= index) { return bounds_exceeded_error(state, "RTuple::put_prim", index); } reinterpret_cast<VALUE*>(field)[index] = MemoryHandle::value(val); state->memory()->write_barrier(this, val); return val; }
/* Decode the encoded SPA data. */ int fko_decode_spa_data(fko_ctx_t ctx) { char *tbuf, *ndx; int t_size, i, res; /* Array of function pointers to SPA field parsing functions */ int (*field_parser[FIELD_PARSERS])(char *tbuf, char **ndx, int *t_size, fko_ctx_t ctx) = { parse_rand_val, /* Extract random value */ parse_username, /* Extract username */ parse_timestamp, /* Client timestamp */ parse_version, /* SPA version */ parse_msg_type, /* SPA msg type */ parse_msg, /* SPA msg string */ parse_nat_msg, /* SPA NAT msg string */ parse_server_auth, /* optional server authentication method */ parse_client_timeout /* client defined timeout */ }; if (! is_valid_encoded_msg_len(ctx->encoded_msg_len)) return(FKO_ERROR_INVALID_DATA_DECODE_MSGLEN_VALIDFAIL); /* Make sure there are no non-ascii printable chars */ for (i=0; i < (int)strnlen(ctx->encoded_msg, MAX_SPA_ENCODED_MSG_SIZE); i++) if(isprint((int)(unsigned char)ctx->encoded_msg[i]) == 0) return(FKO_ERROR_INVALID_DATA_DECODE_NON_ASCII); /* Make sure there are enough fields in the SPA packet * delimited with ':' chars */ ndx = ctx->encoded_msg; if (num_fields(ndx) < MIN_SPA_FIELDS) return(FKO_ERROR_INVALID_DATA_DECODE_LT_MIN_FIELDS); ndx += last_field(ndx); t_size = strnlen(ndx, SHA512_B64_LEN+1); /* Validate digest length */ res = is_valid_digest_len(t_size, ctx); if(res != FKO_SUCCESS) return res; if(ctx->digest != NULL) free(ctx->digest); /* Copy the digest into the context and terminate the encoded data * at that point so the original digest is not part of the * encoded string. */ ctx->digest = strdup(ndx); if(ctx->digest == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Chop the digest off of the encoded_msg bucket... */ bzero((ndx-1), t_size); ctx->encoded_msg_len -= t_size+1; /* Make a tmp bucket for processing base64 encoded data and * other general use. */ tbuf = calloc(1, FKO_ENCODE_TMP_BUF_SIZE); if(tbuf == NULL) return(FKO_ERROR_MEMORY_ALLOCATION); /* Can now verify the digest. */ res = verify_digest(tbuf, t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return(FKO_ERROR_DIGEST_VERIFICATION_FAILED); } /* Now we will work through the encoded data and extract (and base64- * decode where necessary), the SPA data fields and populate the context. */ ndx = ctx->encoded_msg; for (i=0; i < FIELD_PARSERS; i++) { res = (*field_parser[i])(tbuf, &ndx, &t_size, ctx); if(res != FKO_SUCCESS) { free(tbuf); return res; } } /* Done with the tmp buffer. */ free(tbuf); /* Call the context initialized. */ ctx->initval = FKO_CTX_INITIALIZED; FKO_SET_CTX_INITIALIZED(ctx); return(FKO_SUCCESS); }
/* The Tuple#fields primitive. */ Object* Tuple::fields_prim(STATE) { return Integer::from(state, num_fields()); }
Object* at(native_int index) { if(index < 0 || num_fields() <= index) return cNil; return field[index]; }
Object* at(size_t index) { if(num_fields() <= index) return NULL; return field[index]; }
size_t body_in_bytes() { return num_fields() * sizeof(ObjectHeader); }
Object* at(native_int index) { if(index < 0 || num_fields() <= index) return cNil; return MemoryHandle::object(reinterpret_cast<VALUE>(field[index])); }