Beispiel #1
0
  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;
  }
Beispiel #2
0
  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;
  }
Beispiel #3
0
 Object* at(STATE, size_t index) {
   if(num_fields() <= index) {
     Exception::object_bounds_exceeded_error(state, this, index);
     return NULL;
   }
   return field[index];
 }
Beispiel #4
0
  /* 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];
  }
Beispiel #5
0
  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;
  }
Beispiel #6
0
  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]));
  }
Beispiel #7
0
  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;
  }
Beispiel #8
0
  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;
  }
Beispiel #9
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;
}
Beispiel #10
0
  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;
  }
Beispiel #11
0
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;
}
Beispiel #12
0
  /* 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;
  }
Beispiel #13
0
  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;
  }
Beispiel #14
0
  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;
  }
Beispiel #15
0
/* 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);
}
Beispiel #16
0
 /* The Tuple#fields primitive. */
 Object* Tuple::fields_prim(STATE) {
   return Integer::from(state, num_fields());
 }
Beispiel #17
0
 Object* at(native_int index) {
   if(index < 0 || num_fields() <= index) return cNil;
   return field[index];
 }
Beispiel #18
0
 Object* at(size_t index) {
   if(num_fields() <= index) return NULL;
   return field[index];
 }
Beispiel #19
0
 size_t body_in_bytes() {
   return num_fields() * sizeof(ObjectHeader);
 }
Beispiel #20
0
    Object* at(native_int index) {
      if(index < 0 || num_fields() <= index) return cNil;

      return MemoryHandle::object(reinterpret_cast<VALUE>(field[index]));
    }