/// Clear out the raw set and cooked sets. Destroy the entire /// cooked data structure but leave the raw one present though /// empty. This is the same as the initial (post-creation) state. /// @param[in] ca the object pointer void ca_clear_pa(ca_o ca) { dict_t *dict; dnode_t *dnp, *next; pa_o pa; if ((dict = ca->ca_raw_pa_dict)) { for (dnp = dict_first(dict); dnp;) { next = dict_next(dict, dnp); pa = (pa_o)dnode_getkey(dnp); dict_delete(dict, dnp); dnode_destroy(dnp); pa_destroy(pa); dnp = next; } } if ((dict = ca->ca_cooked_pa_dict)) { for (dnp = dict_first(dict); dnp;) { next = dict_next(dict, dnp); pa = (pa_o)dnode_getkey(dnp); dict_delete(dict, dnp); dnode_destroy(dnp); pa_destroy(pa); dnp = next; } dict_destroy(ca->ca_cooked_pa_dict); ca->ca_cooked_pa_dict = NULL; } }
static int verify_bintree( TA_Libc *libHandle, dict_t *dict) { dnode_t *first, *next; first = dict_first( libHandle, dict); if (dict->dupes) { if( first ) { next = dict_next( libHandle, dict, first); while (first && next ) { if (dict->compare(libHandle, first->key, next->key) > 0) return 0; first = next; if( first ) next = dict_next( libHandle, dict, first); } } } else { if( first ) { next = dict_next(libHandle, dict, first); while (first && next) { if (dict->compare(libHandle, first->key, next->key) >= 0) return 0; first = next; if( first ) next = dict_next(libHandle, dict, first); } } } return 1; }
static int verify_bintree(dict_t *dict) { dnode_t *first, *next; first = dict_first(dict); if (dict->dupes) { while (first && (next = dict_next(dict, first))) { #ifdef BE_QSORT_COMPATIBLE if (dict->compare(&first->key, &next->key) > 0) return 0; #else if (dict->compare(first->key, next->key) > 0) return 0; #endif first = next; } } else { while (first && (next = dict_next(dict, first))) { #ifdef BE_QSORT_COMPATIBLE if (dict->compare(&first->key, &next->key) >= 0) return 0; #else if (dict->compare(first->key, next->key) >= 0) return 0; #endif first = next; } } return 1; }
void dict_merge(dict_t *dest, dict_t *source) { dict_load_t load; dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source); assert (dict_similar(dest, source)); if (source == dest) return; #ifdef NO_FC_SOLVE dest->nodecount = 0; #endif load_begin_internal(&load, dest); for (;;) { if (leftnode != NULL && rightnode != NULL) { if (dest->compare(leftnode->key, rightnode->key, source->context) < 0) goto copyleft; else goto copyright; } else if (leftnode != NULL) { goto copyleft; } else if (rightnode != NULL) { goto copyright; } else { assert (leftnode == NULL && rightnode == NULL); break; } copyleft: { dnode_t *next = dict_next(dest, leftnode); #ifndef NDEBUG leftnode->left = NULL; /* suppress assertion in dict_load_next */ #endif dict_load_next(&load, leftnode, leftnode->key); leftnode = next; continue; } copyright: { dnode_t *next = dict_next(source, rightnode); #ifndef NDEBUG rightnode->left = NULL; #endif dict_load_next(&load, rightnode, rightnode->key); rightnode = next; continue; } } dict_clear(source); dict_load_end(&load); }
/* void cxml_node_free(CLOG_INFO* info, void * data) { CXMLNODE *node = (CXMLNODE*) data; */ void cxml_node_free(CLOG_INFO* info, CXMLNODE **node) { dnode_t *dn = NULL; if(NULL==node || NULL==*node) { return; } clog( info, CTRACE, "XML: xml_node_free(), free the attributes"); // free the attributes if(NULL!=(*node)->att) { if(!dict_isempty((*node)->att)) { for (dn = dict_first((*node)->att); dn; dn = dict_next((*node)->att, dn)) { char *key=(char*)dnode_getkey(dn); char *data=(char*)dnode_get(dn); if(NULL!=key) free(key); key=NULL; if(NULL!=data) free(data); data=NULL; } } dict_free_nodes((*node)->att); dict_destroy((*node)->att); (*node)->att=NULL; } clog( info, CTRACE, "XML: xml_node_free(), free the name"); // free the name if(NULL!=(*node)->name) cstring_free(&((*node)->name)); clog( info, CTRACE, "XML: xml_node_free(), free the data"); // free the data if(NULL!=(*node)->data) cstring_free(&((*node)->data)); clog( info, CTRACE, "XML: xml_node_free(), free the subs"); // free the children if(NULL!=(*node)->sub) { if(!dict_isempty((*node)->sub)) { for (dn = dict_first((*node)->sub); dn; dn = dict_next((*node)->sub, dn)) { char *key=(char*)dnode_getkey(dn); CXMLNODE *data=(CXMLNODE*)dnode_get(dn); if(NULL!=key) free(key); key=NULL; cxml_node_free(info, &data); } } dict_free_nodes((*node)->sub); dict_destroy((*node)->sub); (*node)->sub=NULL; } free((*node)); (*node)=NULL; node=NULL; }
static int dict_copy_elements(const ref * pdrfrom /* t_dictionary */ , ref * pdrto /* t_dictionary */ , int options, dict_stack_t *pds) { int space = r_space(pdrto); int index; ref elt[2]; ref *pvslot; int code; if (space != avm_max) { /* Do the store check before starting the copy. */ index = dict_first(pdrfrom); while ((index = dict_next(pdrfrom, index, elt)) >= 0) if (!(options & COPY_NEW_ONLY) || dict_find(pdrto, &elt[0], &pvslot) <= 0 ) { store_check_space(space, &elt[0]); store_check_space(space, &elt[1]); } } /* Now copy the contents. */ index = dict_first(pdrfrom); while ((index = dict_next(pdrfrom, index, elt)) >= 0) { ref *pvalue = pv_no_defn; if ((options & COPY_NEW_ONLY) && dict_find(pdrto, &elt[0], &pvslot) > 0 ) continue; if ((options & COPY_FOR_RESIZE) && r_has_type(&elt[0], t_name) && (pvalue = elt[0].value.pname->pvalue, pv_valid(pvalue)) ) elt[0].value.pname->pvalue = pv_no_defn; if ((code = dict_put(pdrto, &elt[0], &elt[1], pds)) < 0) { /* * If COPY_FOR_RESIZE is set, the dict_put isn't supposed to * be able to fail, but we don't want to depend on this. */ if (pvalue != pv_no_defn) elt[0].value.pname->pvalue = pvalue; return code; } } return 0; }
/* * Enumerate the next glyph from a directory. This is essentially a * wrapper around dict_first/dict_next to implement the enumerate_glyph * font procedure. * * Note that *prdict will be null if the font is a subfont of a * CIDFontType 0 CIDFont. */ int zchar_enumerate_glyph(const gs_memory_t *mem, const ref *prdict, int *pindex, gs_glyph *pglyph) { int index = *pindex - 1; ref elt[2]; if (!r_has_type(prdict, t_dictionary)) return 0; /* *pindex was 0, is still 0 */ if (index < 0) index = dict_first(prdict); next: index = dict_next(prdict, index, elt); *pindex = index + 1; if (index >= 0) { switch (r_type(elt)) { case t_integer: *pglyph = gs_min_cid_glyph + elt[0].value.intval; break; case t_name: *pglyph = name_index(mem, elt); break; default: /* can't handle it */ goto next; } } return 0; }
/// Any PTXes which survived shopping are eligible to be winners, /// as long as they've been seen and evaluated at all. This test is /// necessary because not all commands are run in all PTXes, so the /// fact that a PTX has not been invalidated could mean it was not /// even evaluated. /// This function returns the first eligible surviving PTX. It does not /// establish a policy per se; since PTXes are stored in an order set by /// the server, the policy of which matching PTX is 'best' can be /// dictated by the server. /// @return the chosen PTX id static CCS _shop_ptx_winner(shopping_state_s *ssp) { dnode_t *dnp, *next; ssp->wix[0] = ssp->winner[0] = '\0'; if (ssp->ptx_dict) { for (dnp = dict_first(ssp->ptx_dict); dnp;) { CCS key, id; next = dict_next(ssp->ptx_dict, dnp); key = (CCS)dnode_getkey(dnp); id = (CCS)dnode_get(dnp); // Remember, only an evaluated PTX can be a winner. // These are marked with a lower-case index, but // convert it back to upper case before returning. if (islower((int)key[0])) { snprintf(ssp->wix, charlen(ssp->wix), "%c%s", toupper((int)key[0]), key + 1); snprintf(ssp->winner, charlen(ssp->winner), "%s", id); return ssp->winner; } dnp = next; } } return NULL; }
/* * Swap the contents of a level dictionary (level2dict or ll3dict) and * systemdict. If a value in the level dictionary is itself a dictionary, * and it contains a key/value pair referring to itself, swap its contents * with the contents of the same dictionary in systemdict. (This is a hack * to swap the contents of statusdict.) */ static int swap_level_dict(i_ctx_t *i_ctx_p, const char *dict_name) { ref *pleveldict; ref rleveldict; int index; ref elt[2]; /* key, value */ ref *psubdict; /* * We have to copy the refs for leveldict and subdict, since they may * move if their containing dictionary is resized. */ if (dict_find_string(systemdict, dict_name, &pleveldict) <= 0) return_error(e_undefined); rleveldict = *pleveldict; index = dict_first(&rleveldict); while ((index = dict_next(&rleveldict, index, &elt[0])) >= 0) if (r_has_type(&elt[1], t_dictionary) && dict_find(&elt[1], &elt[0], &psubdict) > 0 && obj_eq(imemory, &elt[1], psubdict) ) { /* elt[1] is the 2nd-level sub-dictionary */ int isub = dict_first(&elt[1]); ref subelt[2]; int found = dict_find(systemdict, &elt[0], &psubdict); ref rsubdict; if (found <= 0) continue; rsubdict = *psubdict; while ((isub = dict_next(&elt[1], isub, &subelt[0])) >= 0) if (!obj_eq(imemory, &subelt[0], &elt[0])) { /* don't swap dict itself */ int code = swap_entry(i_ctx_p, subelt, &rsubdict, &elt[1]); if (code < 0) return code; } } else { int code = swap_entry(i_ctx_p, elt, systemdict, &rleveldict); if (code < 0) return code; } return 0; }
TA_RetCode TA_DictFree( TA_Dict *dict ) { TA_PrivDictInfo *theDict; dnode_t *node; dnode_t *next; TA_String *stringToDelete; void *valueToDelete; dict_t *kazlibDict; TA_Libc *libHandle; int flags; theDict = (TA_PrivDictInfo *)dict; if( theDict == NULL ) return TA_BAD_PARAM; kazlibDict = &theDict->d; libHandle = theDict->libHandle; /* Delete all the key-value pair sequentially. */ node = dict_first( libHandle, kazlibDict ); while (node != NULL) { /* Get the next node. */ next = dict_next( libHandle, kazlibDict, node ); /* Free the 'node, the 'key' string and the 'value'. */ flags = theDict->flags; valueToDelete = dnode_get(node); if( flags & (TA_DICT_KEY_TWO_STRING|TA_DICT_KEY_ONE_STRING) ) { stringToDelete = TA_StringFromChar(dnode_getkey(node)); dict_delete_free( libHandle, kazlibDict, node ); TA_StringFree( TA_GetGlobalStringCache( libHandle ), stringToDelete ); } else dict_delete_free( libHandle, kazlibDict, node ); if( flags & TA_DICT_KEY_TWO_STRING ) { /* The value is a dictionary. Delete it. */ TA_DictFree( (TA_Dict *)valueToDelete ); } else if( theDict->freeValueFunc ) theDict->freeValueFunc( libHandle, valueToDelete ); node = next; } /* Free the TA_PrivDictInfo */ TA_Free( libHandle, theDict ); return TA_SUCCESS; }
static int verify_bintree(dict_t *dict) { dnode_t *first, *next; first = dict_first(dict); if (dict->dupes) { while (first && (next = dict_next(dict, first))) { if (dict->compare(first->key, next->key) > 0) return 0; first = next; } } else { while (first && (next = dict_next(dict, first))) { if (dict->compare(first->key, next->key) >= 0) return 0; first = next; } } return 1; }
void dict_process(dict_t *dict, void *context, dnode_process_t function) { dnode_t *node = dict_first(dict), *next; while (node != NULL) { /* check for callback function deleting */ /* the next node from under us */ assert (dict_contains(dict, node)); next = dict_next(dict, node); function(dict, node, context); node = next; } }
static void on_timer(nw_timer *t, void *privdata) { double now = current_timestamp(); dict_iterator *iter = dict_get_iterator(dict_update); dict_entry *entry; while ((entry = dict_next(iter)) != NULL) { struct update_val *val = entry->val; if (val->create_time < (now - 86400)) { dict_delete(dict_update, entry->key); } } dict_release_iterator(iter); }
static void write_dquots(dict_t *dict, struct quota_handle *qh) { dnode_t *n; struct dquot *dq; for (n = dict_first(dict); n; n = dict_next(dict, n)) { dq = dnode_get(n); if (dq) { dq->dq_h = qh; update_grace_times(dq); qh->qh_ops->commit_dquot(dq); } } }
/// Traverses the CA, calling the specified function on each 'cooked' PA. /// In order to enforce the conventional ordering of read-before-write /// we go around twice, handling reads on the first pass and everything /// else on the second. /// @param[in] ca the object pointer /// @param[in] process pointer to the callback function /// @param[in] data pointer which is passed to the callback /// @return -1 on error, sum of process() return codes on success int ca_foreach_cooked_pa(ca_o ca, int (*process) (pa_o, void *), void *data) { dict_t *dict; dnode_t *dnp; pa_o pa; int rc = 0, pret; if ((dict = ca->ca_cooked_pa_dict)) { for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) { pa = (pa_o)dnode_getkey(dnp); if (pa_is_read(pa)) { pret = process(pa, data); if (pret < 0) { putil_int("ca_foreach_cooked_pa(%s)", pa_get_abs(pa)); return -1; } else { rc += pret; } } } for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) { pa = (pa_o)dnode_getkey(dnp); if (!pa_is_read(pa)) { pret = process(pa, data); if (pret < 0) { putil_int("ca_foreach_cooked_pa(%s)", pa_get_abs(pa)); return -1; } else { rc += pret; } } } } return rc; }
/// Serializes the CmdAction and writes it to the specified file descriptor. /// On Windows this must send to a socket. On Unix it can use any /// kind of file descriptor. /// @param[in] ca the object pointer /// @param[in] fd file descriptor to which the serialized form is sent void ca_write(ca_o ca, int fd) { dict_t *dict; dnode_t *dnp, *next; pa_o pa; CCS pabuf; dict = ca->ca_raw_pa_dict; if (dict_count(dict) <= 0) { return; } // In case buffered files were left open by sloppy audited programs. fflush(NULL); for (dnp = dict_first(dict); dnp;) { pa = (pa_o)dnode_getkey(dnp); // Unfortunately it's too early to dcode any written files // since they may still be open. But we should get stats of // non-member read ops since they may differ in the event // of a distributed build. We must assume logical coherence // for all write ops, member and non-member. // In other words, read ops are allowed to be on physically // separate files with the same path (e.g. /usr/include/stdio.h) // but write ops to the same path are assumed to be to a shared file. // This matters in the case of a distributed build. if (pa_is_read(pa) && !pa_is_member(pa)) { (void)pa_stat(pa, 0); } if ((pabuf = pa_toCSVString(pa))) { if (write(fd, pabuf, strlen(pabuf)) == -1) { putil_syserr(0, "write()"); } putil_free(pabuf); } // Dictionary bookkeeping. next = dict_next(dict, dnp); dict_delete(dict, dnp); dnp = next; pa_destroy(pa); } }
void class_print(struct state *S, struct class_t *C) { struct dict_pair *pair = NULL; printf("Class %p extends parent %p\n", (void *) C, (void *) C->parent); for (pair = dict_begin(C->members[STATIC_MEMBER]); pair != NULL; pair = dict_next(C->members[STATIC_MEMBER])) { char buf[512]; type_to_string((struct type_t *) pair->value, buf, sizeof(buf)); printf(" static %s %s;\n", buf, pair->key); } for (pair = dict_begin(C->members[DYNAMIC_MEMBER]); pair != NULL; pair = dict_next(C->members[DYNAMIC_MEMBER])) { char buf[512]; type_to_string((struct type_t *) pair->value, buf, sizeof(buf)); printf(" %s %s;\n", buf, pair->key); } }
void ledger_close_context(ledger_ctx *ctx) { dnode_t *cur; ledger_topic *topic = NULL; for(cur = dict_first(&ctx->topics); cur != NULL; cur = dict_next(&ctx->topics, cur)) { topic = dnode_get(cur); ledger_topic_close(topic); free(topic); } ledger_position_storage_close(&ctx->position_storage); dict_free_nodes(&ctx->topics); }
/* Implementation for enumerating parameters in a dictionary */ static int /* ret 0 ok, 1 if EOF, or -ve err */ dict_param_enumerate(iparam_list * plist, gs_param_enumerator_t * penum, gs_param_key_t * key, ref_type * type) { ref elt[2]; int code; dict_param_list *const pdlist = (dict_param_list *) plist; int index = (penum->intval != 0 ? penum->intval : dict_first(&pdlist->dict)); index = dict_next(&pdlist->dict, index, elt); if (index < 0) return 1; *type = r_type(&elt[1]); code = ref_to_key(&elt[0], key, plist); penum->intval = index; return code; }
/// Checks the list of PAs and tells us whether any of them references /// a file which needs to be uploaded. /// @param[in] ca the object pointer /// @return true if the object refers to an uploadable file int ca_is_uploadable(ca_o ca) { dict_t *dict; dnode_t *dnp; pa_o pa; int rc = 0; if ((dict = ca->ca_cooked_pa_dict)) { for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) { pa = (pa_o)dnode_getkey(dnp); if (pa_get_uploadable(pa)) { rc++; } } } return rc; }
/* Continuation operator for dictionaries */ static int dict_continue(i_ctx_t *i_ctx_p) { os_ptr op = osp; es_ptr obj = esp - 2; int index = esp->value.intval; push(2); /* make room for key and value */ if ((index = dict_next(obj, index, op - 1)) >= 0) { /* continue */ esp->value.intval = index; esp += 2; *esp = obj[1]; return o_push_estack; } else { /* done */ pop(2); /* undo push */ esp -= 4; /* pop mark, object, proc, index */ return o_pop_estack; } }
/// Merge two CmdActions, a 'leader' and a 'donor', together. The donor /// is then redundant. /// @param[in] leader the leader object pointer /// @param[in] donor the donor object pointer void ca_merge(ca_o leader, ca_o donor) { CCS sub; dict_t *dict; dnode_t *dnp, *next; pa_o pa; // ASSUMPTION: aggregated CAs are composed from // commands run serially - i.e. any parallelism // is above the build-script level. // Stringify the donor and leave that string representation in // the leader for the record. sub = ca_format_header(donor); if (leader->ca_subs) { leader->ca_subs = (CCS)putil_realloc((void *)leader->ca_subs, (strlen(leader->ca_subs) + strlen(sub) + 1) * CHARSIZE); strcat((CS)leader->ca_subs, sub); } else { leader->ca_subs = (CCS)putil_malloc((strlen(sub) + 1) * CHARSIZE); strcpy((CS)leader->ca_subs, sub); } putil_free(sub); // Traverse the donor's raw list of PA's and move them into the leader's. if ((dict = donor->ca_raw_pa_dict)) { for (dnp = dict_first(dict); dnp;) { next = dict_next(dict, dnp); pa = (pa_o)dnode_getkey(dnp); ca_record_pa(leader, pa); dict_delete(dict, dnp); dnode_destroy(dnp); dnp = next; } dict_destroy(donor->ca_raw_pa_dict); donor->ca_raw_pa_dict = NULL; } }
int TA_DictAccessNext( TA_Dict *dict ) { TA_PrivDictInfo *theDict; theDict = (TA_PrivDictInfo *)dict; if( (theDict == NULL) || (theDict->accessNode == NULL) ) return 0; /* Move to the next node. */ theDict->accessNode = dict_next( theDict->libHandle, &theDict->d, theDict->accessNode ); if( !theDict->accessNode ) { /* There is no element left... */ return 0; } return 1; }
/// Free all data structures allocated by _shop_ptx_init(). static void _shop_ptx_destroy(dict_t *dict) { dnode_t *dnp, *next; if (dict) { for (dnp = dict_first(dict); dnp;) { CCS key, id; next = dict_next(dict, dnp); key = (CCS)dnode_getkey(dnp); id = (CCS)dnode_get(dnp); dict_delete_free(dict, dnp); putil_free(key); putil_free(id); dnp = next; } dict_destroy(dict); } }
void process_from_founded_sig(dict_t *dict) { if ( !dict || !dict_count(dict) ) return; if ( !check_rpd_count(true) ) return; dnode_t *node; pdb_class *pc; char *c_name; ea_t ea; for ( node = dict_first(dict); node; node = dict_next(dict, node) ) { c_name = (char *)dnode_get(node); ea = (ea_t)dnode_getkey(node); pc = p_pool->find_class(c_name); if ( !pc ) continue; fill_vtbl(c_name, ea, pc); } }
/// Traverses the CA, calling the specified function on each 'raw' PA. /// @param[in] ca the object pointer /// @param[in] process pointer to the callback function /// @param[in] data pointer which is passed to the callback /// @return -1 on error, sum of process() return codes on success int ca_foreach_raw_pa(ca_o ca, int (*process) (pa_o, void *), void *data) { dict_t *dict; dnode_t *dnp; pa_o pa; int rc = 0, pret; dict = ca->ca_raw_pa_dict; for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) { pa = (pa_o)dnode_getkey(dnp); pret = process(pa, data); if (pret < 0) { putil_int("error from ca_foreach_raw_pa()"); return -1; } else { rc += pret; } } return rc; }
int mongrel2_ws_broadcast(mongrel2_socket *pub_socket, m2_ws_sessions_state *ses, bstring data){ mongrel2_ws_sessions_state_lock(ses); dnode_t *iter = dict_first(ses->dict); const m2_ws_session_id *idptr = NULL; while(iter != NULL){ printf("."); idptr = dnode_getkey(iter); assert(idptr != NULL); assert(idptr->req != NULL); mongrel2_ws_reply(pub_socket,idptr->req,data); iter = dict_next(ses->dict,iter); } printf(" done sending\n"); mongrel2_ws_sessions_state_unlock(ses); return 0; }
TEST(mydict, dict) { dict_t* d = dict_create((void*)123); int k, v; dict_node_t* node = NULL; int i = 0; int sum = 0; for (i = 0; i < 10000; i++) { k = i, v = i; node = dict_add(d, &k, sizeof(k), &v, sizeof(v)); ASSERT_TRUE(node != NULL); sum += i; } for (i = 0; i < 10000; i++) { node = dict_find(d, &k, sizeof(k)); ASSERT_EQ((long)dict_get_val(node), i); } i = 0; for(node = dict_first(d); node; node = dict_next(d, node)) { i += (long)dict_get_val(node); } ASSERT_EQ(i, sum); for (i = 0; i < 10000; i++) { k = i; node = dict_delete(d, &k, sizeof(k)); ASSERT_EQ((long)dict_get_val(node), i); } ASSERT_TRUE(dict_empty(d)); dict_destroy(d); }
static int zsethalftone5(i_ctx_t *i_ctx_p) { os_ptr op = osp; uint count; gs_halftone_component *phtc; gs_halftone_component *pc; int code = 0; int j; gs_halftone *pht; gx_device_halftone *pdht; ref sprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; ref tprocs[GS_CLIENT_COLOR_MAX_COMPONENTS + 1]; gs_memory_t *mem; uint edepth = ref_stack_count(&e_stack); int npop = 2; int dict_enum = dict_first(op); ref rvalue[2]; int cname, colorant_number; byte * pname; uint name_size; int halftonetype, type = 0; gs_state *pgs = igs; int space_index = r_space_index(op - 1); mem = (gs_memory_t *) idmemory->spaces_indexed[space_index]; check_type(*op, t_dictionary); check_dict_read(*op); check_type(op[-1], t_dictionary); check_dict_read(op[-1]); /* * We think that Type 2 and Type 4 halftones, like * screens set by setcolorscreen, adapt automatically to * the device color space, so we need to mark them * with a different internal halftone type. */ dict_int_param(op - 1, "HalftoneType", 1, 5, 0, &type); halftonetype = (type == 2 || type == 4) ? ht_type_multiple_colorscreen : ht_type_multiple; /* Count how many components that we will actually use. */ for (count = 0; ;) { bool have_default = false; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; else if (colorant_number == GX_DEVICE_COLOR_MAX_COMPONENTS) { /* If here then we have the "Default" component */ if (have_default) return_error(e_rangecheck); have_default = true; } count++; /* * Check to see if we have already reached the legal number of * components. */ if (count > GS_CLIENT_COLOR_MAX_COMPONENTS + 1) { code = gs_note_error(e_rangecheck); break; } } check_estack(5); /* for sampling Type 1 screens */ refset_null(sprocs, count); refset_null(tprocs, count); rc_alloc_struct_0(pht, gs_halftone, &st_halftone, imemory, pht = 0, ".sethalftone5"); phtc = gs_alloc_struct_array(mem, count, gs_halftone_component, &st_ht_component_element, ".sethalftone5"); rc_alloc_struct_0(pdht, gx_device_halftone, &st_device_halftone, imemory, pdht = 0, ".sethalftone5"); if (pht == 0 || phtc == 0 || pdht == 0) { j = 0; /* Quiet the compiler: gs_note_error isn't necessarily identity, so j could be left ununitialized. */ code = gs_note_error(e_VMerror); } else { dict_enum = dict_first(op); for (j = 0, pc = phtc; ;) { int type; /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* * Verify that we have a valid component. We may have a * /HalfToneType entry. */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; /* Do not use this component */ pc->cname = cname; pc->comp_number = colorant_number; /* Now process the component dictionary */ check_dict_read(rvalue[1]); if (dict_int_param(&rvalue[1], "HalftoneType", 1, 7, 0, &type) < 0) { code = gs_note_error(e_typecheck); break; } switch (type) { default: code = gs_note_error(e_rangecheck); break; case 1: code = dict_spot_params(&rvalue[1], &pc->params.spot, sprocs + j, tprocs + j); pc->params.spot.screen.spot_function = spot1_dummy; pc->type = ht_type_spot; break; case 3: code = dict_threshold_params(&rvalue[1], &pc->params.threshold, tprocs + j); pc->type = ht_type_threshold; break; case 7: code = dict_threshold2_params(&rvalue[1], &pc->params.threshold2, tprocs + j, imemory); pc->type = ht_type_threshold2; break; } if (code < 0) break; pc++; j++; } } if (code >= 0) { pht->type = halftonetype; pht->params.multiple.components = phtc; pht->params.multiple.num_comp = j; pht->params.multiple.get_colorname_string = gs_get_colorname_string; code = gs_sethalftone_prepare(igs, pht, pdht); } if (code >= 0) { /* * Put the actual frequency and angle in the spot function component dictionaries. */ dict_enum = dict_first(op); for (pc = phtc; ; ) { /* Move to next element in the dictionary */ if ((dict_enum = dict_next(op, dict_enum, rvalue)) == -1) break; /* Verify that we have a valid component */ if (!r_has_type(&rvalue[1], t_dictionary)) continue; /* Get the name of the component and verify that we will use it. */ cname = name_index(mem, &rvalue[0]); code = gs_get_colorname_string(mem, cname, &pname, &name_size); if (code < 0) break; colorant_number = gs_cname_to_colorant_number(pgs, pname, name_size, halftonetype); if (colorant_number < 0) continue; if (pc->type == ht_type_spot) { code = dict_spot_results(i_ctx_p, &rvalue[1], &pc->params.spot); if (code < 0) break; } pc++; } } if (code >= 0) { /* * Schedule the sampling of any Type 1 screens, * and any (Type 1 or Type 3) TransferFunctions. * Save the stack depths in case we have to back out. */ uint odepth = ref_stack_count(&o_stack); ref odict, odict5; odict = op[-1]; odict5 = *op; pop(2); op = osp; esp += 5; make_mark_estack(esp - 4, es_other, sethalftone_cleanup); esp[-3] = odict; make_istruct(esp - 2, 0, pht); make_istruct(esp - 1, 0, pdht); make_op_estack(esp, sethalftone_finish); for (j = 0; j < count; j++) { gx_ht_order *porder = NULL; if (pdht->components == 0) porder = &pdht->order; else { /* Find the component in pdht that matches component j in the pht; gs_sethalftone_prepare() may permute these. */ int k; int comp_number = phtc[j].comp_number; for (k = 0; k < count; k++) { if (pdht->components[k].comp_number == comp_number) { porder = &pdht->components[k].corder; break; } } } switch (phtc[j].type) { case ht_type_spot: code = zscreen_enum_init(i_ctx_p, porder, &phtc[j].params.spot.screen, &sprocs[j], 0, 0, space_index); if (code < 0) break; /* falls through */ case ht_type_threshold: if (!r_has_type(tprocs + j, t__invalid)) { /* Schedule TransferFunction sampling. */ /****** check_xstack IS WRONG ******/ check_ostack(zcolor_remap_one_ostack); check_estack(zcolor_remap_one_estack); code = zcolor_remap_one(i_ctx_p, tprocs + j, porder->transfer, igs, zcolor_remap_one_finish); op = osp; } break; default: /* not possible here, but to keep */ /* the compilers happy.... */ ; } if (code < 0) { /* Restore the stack. */ ref_stack_pop_to(&o_stack, odepth); ref_stack_pop_to(&e_stack, edepth); op = osp; op[-1] = odict; *op = odict5; break; } npop = 0; } } if (code < 0) { gs_free_object(mem, pdht, ".sethalftone5"); gs_free_object(mem, phtc, ".sethalftone5"); gs_free_object(mem, pht, ".sethalftone5"); return code; } pop(npop); return (ref_stack_count(&e_stack) > edepth ? o_push_estack : 0); }
static int zmatchmedia(i_ctx_t *i_ctx_p) { os_ptr op = osp; os_ptr preq = op - 3; os_ptr pattr = op - 2; os_ptr ppol = op - 1; os_ptr pkeys = op; /* *const */ int policy_default; float best_mismatch = (float)max_long; /* adhoc */ float mepos_penalty; float mbest = best_mismatch; match_record_t match; ref no_priority; ref *ppriority; int mepos, orient; bool roll; int code; int ai; struct mkd_ { ref key, dict; } aelt; if (r_has_type(pattr, t_null)) { check_op(4); make_null(op - 3); make_true(op - 2); pop(2); return 0; } check_type(*preq, t_dictionary); check_dict_read(*preq); check_type(*pattr, t_dictionary); check_dict_read(*pattr); check_type(*ppol, t_dictionary); check_dict_read(*ppol); check_array(*pkeys); check_read(*pkeys); switch (code = dict_int_null_param(preq, "MediaPosition", 0, 0x7fff, 0, &mepos)) { default: return code; case 2: case 1: mepos = -1; case 0:; } switch (code = dict_int_null_param(preq, "Orientation", 0, 3, 0, &orient)) { default: return code; case 2: case 1: orient = -1; case 0:; } code = dict_bool_param(preq, "RollFedMedia", false, &roll); if (code < 0) return code; code = dict_int_param(ppol, "PolicyNotFound", 0, 7, 0, &policy_default); if (code < 0) return code; if (dict_find_string(pattr, "Priority", &ppriority) > 0) { check_array_only(*ppriority); check_read(*ppriority); } else { make_empty_array(&no_priority, a_readonly); ppriority = &no_priority; } match.no_match_priority = r_size(ppriority); reset_match(&match); for (ai = dict_first(pattr); (ai = dict_next(pattr, ai, (ref * /*[2]*/)&aelt)) >= 0; ) { if (r_has_type(&aelt.dict, t_dictionary) && r_has_attr(dict_access_ref(&aelt.dict), a_read) && r_has_type(&aelt.key, t_integer) ) { bool match_all; uint ki, pi; code = dict_bool_param(&aelt.dict, "MatchAll", false, &match_all); if (code < 0) return code; for (ki = 0; ki < r_size(pkeys); ki++) { ref key; ref kstr; ref *prvalue; ref *pmvalue; ref *ppvalue; int policy; array_get(imemory, pkeys, ki, &key); if (dict_find(&aelt.dict, &key, &pmvalue) <= 0) continue; if (dict_find(preq, &key, &prvalue) <= 0 || r_has_type(prvalue, t_null) ) { if (match_all) goto no; else continue; } /* Look for the Policies entry for this key. */ if (dict_find(ppol, &key, &ppvalue) > 0) { check_type_only(*ppvalue, t_integer); policy = ppvalue->value.intval; } else policy = policy_default; /* * Match a requested attribute value with the attribute value in the * description of a medium. For all attributes except PageSize, * matching means equality. PageSize is special; see match_page_size * below. */ if (r_has_type(&key, t_name) && (name_string_ref(imemory, &key, &kstr), r_size(&kstr) == 8 && !memcmp(kstr.value.bytes, "PageSize", 8)) ) { gs_matrix ignore_mat; gs_point ignore_msize; if (zmatch_page_size(imemory, prvalue, pmvalue, policy, orient, roll, &best_mismatch, &ignore_mat, &ignore_msize) <= 0) goto no; } else if (!obj_eq(imemory, prvalue, pmvalue)) goto no; } mepos_penalty = (mepos < 0 || aelt.key.value.intval == mepos) ? 0 : .001; /* We have a match. Save the match in case no better match is found */ if (r_has_type(&match.match_key, t_null)) match.match_key = aelt.key; /* * If it is a better match than the current best it supersedes it * regardless of priority. If the match is the same, then update * to the current only if the key value is lower. */ if (best_mismatch + mepos_penalty <= mbest) { if (best_mismatch + mepos_penalty < mbest || (r_has_type(&match.match_key, t_integer) && match.match_key.value.intval > aelt.key.value.intval)) { reset_match(&match); match.match_key = aelt.key; mbest = best_mismatch + mepos_penalty; } } /* In case of a tie, see if the new match has priority. */ for (pi = match.priority; pi > 0;) { ref pri; pi--; array_get(imemory, ppriority, pi, &pri); if (obj_eq(imemory, &aelt.key, &pri)) { /* Yes, higher priority. */ match.best_key = aelt.key; match.priority = pi; break; } } no:; } } if (r_has_type(&match.match_key, t_null)) { make_false(op - 3); pop(3); } else { if (r_has_type(&match.best_key, t_null)) op[-3] = match.match_key; else op[-3] = match.best_key; make_true(op - 2); pop(2); } return 0; }