static value_ptr extract_object(bplist_info_ptr bplist, uint64_t objectRef) { uint64_t offset; value_ptr result = NULL; uint8_t objectTag; if (objectRef >= bplist->object_count) { // Out-of-range object reference. bplist_log("Bad binary plist: object index is out of range.\n"); return NULL; } // Use cached object if it exists result = cache_lookup(bplist->cache, objectRef); if (result != NULL) return result; // Otherwise, find object in file. offset = read_offset(bplist, objectRef); if (offset > bplist->length) { // Out-of-range offset. bplist_log("Bad binary plist: object outside container.\n"); return NULL; } objectTag = *(bplist->data_bytes + offset); switch (objectTag & 0xF0) { case kTAG_SIMPLE: result = extract_simple(bplist, offset); break; case kTAG_INT: result = extract_int(bplist, offset); break; case kTAG_REAL: result = extract_real(bplist, offset); break; case kTAG_DATE: result = extract_date(bplist, offset); break; case kTAG_DATA: result = extract_data(bplist, offset); break; case kTAG_ASCIISTRING: result = extract_ascii_string(bplist, offset); break; case kTAG_UNICODESTRING: result = extract_unicode_string(bplist, offset); break; case kTAG_UID: result = extract_uid(bplist, offset); break; case kTAG_ARRAY: result = extract_array(bplist, offset); break; case kTAG_DICTIONARY: result = extract_dictionary(bplist, offset); break; default: // Unknown tag. bplist_log("Bad binary plist: unknown tag 0x%X.\n", (objectTag & 0x0F) >> 4); result = NULL; } // Cache and return result. if (result != NULL) cache_insert(&bplist->cache, objectRef, result); return result; }
static void write_float (st_parameter_dt *dtp, const fnode *f, const char *source, int len) { GFC_REAL_LARGEST n; int nb =0, res, save_scale_factor; char * p, fin; fnode *f2 = NULL; n = extract_real (source, len); if (f->format != FMT_B && f->format != FMT_O && f->format != FMT_Z) { res = isfinite (n); if (res == 0) { nb = f->u.real.w; /* If the field width is zero, the processor must select a width not zero. 4 is chosen to allow output of '-Inf' or '+Inf' */ if (nb == 0) nb = 4; p = write_block (dtp, nb); if (p == NULL) return; if (nb < 3) { memset (p, '*',nb); return; } memset(p, ' ', nb); res = !isnan (n); if (res != 0) { if (signbit(n)) { /* If the sign is negative and the width is 3, there is insufficient room to output '-Inf', so output asterisks */ if (nb == 3) { memset (p, '*',nb); return; } /* The negative sign is mandatory */ fin = '-'; } else /* The positive sign is optional, but we output it for consistency */ fin = '+'; if (nb > 8) /* We have room, so output 'Infinity' */ memcpy(p + nb - 8, "Infinity", 8); else /* For the case of width equals 8, there is not enough room for the sign and 'Infinity' so we go with 'Inf' */ memcpy(p + nb - 3, "Inf", 3); if (nb < 9 && nb > 3) p[nb - 4] = fin; /* Put the sign in front of Inf */ else if (nb > 8) p[nb - 9] = fin; /* Put the sign in front of Infinity */ } else memcpy(p + nb - 3, "NaN", 3); return; } } if (f->format != FMT_G) output_float (dtp, f, n); else { save_scale_factor = dtp->u.p.scale_factor; f2 = calculate_G_format (dtp, f, n, &nb); output_float (dtp, f2, n); dtp->u.p.scale_factor = save_scale_factor; if (f2 != NULL) free_mem(f2); if (nb > 0) { p = write_block (dtp, nb); if (p == NULL) return; memset (p, ' ', nb); } } }