Beispiel #1
0
Datei: jv.c Projekt: fblondiau/jq
static jv* jvp_array_write(jv* a, int i) {
  assert(i >= 0);
  jvp_array* array = jvp_array_ptr(*a);

  int pos = i + jvp_array_offset(*a);
  if (pos < array->alloc_length && jvp_refcnt_unshared(a->u.ptr)) {
    // use existing array space
    for (int j = array->length; j <= pos; j++) {
      array->elements[j] = JV_NULL;
    }
    array->length = imax(pos + 1, array->length);
    a->size = imax(i + 1, a->size);
    return &array->elements[pos];
  } else {
    // allocate a new array
    int new_length = imax(i + 1, jvp_array_length(*a));
    jvp_array* new_array = jvp_array_alloc(ARRAY_SIZE_ROUND_UP(new_length));
    int j;
    for (j = 0; j < jvp_array_length(*a); j++) {
      new_array->elements[j] = 
        jv_copy(array->elements[j + jvp_array_offset(*a)]);
    }
    for (; j < new_length; j++) {
      new_array->elements[j] = JV_NULL;
    }
    new_array->length = new_length;
    jvp_array_free(*a);
    jv new_jv = {JV_KIND_ARRAY, 0, 0, new_length, {&new_array->refcnt}};
    *a = new_jv;
    return &new_array->elements[i];
  }
}
Beispiel #2
0
Datei: jv.c Projekt: fblondiau/jq
static int jvp_array_equal(jv a, jv b) {
  if (jvp_array_length(a) != jvp_array_length(b)) 
    return 0;
  if (jvp_array_ptr(a) == jvp_array_ptr(b) &&
      jvp_array_offset(a) == jvp_array_offset(b)) 
    return 1;
  for (int i=0; i<jvp_array_length(a); i++) {
    if (!jv_equal(jv_copy(*jvp_array_read(a, i)), 
                  jv_copy(*jvp_array_read(b, i))))
      return 0;
  }
  return 1;
}
Beispiel #3
0
Datei: jv.c Projekt: CoolCloud/jq
static int jvp_array_equal(jv_nontrivial* a, jv_nontrivial* b) {
  if (jvp_array_length(a) != jvp_array_length(b)) 
    return 0;
  if (jvp_array_ptr(a) == jvp_array_ptr(b) &&
      a->i[0] == b->i[0]) 
    return 1;
  for (int i=0; i<jvp_array_length(a); i++) {
    if (!jv_equal(jv_copy(*jvp_array_read(a, i)), 
                  jv_copy(*jvp_array_read(b,i))))
      return 0;
  }
  return 1;
}
Beispiel #4
0
Datei: jv.c Projekt: CoolCloud/jq
static jv* jvp_array_read(jv_nontrivial* a, int i) {
  if (i >= 0 && i < jvp_array_length(a)) {
    jvp_array* array = jvp_array_ptr(a);
    assert(i + a->i[0] < array->length);
    return &array->elements[i + a->i[0]];
  } else {
    return 0;
  }
}
Beispiel #5
0
Datei: jv.c Projekt: fblondiau/jq
static jv jvp_array_slice(jv a, int start, int end) {
  assert(jv_get_kind(a) == JV_KIND_ARRAY);
  // FIXME: maybe slice should reallocate if the slice is small enough
  assert(0 <= start && start <= end);
  assert(end <= jvp_array_length(a));
  // FIXME FIXME FIXME large offsets
  a.offset += start;
  a.size = end - start;
  return a;
}
Beispiel #6
0
Datei: jv.c Projekt: fblondiau/jq
static jv* jvp_array_read(jv a, int i) {
  assert(jv_get_kind(a) == JV_KIND_ARRAY);
  if (i >= 0 && i < jvp_array_length(a)) {
    jvp_array* array = jvp_array_ptr(a);
    assert(i + jvp_array_offset(a) < array->length);
    return &array->elements[i + jvp_array_offset(a)];
  } else {
    return 0;
  }
}
Beispiel #7
0
Datei: jv.c Projekt: CoolCloud/jq
static jv* jvp_array_write(jv_nontrivial* a, int i) {
  assert(i >= 0);
  jvp_array* array = jvp_array_ptr(a);

  int pos = i + a->i[0];
  if (pos < array->alloc_length) {
    // maybe we can update it in-place
    // FIXME: this "optimisation" can cause circular references
    #if 0
    int can_write_past_end = 
      array->length <= pos && /* the end of this array has never been used */
      a->i[1] == array->length; /* the current slice sees the end of the array */
    #endif
    int can_write_past_end = 0;
    if (can_write_past_end || jvp_refcnt_unshared(a)) {
      // extend the array
      for (int j = array->length; j <= pos; j++) {
        array->elements[j] = JV_NULL;
      }
      array->length = imax(pos + 1, array->length);
      a->i[1] = imax(pos + 1, a->i[1]);
      return &array->elements[pos];
    }
  }
  
  
  int new_length = imax(i + 1, jvp_array_length(a));
  jvp_array* new_array = jvp_array_alloc(ARRAY_SIZE_ROUND_UP(new_length));
  int j;
  for (j = 0; j < jvp_array_length(a); j++) {
    new_array->elements[j] = jv_copy(array->elements[j + a->i[0]]);
  }
  for (; j < new_length; j++) {
    new_array->elements[j] = JV_NULL;
  }
  new_array->length = new_length;
  jvp_array_free(a);
  a->ptr = &new_array->refcnt;
  a->i[0] = 0;
  a->i[1] = new_length;
  return &new_array->elements[i];
}
Beispiel #8
0
Datei: jv.c Projekt: fblondiau/jq
int jv_array_length(jv j) {
  assert(jv_get_kind(j) == JV_KIND_ARRAY);
  int len = jvp_array_length(j);
  jv_free(j);
  return len;
}