double de_getfloat32x_direct(deark *c, const u8 *m, int is_le) { char buf[4]; float val = 0.0; if(c->can_decode_fltpt<0) { init_fltpt_decoder(c); } if(!c->can_decode_fltpt) return 0.0; // FIXME: This assumes that the native floating point format is // IEEE 754, but that does not have to be the case. de_memcpy(buf, m, 4); if(is_le != c->host_is_le) { int i; char tmpc; // Reverse order of bytes for(i=0; i<2; i++) { tmpc = buf[i]; buf[i] = buf[3-i]; buf[3-i] = tmpc; } } de_memcpy(&val, buf, 4); return (double)val; }
// Note: This function is similar to de_finfo_set_name_from_ucstring(). // Maybe they should be consolidated. void ucstring_to_sz(de_ucstring *s, char *szbuf, size_t szbuf_len, int encoding) { de_int64 i; de_int64 szpos = 0; de_byte utf8buf[4]; de_int64 utf8codelen; if(szbuf_len<1) return; for(i=0; i<s->len; i++) { if(encoding==DE_ENCODING_UTF8) { de_uchar_to_utf8(s->str[i], utf8buf, &utf8codelen); } else { // DE_ENCODING_LATIN1 or DE_ENCODING_ASCII if(s->str[i]>=0 && s->str[i]<=(encoding==DE_ENCODING_LATIN1?255:127)) utf8buf[0] = (de_byte)s->str[i]; else utf8buf[0] = '_'; utf8codelen = 1; } if(szpos + utf8codelen + 1 > (de_int64)szbuf_len) break; de_memcpy(&szbuf[szpos], utf8buf, (size_t)utf8codelen); szpos += utf8codelen; } szbuf[szpos] = '\0'; }
static void membuf_append(dbuf *f, const u8 *m, i64 mlen) { i64 new_alloc_size; if(f->has_len_limit) { if(f->len + mlen > f->len_limit) { mlen = f->len_limit - f->len; } } if(mlen<=0) return; if(mlen > f->membuf_alloc - f->len) { // Need to allocate more space new_alloc_size = (f->membuf_alloc + mlen)*2; if(new_alloc_size<1024) new_alloc_size=1024; if(new_alloc_size > f->max_len_hard) new_alloc_size = f->max_len_hard; de_dbg3(f->c, "increasing membuf size %"I64_FMT" -> %"I64_FMT, f->membuf_alloc, new_alloc_size); if(f->len + mlen > f->max_len_hard) { do_on_dbuf_size_exceeded(f); } f->membuf_buf = de_realloc(f->c, f->membuf_buf, f->membuf_alloc, new_alloc_size); f->membuf_alloc = new_alloc_size; } de_memcpy(&f->membuf_buf[f->len], m, (size_t)mlen); f->len += mlen; }
// Swap some bytes to convert a (little-endian) GUID to a UUID, in-place void de_fmtutil_guid_to_uuid(u8 *id) { u8 tmp[16]; de_memcpy(tmp, id, 16); id[0] = tmp[3]; id[1] = tmp[2]; id[2] = tmp[1]; id[3] = tmp[0]; id[4] = tmp[5]; id[5] = tmp[4]; id[6] = tmp[7]; id[7] = tmp[6]; }
// Allowed only for membufs, and unmanaged output files. // For unmanaged output files, must be used with care, and should not be // mixed with dbuf_write(). void dbuf_write_at(dbuf *f, i64 pos, const u8 *m, i64 len) { if(len<1 || pos<0) return; if(pos + len > f->max_len_hard) { do_on_dbuf_size_exceeded(f); } if(f->btype==DBUF_TYPE_MEMBUF) { i64 amt_overwrite, amt_newzeroes, amt_append; if(pos+len <= f->len) { // entirely within the current file amt_overwrite = len; amt_newzeroes = 0; amt_append = 0; } else if(pos >= f->len) { // starts after the end of the current file amt_overwrite = 0; amt_newzeroes = pos - f->len; amt_append = len; } else { // overlaps the end of the current file amt_overwrite = f->len - pos; amt_newzeroes = 0; amt_append = len - amt_overwrite; } if(amt_overwrite>0) { de_memcpy(&f->membuf_buf[pos], m, (size_t)amt_overwrite); } if(amt_newzeroes>0) { dbuf_write_zeroes(f, amt_newzeroes); } if(amt_append>0) { membuf_append(f, &m[amt_overwrite], amt_append); } } else if(f->btype==DBUF_TYPE_OFILE && !f->is_managed) { i64 curpos = de_ftell(f->fp); if(pos != curpos) { de_fseek(f->fp, pos, SEEK_SET); } fwrite(m, 1, (size_t)len, f->fp); if(pos+len > f->len) { f->len = pos+len; } } else if(f->btype==DBUF_TYPE_NULL) { ; } else { de_err(f->c, "internal: Attempt to seek on non-seekable stream"); de_fatalerror(f->c); } }
double de_getfloat64x_direct(deark *c, const u8 *m, int is_le) { char buf[8]; double val = 0.0; if(c->can_decode_fltpt<0) { init_fltpt_decoder(c); } if(!c->can_decode_fltpt) return 0.0; de_memcpy(buf, m, 8); if(is_le != c->host_is_le) { int i; char tmpc; // Reverse order of bytes for(i=0; i<4; i++) { tmpc = buf[i]; buf[i] = buf[7-i]; buf[7-i] = tmpc; } } de_memcpy(&val, buf, 8); return (double)val; }
static void init_fltpt_decoder(deark *c) { unsigned int x = 1; char b = 0; c->can_decode_fltpt = 0; if(sizeof(float)!=4 || sizeof(double)!=8) return; c->can_decode_fltpt = 1; de_memcpy(&b, &x, 1); if(b==0) c->host_is_le = 0; else c->host_is_le = 1; }
// Read len bytes, starting at file position pos, into buf. // Unread bytes will be set to 0. void dbuf_read(dbuf *f, u8 *buf, i64 pos, i64 len) { i64 bytes_read = 0; i64 bytes_to_read; deark *c; c = f->c; bytes_to_read = len; if(pos >= f->len) { bytes_to_read = 0; } else if(pos + bytes_to_read > f->len) { bytes_to_read = f->len - pos; } if(bytes_to_read<1) { goto done_read; } if(!f->cache && f->cache_policy==DE_CACHE_POLICY_ENABLED) { populate_cache(f); } // If the data we need is all cached, get it from cache. if(f->cache && pos >= f->cache_start_pos && pos + bytes_to_read <= f->cache_start_pos + f->cache_bytes_used) { de_memcpy(buf, &f->cache[pos - f->cache_start_pos], (size_t)bytes_to_read); bytes_read = bytes_to_read; goto done_read; } switch(f->btype) { case DBUF_TYPE_IFILE: if(!f->fp) { de_err(c, "Internal: File not open"); de_fatalerror(c); return; } // For performance reasons, don't call fseek if we're already at the // right position. if(!f->file_pos_known || f->file_pos!=pos) { de_fseek(f->fp, pos, SEEK_SET); } bytes_read = fread(buf, 1, (size_t)bytes_to_read, f->fp); f->file_pos = pos + bytes_read; f->file_pos_known = 1; break; case DBUF_TYPE_IDBUF: // Recursive call to the parent dbuf. dbuf_read(f->parent_dbuf, buf, f->offset_into_parent_dbuf+pos, bytes_to_read); // The parent dbuf always writes 'bytes_to_read' bytes. bytes_read = bytes_to_read; break; case DBUF_TYPE_MEMBUF: de_memcpy(buf, &f->membuf_buf[pos], (size_t)bytes_to_read); bytes_read = bytes_to_read; break; default: de_err(c, "Internal: getbytes from this I/O type not implemented"); de_fatalerror(c); return; } done_read: // Zero out any requested bytes that were not read. if(bytes_read < len) { de_zeromem(buf+bytes_read, (size_t)(len - bytes_read)); } }