U8_EXPORT /* u8_grow_input_stream: Arguments: a pointer to an input stream and max buffer size Returns: the size of the new buffer Doubles the size of the input buffer */ ssize_t u8_grow_input_stream(struct U8_INPUT *in,ssize_t to_size) { int owns_buf = ((in->u8_streaminfo)&(U8_STREAM_OWNS_BUF)); size_t max = in->u8_bufsz, bytes_buffered = in->u8_inlim - in->u8_read, bytes_read = in->u8_read - in->u8_inbuf; size_t new_max = ((max>=U8_BUF_THROTTLE_POINT)? (max+(U8_BUF_THROTTLE_POINT/2)): (max*2)); if (to_size<0) to_size=new_max; else if ((to_size+U8_BUF_MIN_GROW)<max) return max; else {} while (new_max<to_size) new_max = ((new_max>=U8_BUF_THROTTLE_POINT)? (new_max+(U8_BUF_THROTTLE_POINT/2)): (new_max*2)); u8_byte *buf = in->u8_inbuf, *new_buf=NULL; /* Reset buffer */ if (bytes_read>0) { memcpy(buf, in->u8_read, bytes_buffered); in->u8_read = buf; in->u8_inlim -= bytes_read; *(in->u8_inlim) = '\0';} /* Try to allocate a new buffer */ new_buf=(owns_buf)?(u8_realloc(buf,new_max)):(u8_malloc(new_max)); if (new_buf==NULL) { size_t shrink_by = (new_max-max)/16; while (new_buf==NULL) { /* The alloc/realloc call failed, so try smaller sizes */ errno=0; /* Reset errno */ /* Shrink until it works or the buffer size is smaller than the current value */ new_max=new_max-shrink_by; if (new_max<=max) { u8_log(LOGCRIT,"MallocFailed/grow_output", "Couldn't grow buffer for input stream"); return max;} u8_log(LOGCRIT,"MemoryRestricted", "Couldn't grow u8_input_stream buffer (x%llx) to %lld bytes, trying %lld", (long long) in,new_max+shrink_by,new_max); new_buf=(owns_buf)?(u8_realloc(in->u8_inbuf,new_max)): (u8_malloc(new_max));}} if (!(owns_buf)) { memcpy(new_buf,buf,bytes_buffered); in->u8_streaminfo|=U8_STREAM_OWNS_BUF;} in->u8_inbuf=new_buf; in->u8_read=new_buf; in->u8_inlim=new_buf+bytes_buffered; in->u8_bufsz=new_max; return new_max; }
U8_EXPORT void *u8_contour_realloc(u8_contour c,void *ptr,size_t new_size) { u8_contour scan=c; while (scan) { if (scan->u8c_n_blocks) { void **blocks=scan->u8c_blocks; /* Intentionally scanning backwards */ int i=scan->u8c_n_blocks-1; while (i>=0) if (blocks[i]==ptr) { void *newptr=u8_realloc(ptr,new_size); blocks[i]=newptr; return newptr;} else i++;} scan=scan->u8c_outer_contour;} /* Should this err or warn? */ return u8_realloc(ptr,new_size); }
U8_EXPORT void u8_grow_contour(u8_contour c) { if (c->u8c_max_blocks==0) { c->u8c_blocks=u8_malloc(U8_CONTOUR_INIT_N_BLOCKS*sizeof(void *)); c->u8c_max_blocks=U8_CONTOUR_INIT_N_BLOCKS;} else if ((c->u8c_flags)&(U8_CONTOUR_BLOCKS_MALLOCD)) { int new_max=c->u8c_max_blocks*2; void **new_blocks=u8_realloc(c->u8c_blocks,new_max*sizeof(void *)); c->u8c_blocks=new_blocks; c->u8c_max_blocks=new_max;} else { int new_max=c->u8c_max_blocks*2; void **new_blocks=u8_malloc(new_max*sizeof(void *)); memcpy(new_blocks,c->u8c_blocks,sizeof(void *)*(c->u8c_n_blocks)); c->u8c_blocks=new_blocks; c->u8c_max_blocks=new_max;} }