/* FIXME: not tested yet */ mm_struct_t * mm_struct_new ( addr_t code_start , addr_t code_end , addr_t data_start , addr_t data_end , addr_t file , addr_t code_ofs , addr_t data_ofs , uint64_t bss_size ) { addr_t pgt_pa = 0; addr_t addr = 0; vma_t *vma_tmp = NULL; vma_t *vma_current= NULL; mm_struct_t *mm_s = (mm_struct_t *)(get_object( objcache_mm_struct_head )); mm_s->code_start = code_start; mm_s->code_end = code_end ; mm_s->data_start = data_start; mm_s->data_end = data_end ; mm_s->stack_start = USTACK_TOP - __PAGE_SIZE; mm_s->brk_start = data_end + bss_size; mm_s->brk_end = mm_s->brk_start; /* setup vma for code */ vma_tmp = (vma_t *)get_object( objcache_vma_head ); vma_set( vma_tmp, code_start, code_end , NULL , NULL, 0, file, code_ofs, 0, 0 ); mm_s->mmap = vma_tmp; vma_current = vma_tmp; /* setup vma for data */ if (data_start < data_end) { vma_tmp = (vma_t *)get_object( objcache_vma_head ); vma_set( vma_tmp, data_start, data_end , mm_s->mmap, vma_current, 0, file, data_ofs, 0, 0 ); vma_current->next = vma_tmp; mm_s->mmap->prev = vma_tmp; } /* setup vma for bss */ if (bss_size > 0) { vma_tmp = (vma_t *)get_object( objcache_vma_head ); vma_set( vma_tmp, data_end , data_end+bss_size, mm_s->mmap, vma_current, 0, file, data_ofs, 0, 0 ); vma_current->next = vma_tmp; mm_s->mmap->prev = vma_tmp; } /* XXX: we always provide user mode stack */ vma_tmp = (vma_t *)get_object(objcache_vma_head); vma_set(vma_tmp, mm_s->stack_start, USTACK_TOP, mm_s->mmap, vma_current, 0, file, data_ofs, 0, 0); vma_current->next = vma_tmp; mm_s->mmap->prev = vma_tmp; /* setup page table */ mm_s->pgt = get_zeroed_page( PG_PGT | PG_SUP | PG_OCP ); pgt_pa = get_pa_from_va( mm_s->pgt ); init_pgt( (mm_s->pgt) ); /* set lv1 page table entry: self-reference entry */ addr = ((addr_t)(mm_s->pgt)) + (8*PGT_ENTRY_LV1_SELFREF); set_pgt_entry( addr, pgt_pa , PGT_P, PGT_EXE, 0x0, 0x0, PGT_RW | PGT_SUP ); /* set lv1 page table entry: kernel page */ addr = ((addr_t)(mm_s->pgt)) + (8*PGT_ENTRY_LV1_KERNEL ); set_pgt_entry( addr, def_pgt_paddr_lv2, PGT_P, PGT_EXE, 0x0, 0x0, PGT_RW | PGT_SUP ); return mm_s; } /* mm_struct_new() */
Object* NativeMethodEnvironment::block() { return get_object(current_native_frame_->block()); }
int pv_get_json_ext(struct sip_msg* msg, pv_param_t* pvp, pv_value_t* val, int flags) { pv_json_t * var ; json_t * obj; json_name * id = (json_name *) pvp->pvn.u.dname; UNUSED(id); if( expand_tag_list( msg, ((json_name *)pvp->pvn.u.dname)->tags ) < 0) { LM_ERR("Cannot expand variables in path\n"); return pv_get_null( msg, pvp, val); } var = get_pv_json(pvp); if( var == NULL ) { /* this is not an error - we simply came across a json spec * pointing a json var which was never set/init */ LM_DBG("Variable named:%.*s not found\n",id->name.len,id->name.s); return pv_get_null( msg, pvp, val); } obj = get_object(var, pvp, NULL, 0, 0); memset(val, 0, sizeof(pv_value_t)); if( obj == NULL ) return pv_get_null( msg, pvp, val); if (pvp->pvi.type == PV_IDX_INT) { if (pv_json_iterate(&obj, pvp, id, val) < 0) { LM_DBG("Failed to iterate\n"); return pv_get_null(msg, pvp, val); } if (val->flags == PV_VAL_STR || val->flags == PV_VAL_NULL) /* val is set */ return 0; /* else we got an object */ } else if (pvp->pvi.type == PV_IDX_ALL) { LM_ERR("\"[*]\" index only supported in for each statement\n"); return pv_get_null(msg, pvp, val); } if( json_object_is_type(obj, json_type_int) ) { val->rs.s = sint2str(json_object_get_int(obj), &val->rs.len); val->ri = json_object_get_int(obj);; val->flags |= PV_VAL_INT|PV_TYPE_INT|PV_VAL_STR; } else if( json_object_is_type(obj, json_type_string)) { val->flags = PV_VAL_STR; val->rs.s = (char*)json_object_get_string( obj ); #if JSON_C_VERSION_NUM >= JSON_C_VERSION_010 val->rs.len = json_object_get_string_len( obj ); #else val->rs.len = strlen(val->rs.s); #endif } else { val->flags = PV_VAL_STR; val->rs.s = (char*)json_object_to_json_string_ext( obj, flags); val->rs.len = strlen(val->rs.s); } return 0; }
/** * This pays for the item, and takes the proper amount of money off the * player. * @param op Player paying. * @param pouch Container (pouch or player) to remove the coins from. * @param to_pay Required amount. * @return Amount still not paid after using "pouch". */ static sint64 pay_from_container(object *op, object *pouch, sint64 to_pay) { sint64 remain; int count, i; object *tmp, *coin_objs[NUM_COINS], *next, *bank_object = NULL; archetype *at; object *who; (void) op; if (pouch->type != PLAYER && pouch->type != CONTAINER) { return to_pay; } remain = to_pay; for (i = 0; i < NUM_COINS; i++) { coin_objs[i] = NULL; } /* This hunk should remove all the money objects from the player/container */ for (tmp = pouch->inv; tmp; tmp = next) { next = tmp->below; if (tmp->type == MONEY) { for (i = 0; i < NUM_COINS; i++) { if (!strcmp(coins[NUM_COINS - 1 - i], tmp->arch->name) && (tmp->value == tmp->arch->clone.value)) { /* This should not happen, but if it does, just merge * the two. */ if (coin_objs[i] != NULL) { LOG(llevBug, "BUG: pay_from_container(): %s has two money entries of (%s)\n", query_name(pouch, NULL), coins[NUM_COINS - 1 - i]); remove_ob(tmp); coin_objs[i]->nrof += tmp->nrof; esrv_del_item(CONTR(pouch), tmp->count, tmp->env); } else { remove_ob(tmp); if (pouch->type == PLAYER) { esrv_del_item(CONTR(pouch), tmp->count,tmp->env); } coin_objs[i] = tmp; } break; } } if (i == NUM_COINS) { LOG(llevBug, "BUG: pay_from_container(): Did not find string match for %s\n", tmp->arch->name); } } else if (tmp->arch->name == shstr_cons.player_info && tmp->name == shstr_cons.BANK_GENERAL) { bank_object = tmp; } } /* Fill in any gaps in the coin_objs array - needed to make change. */ /* Note that the coin_objs array goes from least value to greatest value */ for (i = 0; i < NUM_COINS; i++) { if (coin_objs[i] == NULL) { at = find_archetype(coins[NUM_COINS - 1 - i]); if (at == NULL) { LOG(llevBug, "BUG: pay_from_container(): Could not find %s archetype", coins[NUM_COINS - 1 - i]); } coin_objs[i] = get_object(); copy_object(&at->clone, coin_objs[i], 0); coin_objs[i]->nrof = 0; } } for (i = 0; i < NUM_COINS; i++) { sint64 num_coins; if ((sint64) (coin_objs[i]->nrof * coin_objs[i]->value) > remain) { num_coins = remain / coin_objs[i]->value; if ((num_coins * coin_objs[i]->value) < remain) { num_coins++; } } else { num_coins = coin_objs[i]->nrof; } if (num_coins > ((sint64) 1 << 31)) { LOG(llevDebug, "DEBUG: pay_from_container(): Money overflow value->nrof: number of coins > 2 ^ 32 (type coin %d)\n", i); num_coins = ((sint64) 1 << 31); } remain -= num_coins * coin_objs[i]->value; coin_objs[i]->nrof -= (uint32) num_coins; /* Now start making change. Start at the coin value * below the one we just did, and work down to * the lowest value. */ count = i - 1; while (remain < 0 && count >= 0) { num_coins = -remain / coin_objs[count]->value; coin_objs[count]->nrof += (uint32) num_coins; remain += num_coins * coin_objs[count]->value; count--; } } /* If there's still some remain, that means we could try to pay from * bank. */ if (bank_object && bank_object->value != 0 && remain != 0 && bank_object->value >= remain) { bank_object->value -= remain; remain = 0; } for (i = 0; i < NUM_COINS; i++) { if (coin_objs[i]->nrof) { object *tmp = insert_ob_in_ob(coin_objs[i], pouch); for (who = pouch; who && who->type != PLAYER && who->env != NULL; who = who->env) { } esrv_send_item(who, tmp); esrv_send_item (who, pouch); esrv_update_item(UPD_WEIGHT, who, pouch); if (pouch->type != PLAYER) { esrv_send_item(who, who); esrv_update_item(UPD_WEIGHT, who, who); } } } return remain; }
const T& get( object_id_type id )const { const object& obj = get_object( id ); assert( nullptr != dynamic_cast<const T*>(&obj) ); return static_cast<const T&>(obj); }
void Incidence::setChildUid(QString uid) { get_object()->setCustomProperty("qmlCalendar","child",uid); emit childUidChanged(); }
/* ECMA-262 5.1 Edition 15.12.3 (abstract operation Str) */ static HRESULT stringify(stringify_ctx_t *ctx, jsval_t val) { jsval_t value; HRESULT hres; if(is_object_instance(val) && get_object(val)) { jsdisp_t *obj; DISPID id; obj = iface_to_jsdisp((IUnknown*)get_object(val)); if(!obj) return S_FALSE; hres = jsdisp_get_id(obj, toJSONW, 0, &id); jsdisp_release(obj); if(hres == S_OK) FIXME("Use toJSON.\n"); } /* FIXME: Support replacer replacer. */ hres = maybe_to_primitive(ctx->ctx, val, &value); if(FAILED(hres)) return hres; switch(jsval_type(value)) { case JSV_NULL: if(!append_string(ctx, nullW)) hres = E_OUTOFMEMORY; break; case JSV_BOOL: if(!append_string(ctx, get_bool(value) ? trueW : falseW)) hres = E_OUTOFMEMORY; break; case JSV_STRING: { jsstr_t *str = get_string(value); const WCHAR *ptr = jsstr_flatten(str); if(ptr) hres = json_quote(ctx, ptr, jsstr_length(str)); else hres = E_OUTOFMEMORY; break; } case JSV_NUMBER: { double n = get_number(value); if(is_finite(n)) { const WCHAR *ptr; jsstr_t *str; /* FIXME: Optimize. There is no need for jsstr_t here. */ hres = double_to_string(n, &str); if(FAILED(hres)) break; ptr = jsstr_flatten(str); assert(ptr != NULL); hres = ptr && !append_string_len(ctx, ptr, jsstr_length(str)) ? E_OUTOFMEMORY : S_OK; jsstr_release(str); }else { if(!append_string(ctx, nullW)) hres = E_OUTOFMEMORY; } break; } case JSV_OBJECT: { jsdisp_t *obj; obj = iface_to_jsdisp((IUnknown*)get_object(value)); if(!obj) { hres = S_FALSE; break; } if(!is_callable(obj)) hres = is_class(obj, JSCLASS_ARRAY) ? stringify_array(ctx, obj) : stringify_object(ctx, obj); else hres = S_FALSE; jsdisp_release(obj); break; } case JSV_UNDEFINED: hres = S_FALSE; break; case JSV_VARIANT: FIXME("VARIANT\n"); hres = E_NOTIMPL; break; } jsval_release(value); return hres; }
QString Incidence::description() { return get_object()->description(); }
void Incidence::setDescription(QString &description) { get_object()->setDescription(description, true); //true = isRich }
int example_syscall(struct credential *cred, int index, int op) { /* * Entering the system call should instantiate automata: * * CHECK: [CALE] example_syscall * CHECK: sunrise */ struct object *o; /* * get_object() calls hold(), which should be reflected in two automata * (one which cares about entry and the other, exit): * * CHECK: [CALE] hold * CHECK: new [[A0I0:[0-9]+]]: [[INIT:[0-9]+:0x0]] ('[[A0:.*]]') * CHECK: clone [[A0I0]]:[[INIT]] -> [[A0I1:[0-9]+]]:[[HOLD:[0-9]+:0x1]] * CHECK: [RETE] hold * CHECK: new [[A1I0:[0-9]+]]: [[INIT:[0-9]+:0x0]] ('[[A1:.*]]') * CHECK: clone [[A1I0]]:[[INIT]] -> [[A1I1:[0-9]+]]:[[HOLD:[0-9]+:0x1]] */ int error = get_object(index, &o); if (error != 0) return (error); /* * CHECK: [CALE] hold * CHECK: clone [[A0I0]]:[[INIT]] -> [[A0I2:[0-9]+]]:[[HOLD:[0-9]+:0x1]] * CHECK: [RETE] hold * CHECK: clone [[A1I0]]:[[INIT]] -> [[A1I2:[0-9]+]]:[[HOLD:[0-9]+:0x1]] */ error = get_object(index + 1, &o); if (error != 0) return (error); /* * perform_operation() contains all NOW events: * * CHECK: [ASRT] automaton 0 * CHECK: update [[A0I2]]: [[HOLD]]->[[NOW:[0-9]+:0x1]] * CHECK: [ASRT] automaton 1 * CHECK: update [[A1I2]]: [[HOLD]]->[[NOW:[0-9]+:0x1]] */ return perform_operation(op, o); /* * On leaving the assertion scope, we should be cleaning up: * * CHECK: [RETE] example_syscall * * There should only be one (shared) sunset event: * CHECK: sunset * CHECK-NOT: sunset * * CHECK: update [[A0I0]]: [[INIT]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A0]]': [[A0I0]] * CHECK: update [[A0I1]]: [[HOLD]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A0]]': [[A0I1]] * CHECK: update [[A0I2]]: [[NOW]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A0]]': [[A0I2]] * CHECK: tesla_class_reset [[A0]] * * CHECK: update [[A1I0]]: [[INIT]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A1]]': [[A1I0]] * CHECK: update [[A1I1]]: [[HOLD]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A1]]': [[A1I1]] * CHECK: update [[A1I2]]: [[NOW]]->[[DONE:[0-9]+:0x0]] * CHECK: pass '[[A1]]': [[A1I2]] * CHECK: tesla_class_reset [[A1]] */ }
QString Incidence::uid() { return get_object()->uid(); }
/** * Converts a command name into a `reg_portgroup`. * * @param [in] interp Tcl interpreter to check within * @param [in] name name of portgroup to get * @param [out] errPtr description of error if the portgroup can't be found * @return a portgroup, or NULL if one couldn't be found * @see get_object */ static reg_portgroup* get_portgroup(Tcl_Interp* interp, char* name, reg_error* errPtr) { return (reg_portgroup*)get_object(interp, name, "portgroup", portgroup_obj_cmd, errPtr); }
/** * Moves bolt 'op'. Basically, it just advances a space, and checks for * various things that may stop it. * @param op The bolt object moving. */ void move_bolt(object *op) { int w, r; object *tmp; if (--(op->stats.hp) < 0) { destruct_ob(op); return; } if (!op->direction) { return; } if (blocks_magic(op->map, op->x + DIRX(op), op->y + DIRY(op))) { return; } check_fired_arch(op); if (!OBJECT_ACTIVE(op)) { return; } w = wall(op->map, op->x + DIRX(op), op->y + DIRY(op)); r = reflwall(op->map, op->x + DIRX(op), op->y + DIRY(op), op); if (w && !QUERY_FLAG(op, FLAG_REFLECTING)) { return; } /* We're about to bounce */ if (w || r) { if (op->direction & 1) { op->direction = absdir(op->direction + 4); } else { int left = wall(op->map, op->x + freearr_x[absdir(op->direction - 1)], op->y + freearr_y[absdir(op->direction - 1)]), right = wall(op->map, op->x + freearr_x[absdir(op->direction + 1)], op->y + freearr_y[absdir(op->direction + 1)]); if (left == right) { op->direction = absdir(op->direction + 4); } else if (left) { op->direction = absdir(op->direction + 2); } else if (right) { op->direction = absdir(op->direction - 2); } } update_turn_face(op); return; } if (op->stats.food || !op->stats.hp) { return; } op->stats.food = 1; /* Create a copy of this object and put it ahead */ tmp = get_object(); copy_object(op, tmp, 0); tmp->speed_left = -0.1f; tmp->x += DIRX(tmp); tmp->y += DIRY(tmp); if (!insert_ob_in_map(tmp, op->map, op, 0)) { return; } if (rndm(0, 99) < tmp->stats.Dex) { forklightning(op, tmp); } if (tmp) { if (!tmp->stats.food) { tmp->stats.food = 1; move_bolt(tmp); } else { tmp->stats.food = 0; } } }
/** * Causes op to fork. * @param op Original bolt. * @param tmp First piece of the fork. */ void forklightning(object *op, object *tmp) { mapstruct *m; /* Direction or -1 for left, +1 for right 0 if no new bolt */ int xt, yt, new_dir = 1; /* Stores temporary dir calculation */ int t_dir; /* pick a fork direction. tmp->stats.Con is the left bias * i.e., the chance in 100 of forking LEFT * Should start out at 50, down to 25 for one already going left * down to 0 for one going 90 degrees left off original path*/ /* Fork left */ if (rndm(0, 99) < tmp->stats.Con) { new_dir = -1; } /* Check the new dir for a wall and in the map*/ t_dir = absdir(tmp->direction + new_dir); xt = tmp->x + freearr_x[t_dir]; yt = tmp->y + freearr_y[t_dir]; if (!(m = get_map_from_coord(tmp->map, &xt, &yt)) || wall(m, xt, yt)) { new_dir = 0; } /* OK, we made a fork */ if (new_dir) { object *new_bolt = get_object(); copy_object(tmp, new_bolt, 0); new_bolt->stats.food = 0; /* Reduce chances of subsequent forking */ new_bolt->stats.Dex -= 10; /* Less forks from main bolt too */ tmp->stats.Dex -= 10; /* Adjust the left bias */ new_bolt->stats.Con += 25 * new_dir; new_bolt->speed_left = -0.1f; new_bolt->direction = t_dir; new_bolt->stats.hp++; new_bolt->x = xt; new_bolt->y = yt; /* Reduce daughter bolt damage */ new_bolt->stats.dam /= 2; new_bolt->stats.dam++; /* Reduce father bolt damage */ tmp->stats.dam /= 2; tmp->stats.dam++; if (!insert_ob_in_map(new_bolt, m, op, 0)) { return; } update_turn_face(new_bolt); } }
void Incidence::setParentUid(QString uid) { get_object()->setRelatedTo(uid, KCalCore::Incidence::RelTypeParent); emit parentUidChanged(); }
QString Incidence::summary() { return get_object()->summary(); }
void Incidence::setSiblingUid(QString uid) { get_object()->setCustomProperty("qmlCalendar","sibling",uid); emit siblingUidChanged(); }
void Incidence::setSummary(QString &summary) { get_object()->setSummary(summary, true); //true = isRich }
/** * Converts a command name into a `reg_entry`. * * @param [in] interp Tcl interpreter to check within * @param [in] name name of entry to get * @param [out] errPtr description of error if the entry can't be found * @return an entry, or NULL if one couldn't be found * @see get_object */ static reg_entry* get_entry(Tcl_Interp* interp, char* name, reg_error* errPtr) { return (reg_entry*)get_object(interp, name, "entry", entry_obj_cmd, errPtr); }
int Incidence::priority() { return get_object()->priority(); }
/** * Insert coins into a player. * @param pl Player. * @param value Value of coins to insert (for example, 120 for 1 silver and 20 copper). * @return value. */ sint64 insert_coins(object *pl, sint64 value) { int count; object *tmp, *pouch; archetype *at; for (count = 0; coins[count]; count++) { at = find_archetype(coins[count]); if (at == NULL) { LOG(llevBug, "BUG: Could not find %s archetype", coins[count]); } else if ((value / at->clone.value) > 0) { for (pouch = pl->inv; pouch; pouch = pouch->below) { if (pouch->type == CONTAINER && QUERY_FLAG(pouch, FLAG_APPLIED) && pouch->race && strstr(pouch->race, "gold")) { int w = (int) ((float) at->clone.weight * pouch->weapon_speed); uint32 n = (uint32) (value / at->clone.value); /* Prevent FPE */ if (w == 0) { w = 1; } if (n > 0 && (!pouch->weight_limit || pouch->carrying + w <= (sint32) pouch->weight_limit)) { if (pouch->weight_limit && ((sint32)pouch->weight_limit-pouch->carrying) / w < (sint32) n) { n = (pouch->weight_limit-pouch->carrying) / w; } tmp = get_object(); copy_object(&at->clone, tmp, 0); tmp->nrof = n; value -= tmp->nrof * tmp->value; tmp = insert_ob_in_ob(tmp, pouch); esrv_send_item(pl, tmp); esrv_send_item(pl, pouch); esrv_update_item(UPD_WEIGHT, pl, pouch); esrv_send_item(pl, pl); esrv_update_item(UPD_WEIGHT, pl, pl); } } } if (value / at->clone.value > 0) { tmp = get_object(); copy_object(&at->clone, tmp, 0); tmp->nrof = (uint32) (value / tmp->value); value -= tmp->nrof * tmp->value; tmp = insert_ob_in_ob(tmp, pl); esrv_send_item(pl, tmp); esrv_send_item(pl, pl); esrv_update_item(UPD_WEIGHT, pl, pl); } } } return value; }
void Incidence::setPriority(int priority) { get_object()->setPriority(priority); }
void OnTextEnter(wxCommandEvent& event) { USE_PARAMETER(event); if (update_callback) update_callback->callback_function(get_object()); }
QDate Incidence::creationDate() { KDateTime createdDT = get_object()->created(); return createdDT.date(); }
static auto dispatch(_Functor&& functor, Objects&&... objects) { std::size_t index = type_index<typename std::remove_cv<Types>::type...>::index(std::forward<Objects>(objects)...); return function(index)(std::forward<_Functor>(functor), get_object(std::forward<Objects>(objects))...); }
QString Incidence::parentUid() { return get_object()->relatedTo(KCalCore::Incidence::RelTypeParent); }
void view_set_line_data_func(const char *column, const char *cell, gint column_id) { gtk_tree_view_column_set_cell_data_func(get_column(column), GTK_CELL_RENDERER(get_object(cell)), view_line_cell_data_func, GINT_TO_POINTER(column_id), NULL); }
QString Incidence::childUid() { //As the only relation supported atm is parent, I've to use a customProperty return get_object()->customProperty("qmlCalendar","child"); }
int pv_add_json ( pv_param_t* pvp, json_t * obj ) { json_t *dest; json_name * id; pv_json_t * var; json_tag * tag; int poz; id = (json_name *) pvp->pvn.u.dname; var = get_pv_json(pvp); if( var == NULL ) { if( id->tags ) { LM_ERR("Object is not initialized yet\n"); return -1; } var = (pv_json_t *) pkg_malloc(sizeof(pv_json_t)); if( var == NULL ) { LM_ERR("Out of memory\n"); return -1; } memset(var,0,sizeof(pv_json_t)); var->name = id->name; var->next = all; var->data = obj; all = var; return 0; } if( id ->tags == NULL) { if( var->data ) json_object_put(var->data); var->data = obj; return 0; } dest = get_object(var, pvp, &tag, 1, 1); if( dest == NULL ) { LM_NOTICE("Could not find object with that path\n"); return -1; } if( tag->type & TAG_KEY ) { memcpy(buff,tag->key.s,tag->key.len); buff[tag->key.len] = 0; if( obj == NULL ) json_object_object_del(dest,buff); else json_object_object_add(dest,buff,obj); } if( tag->type & TAG_IDX ) { poz = tag->idx; if( tag->type & TAG_END ) { if( obj == NULL) { LM_ERR("Invalid parameter for deletion\n"); return -1; } json_object_array_add(dest,obj); return 0; } if( poz < 0 ) poz += json_object_array_length(dest); if( poz<0 || poz >= json_object_array_length(dest)) { LM_ERR("Attempting to replace at invalid index in array:%d\n", poz); return -1; } if( obj == NULL) { if( poz >= json_object_array_length(dest)) { LM_ERR("Index out of bounds for deletion\n"); return -1; } json_object_array_del(dest,poz); } else json_object_array_put_idx(dest,poz,obj); } return 0; }
/* ECMA-262 3rd Edition 15.4.4.11 */ static HRESULT Array_sort(script_ctx_t *ctx, vdisp_t *vthis, WORD flags, unsigned argc, jsval_t *argv, jsval_t *r) { jsdisp_t *jsthis, *cmp_func = NULL; jsval_t *vtab, **sorttab = NULL; DWORD length; DWORD i; HRESULT hres = S_OK; TRACE("\n"); hres = get_length(ctx, vthis, &jsthis, &length); if(FAILED(hres)) return hres; if(argc > 1) { WARN("invalid arg_cnt %d\n", argc); return E_FAIL; } if(argc == 1) { if(!is_object_instance(argv[0])) { WARN("arg is not dispatch\n"); return E_FAIL; } cmp_func = iface_to_jsdisp((IUnknown*)get_object(argv[0])); if(!cmp_func || !is_class(cmp_func, JSCLASS_FUNCTION)) { WARN("cmp_func is not a function\n"); if(cmp_func) jsdisp_release(cmp_func); return E_FAIL; } } if(!length) { if(cmp_func) jsdisp_release(cmp_func); if(r) *r = jsval_obj(jsdisp_addref(jsthis)); return S_OK; } vtab = heap_alloc_zero(length * sizeof(*vtab)); if(vtab) { for(i=0; i<length; i++) { hres = jsdisp_get_idx(jsthis, i, vtab+i); if(hres == DISP_E_UNKNOWNNAME) { vtab[i] = jsval_undefined(); hres = S_OK; } else if(FAILED(hres)) { WARN("Could not get elem %d: %08x\n", i, hres); break; } } }else { hres = E_OUTOFMEMORY; } if(SUCCEEDED(hres)) { sorttab = heap_alloc(length*2*sizeof(*sorttab)); if(!sorttab) hres = E_OUTOFMEMORY; } /* merge-sort */ if(SUCCEEDED(hres)) { jsval_t *tmpv, **tmpbuf; INT cmp; tmpbuf = sorttab + length; for(i=0; i < length; i++) sorttab[i] = vtab+i; for(i=0; i < length/2; i++) { hres = sort_cmp(ctx, cmp_func, *sorttab[2*i+1], *sorttab[2*i], &cmp); if(FAILED(hres)) break; if(cmp < 0) { tmpv = sorttab[2*i]; sorttab[2*i] = sorttab[2*i+1]; sorttab[2*i+1] = tmpv; } } if(SUCCEEDED(hres)) { DWORD k, a, b, bend; for(k=2; k < length; k *= 2) { for(i=0; i+k < length; i += 2*k) { a = b = 0; if(i+2*k <= length) bend = k; else bend = length - (i+k); memcpy(tmpbuf, sorttab+i, k*sizeof(jsval_t*)); while(a < k && b < bend) { hres = sort_cmp(ctx, cmp_func, *tmpbuf[a], *sorttab[i+k+b], &cmp); if(FAILED(hres)) break; if(cmp < 0) { sorttab[i+a+b] = tmpbuf[a]; a++; }else { sorttab[i+a+b] = sorttab[i+k+b]; b++; } } if(FAILED(hres)) break; if(a < k) memcpy(sorttab+i+a+b, tmpbuf+a, (k-a)*sizeof(jsval_t*)); } if(FAILED(hres)) break; } } for(i=0; SUCCEEDED(hres) && i < length; i++) hres = jsdisp_propput_idx(jsthis, i, *sorttab[i]); } if(vtab) { for(i=0; i < length; i++) jsval_release(vtab[i]); heap_free(vtab); } heap_free(sorttab); if(cmp_func) jsdisp_release(cmp_func); if(FAILED(hres)) return hres; if(r) *r = jsval_obj(jsdisp_addref(jsthis)); return S_OK; }