1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file common.h 4207753Smm/// \brief Common functions needed in many places in liblzma 5207753Smm// 6207753Smm// Author: Lasse Collin 7207753Smm// 8207753Smm// This file has been put into the public domain. 9207753Smm// You can do whatever you want with this file. 10207753Smm// 11207753Smm/////////////////////////////////////////////////////////////////////////////// 12207753Smm 13207753Smm#include "common.h" 14207753Smm 15207753Smm 16207753Smm///////////// 17207753Smm// Version // 18207753Smm///////////// 19207753Smm 20207753Smmextern LZMA_API(uint32_t) 21207753Smmlzma_version_number(void) 22207753Smm{ 23207753Smm return LZMA_VERSION; 24207753Smm} 25207753Smm 26207753Smm 27207753Smmextern LZMA_API(const char *) 28207753Smmlzma_version_string(void) 29207753Smm{ 30207753Smm return LZMA_VERSION_STRING; 31207753Smm} 32207753Smm 33207753Smm 34207753Smm/////////////////////// 35207753Smm// Memory allocation // 36207753Smm/////////////////////// 37207753Smm 38223935Smmextern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1) 39207753Smmlzma_alloc(size_t size, lzma_allocator *allocator) 40207753Smm{ 41207753Smm // Some malloc() variants return NULL if called with size == 0. 42207753Smm if (size == 0) 43207753Smm size = 1; 44207753Smm 45207753Smm void *ptr; 46207753Smm 47207753Smm if (allocator != NULL && allocator->alloc != NULL) 48207753Smm ptr = allocator->alloc(allocator->opaque, 1, size); 49207753Smm else 50207753Smm ptr = malloc(size); 51207753Smm 52207753Smm return ptr; 53207753Smm} 54207753Smm 55207753Smm 56207753Smmextern void 57207753Smmlzma_free(void *ptr, lzma_allocator *allocator) 58207753Smm{ 59207753Smm if (allocator != NULL && allocator->free != NULL) 60207753Smm allocator->free(allocator->opaque, ptr); 61207753Smm else 62207753Smm free(ptr); 63207753Smm 64207753Smm return; 65207753Smm} 66207753Smm 67207753Smm 68207753Smm////////// 69207753Smm// Misc // 70207753Smm////////// 71207753Smm 72207753Smmextern size_t 73207753Smmlzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, 74207753Smm size_t in_size, uint8_t *restrict out, 75207753Smm size_t *restrict out_pos, size_t out_size) 76207753Smm{ 77207753Smm const size_t in_avail = in_size - *in_pos; 78207753Smm const size_t out_avail = out_size - *out_pos; 79213700Smm const size_t copy_size = my_min(in_avail, out_avail); 80207753Smm 81207753Smm memcpy(out + *out_pos, in + *in_pos, copy_size); 82207753Smm 83207753Smm *in_pos += copy_size; 84207753Smm *out_pos += copy_size; 85207753Smm 86207753Smm return copy_size; 87207753Smm} 88207753Smm 89207753Smm 90207753Smmextern lzma_ret 91207753Smmlzma_next_filter_init(lzma_next_coder *next, lzma_allocator *allocator, 92207753Smm const lzma_filter_info *filters) 93207753Smm{ 94207753Smm lzma_next_coder_init(filters[0].init, next, allocator); 95207753Smm next->id = filters[0].id; 96207753Smm return filters[0].init == NULL 97207753Smm ? LZMA_OK : filters[0].init(next, allocator, filters); 98207753Smm} 99207753Smm 100207753Smm 101207753Smmextern lzma_ret 102207753Smmlzma_next_filter_update(lzma_next_coder *next, lzma_allocator *allocator, 103207753Smm const lzma_filter *reversed_filters) 104207753Smm{ 105207753Smm // Check that the application isn't trying to change the Filter ID. 106207753Smm // End of filters is indicated with LZMA_VLI_UNKNOWN in both 107207753Smm // reversed_filters[0].id and next->id. 108207753Smm if (reversed_filters[0].id != next->id) 109207753Smm return LZMA_PROG_ERROR; 110207753Smm 111207753Smm if (reversed_filters[0].id == LZMA_VLI_UNKNOWN) 112207753Smm return LZMA_OK; 113207753Smm 114207753Smm assert(next->update != NULL); 115207753Smm return next->update(next->coder, allocator, NULL, reversed_filters); 116207753Smm} 117207753Smm 118207753Smm 119207753Smmextern void 120207753Smmlzma_next_end(lzma_next_coder *next, lzma_allocator *allocator) 121207753Smm{ 122207753Smm if (next->init != (uintptr_t)(NULL)) { 123207753Smm // To avoid tiny end functions that simply call 124207753Smm // lzma_free(coder, allocator), we allow leaving next->end 125207753Smm // NULL and call lzma_free() here. 126207753Smm if (next->end != NULL) 127207753Smm next->end(next->coder, allocator); 128207753Smm else 129207753Smm lzma_free(next->coder, allocator); 130207753Smm 131207753Smm // Reset the variables so the we don't accidentally think 132207753Smm // that it is an already initialized coder. 133207753Smm *next = LZMA_NEXT_CODER_INIT; 134207753Smm } 135207753Smm 136207753Smm return; 137207753Smm} 138207753Smm 139207753Smm 140207753Smm////////////////////////////////////// 141207753Smm// External to internal API wrapper // 142207753Smm////////////////////////////////////// 143207753Smm 144207753Smmextern lzma_ret 145207753Smmlzma_strm_init(lzma_stream *strm) 146207753Smm{ 147207753Smm if (strm == NULL) 148207753Smm return LZMA_PROG_ERROR; 149207753Smm 150207753Smm if (strm->internal == NULL) { 151207753Smm strm->internal = lzma_alloc(sizeof(lzma_internal), 152207753Smm strm->allocator); 153207753Smm if (strm->internal == NULL) 154207753Smm return LZMA_MEM_ERROR; 155207753Smm 156207753Smm strm->internal->next = LZMA_NEXT_CODER_INIT; 157207753Smm } 158207753Smm 159207753Smm strm->internal->supported_actions[LZMA_RUN] = false; 160207753Smm strm->internal->supported_actions[LZMA_SYNC_FLUSH] = false; 161207753Smm strm->internal->supported_actions[LZMA_FULL_FLUSH] = false; 162207753Smm strm->internal->supported_actions[LZMA_FINISH] = false; 163207753Smm strm->internal->sequence = ISEQ_RUN; 164207753Smm strm->internal->allow_buf_error = false; 165207753Smm 166207753Smm strm->total_in = 0; 167207753Smm strm->total_out = 0; 168207753Smm 169207753Smm return LZMA_OK; 170207753Smm} 171207753Smm 172207753Smm 173207753Smmextern LZMA_API(lzma_ret) 174207753Smmlzma_code(lzma_stream *strm, lzma_action action) 175207753Smm{ 176207753Smm // Sanity checks 177207753Smm if ((strm->next_in == NULL && strm->avail_in != 0) 178207753Smm || (strm->next_out == NULL && strm->avail_out != 0) 179207753Smm || strm->internal == NULL 180207753Smm || strm->internal->next.code == NULL 181207753Smm || (unsigned int)(action) > LZMA_FINISH 182207753Smm || !strm->internal->supported_actions[action]) 183207753Smm return LZMA_PROG_ERROR; 184207753Smm 185215187Smm // Check if unsupported members have been set to non-zero or non-NULL, 186215187Smm // which would indicate that some new feature is wanted. 187215187Smm if (strm->reserved_ptr1 != NULL 188215187Smm || strm->reserved_ptr2 != NULL 189215187Smm || strm->reserved_ptr3 != NULL 190215187Smm || strm->reserved_ptr4 != NULL 191215187Smm || strm->reserved_int1 != 0 192215187Smm || strm->reserved_int2 != 0 193215187Smm || strm->reserved_int3 != 0 194215187Smm || strm->reserved_int4 != 0 195215187Smm || strm->reserved_enum1 != LZMA_RESERVED_ENUM 196215187Smm || strm->reserved_enum2 != LZMA_RESERVED_ENUM) 197215187Smm return LZMA_OPTIONS_ERROR; 198215187Smm 199207753Smm switch (strm->internal->sequence) { 200207753Smm case ISEQ_RUN: 201207753Smm switch (action) { 202207753Smm case LZMA_RUN: 203207753Smm break; 204207753Smm 205207753Smm case LZMA_SYNC_FLUSH: 206207753Smm strm->internal->sequence = ISEQ_SYNC_FLUSH; 207207753Smm break; 208207753Smm 209207753Smm case LZMA_FULL_FLUSH: 210207753Smm strm->internal->sequence = ISEQ_FULL_FLUSH; 211207753Smm break; 212207753Smm 213207753Smm case LZMA_FINISH: 214207753Smm strm->internal->sequence = ISEQ_FINISH; 215207753Smm break; 216207753Smm } 217207753Smm 218207753Smm break; 219207753Smm 220207753Smm case ISEQ_SYNC_FLUSH: 221207753Smm // The same action must be used until we return 222207753Smm // LZMA_STREAM_END, and the amount of input must not change. 223207753Smm if (action != LZMA_SYNC_FLUSH 224207753Smm || strm->internal->avail_in != strm->avail_in) 225207753Smm return LZMA_PROG_ERROR; 226207753Smm 227207753Smm break; 228207753Smm 229207753Smm case ISEQ_FULL_FLUSH: 230207753Smm if (action != LZMA_FULL_FLUSH 231207753Smm || strm->internal->avail_in != strm->avail_in) 232207753Smm return LZMA_PROG_ERROR; 233207753Smm 234207753Smm break; 235207753Smm 236207753Smm case ISEQ_FINISH: 237207753Smm if (action != LZMA_FINISH 238207753Smm || strm->internal->avail_in != strm->avail_in) 239207753Smm return LZMA_PROG_ERROR; 240207753Smm 241207753Smm break; 242207753Smm 243207753Smm case ISEQ_END: 244207753Smm return LZMA_STREAM_END; 245207753Smm 246207753Smm case ISEQ_ERROR: 247207753Smm default: 248207753Smm return LZMA_PROG_ERROR; 249207753Smm } 250207753Smm 251207753Smm size_t in_pos = 0; 252207753Smm size_t out_pos = 0; 253207753Smm lzma_ret ret = strm->internal->next.code( 254207753Smm strm->internal->next.coder, strm->allocator, 255207753Smm strm->next_in, &in_pos, strm->avail_in, 256207753Smm strm->next_out, &out_pos, strm->avail_out, action); 257207753Smm 258207753Smm strm->next_in += in_pos; 259207753Smm strm->avail_in -= in_pos; 260207753Smm strm->total_in += in_pos; 261207753Smm 262207753Smm strm->next_out += out_pos; 263207753Smm strm->avail_out -= out_pos; 264207753Smm strm->total_out += out_pos; 265207753Smm 266207753Smm strm->internal->avail_in = strm->avail_in; 267207753Smm 268207753Smm switch (ret) { 269207753Smm case LZMA_OK: 270207753Smm // Don't return LZMA_BUF_ERROR when it happens the first time. 271207753Smm // This is to avoid returning LZMA_BUF_ERROR when avail_out 272207753Smm // was zero but still there was no more data left to written 273207753Smm // to next_out. 274207753Smm if (out_pos == 0 && in_pos == 0) { 275207753Smm if (strm->internal->allow_buf_error) 276207753Smm ret = LZMA_BUF_ERROR; 277207753Smm else 278207753Smm strm->internal->allow_buf_error = true; 279207753Smm } else { 280207753Smm strm->internal->allow_buf_error = false; 281207753Smm } 282207753Smm break; 283207753Smm 284207753Smm case LZMA_STREAM_END: 285207753Smm if (strm->internal->sequence == ISEQ_SYNC_FLUSH 286207753Smm || strm->internal->sequence == ISEQ_FULL_FLUSH) 287207753Smm strm->internal->sequence = ISEQ_RUN; 288207753Smm else 289207753Smm strm->internal->sequence = ISEQ_END; 290207753Smm 291207753Smm // Fall through 292207753Smm 293207753Smm case LZMA_NO_CHECK: 294207753Smm case LZMA_UNSUPPORTED_CHECK: 295207753Smm case LZMA_GET_CHECK: 296207753Smm case LZMA_MEMLIMIT_ERROR: 297207753Smm // Something else than LZMA_OK, but not a fatal error, 298207753Smm // that is, coding may be continued (except if ISEQ_END). 299207753Smm strm->internal->allow_buf_error = false; 300207753Smm break; 301207753Smm 302207753Smm default: 303207753Smm // All the other errors are fatal; coding cannot be continued. 304207753Smm assert(ret != LZMA_BUF_ERROR); 305207753Smm strm->internal->sequence = ISEQ_ERROR; 306207753Smm break; 307207753Smm } 308207753Smm 309207753Smm return ret; 310207753Smm} 311207753Smm 312207753Smm 313207753Smmextern LZMA_API(void) 314207753Smmlzma_end(lzma_stream *strm) 315207753Smm{ 316207753Smm if (strm != NULL && strm->internal != NULL) { 317207753Smm lzma_next_end(&strm->internal->next, strm->allocator); 318207753Smm lzma_free(strm->internal, strm->allocator); 319207753Smm strm->internal = NULL; 320207753Smm } 321207753Smm 322207753Smm return; 323207753Smm} 324207753Smm 325207753Smm 326207753Smmextern LZMA_API(lzma_check) 327207753Smmlzma_get_check(const lzma_stream *strm) 328207753Smm{ 329207753Smm // Return LZMA_CHECK_NONE if we cannot know the check type. 330207753Smm // It's a bug in the application if this happens. 331207753Smm if (strm->internal->next.get_check == NULL) 332207753Smm return LZMA_CHECK_NONE; 333207753Smm 334207753Smm return strm->internal->next.get_check(strm->internal->next.coder); 335207753Smm} 336207753Smm 337207753Smm 338207753Smmextern LZMA_API(uint64_t) 339207753Smmlzma_memusage(const lzma_stream *strm) 340207753Smm{ 341207753Smm uint64_t memusage; 342207753Smm uint64_t old_memlimit; 343207753Smm 344207753Smm if (strm == NULL || strm->internal == NULL 345207753Smm || strm->internal->next.memconfig == NULL 346207753Smm || strm->internal->next.memconfig( 347207753Smm strm->internal->next.coder, 348207753Smm &memusage, &old_memlimit, 0) != LZMA_OK) 349207753Smm return 0; 350207753Smm 351207753Smm return memusage; 352207753Smm} 353207753Smm 354207753Smm 355207753Smmextern LZMA_API(uint64_t) 356207753Smmlzma_memlimit_get(const lzma_stream *strm) 357207753Smm{ 358207753Smm uint64_t old_memlimit; 359207753Smm uint64_t memusage; 360207753Smm 361207753Smm if (strm == NULL || strm->internal == NULL 362207753Smm || strm->internal->next.memconfig == NULL 363207753Smm || strm->internal->next.memconfig( 364207753Smm strm->internal->next.coder, 365207753Smm &memusage, &old_memlimit, 0) != LZMA_OK) 366207753Smm return 0; 367207753Smm 368207753Smm return old_memlimit; 369207753Smm} 370207753Smm 371207753Smm 372207753Smmextern LZMA_API(lzma_ret) 373207753Smmlzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit) 374207753Smm{ 375207753Smm // Dummy variables to simplify memconfig functions 376207753Smm uint64_t old_memlimit; 377207753Smm uint64_t memusage; 378207753Smm 379207753Smm if (strm == NULL || strm->internal == NULL 380207753Smm || strm->internal->next.memconfig == NULL) 381207753Smm return LZMA_PROG_ERROR; 382207753Smm 383207753Smm if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE) 384207753Smm return LZMA_MEMLIMIT_ERROR; 385207753Smm 386207753Smm return strm->internal->next.memconfig(strm->internal->next.coder, 387207753Smm &memusage, &old_memlimit, new_memlimit); 388207753Smm} 389