in benchmarks/JetStream2/wasm/TSF/tsf_adaptive_reader.c [335:506]
tsf_bool_t tsf_adaptive_reader_read(void *_reader,
void *_data,
uint32_t len) {
tsf_adpt_rdr_t *reader=_reader;
uint8_t *data=_data;
if (len==0) {
return tsf_true;
}
/* this just constitutes lazy initialization upon read */
if (reader->mode==TSF_ZIP_UNKNOWN) {
if (!select_mode(reader,NULL,0,tsf_false)) {
return tsf_false;
}
}
switch (reader->mode) {
case TSF_ZIP_NONE: {
/* ok - this code is complicated. it is complicated because it
needs to deal with the possibility of a format change - if the
magic code for one of the zip formats comes in, this thing's job
is to recognize it and switch from no-zip buffering to unzipping.
we use the hint_switch() function calls as a hint of when to
look for the format changes. */
if (reader->expect_switch && reader->puti>reader->geti) {
reader->expect_switch=tsf_false;
if (reader->buf[reader->geti]==TSF_SP_C_SWITCH_FORMAT) {
if (!tear_down_and_select_mode(reader)) {
return tsf_false;
}
return tsf_adaptive_reader_read(reader,data,len);
}
}
uint32_t toread=tsf_min(reader->puti-reader->geti,len);
memcpy(data,reader->buf+reader->geti,toread);
reader->geti+=toread;
data+=toread;
len-=toread;
if (len>reader->buf_size) {
tsf_assert(reader->geti==reader->puti);
if (reader->expect_switch) {
int32_t res=reader->reader(reader->reader_arg,
data,len);
if (res<0) {
return tsf_false;
}
tsf_assert(res>0);
if (data[0]==TSF_SP_C_SWITCH_FORMAT) {
tear_down_mode(reader,NULL,NULL);
if (!select_mode(reader,data,res,tsf_false)) {
return tsf_false;
}
return tsf_adaptive_reader_read(reader,data,len);
} else {
data+=res;
len-=res;
}
}
if (!tsf_full_read_of_partial(reader->reader,
reader->reader_arg,
data,
len)) {
if (tsf_get_error_code()==TSF_E_UNEXPECTED_EOF
&& data!=_data) {
tsf_set_error(TSF_E_ERRONEOUS_EOF,
"End-of-file after part of a full buffered "
"read; original error: %s",tsf_get_error());
}
return tsf_false;
}
} else if (len>0) {
reader->puti=0;
reader->geti=0;
for (;;) {
int32_t res;
uint32_t tocopy;
res=reader->reader(reader->reader_arg,
reader->buf,
reader->buf_size);
if (res<0) {
if (tsf_get_error_code()==TSF_E_UNEXPECTED_EOF
&& data!=_data) {
tsf_set_error(TSF_E_ERRONEOUS_EOF,
"End-of-file after part of a full buffered "
"read; original error: %s",tsf_get_error());
}
return tsf_false;
}
tsf_assert(res>0);
if (reader->expect_switch) {
reader->expect_switch=tsf_false;
if (reader->buf[0]==TSF_SP_C_SWITCH_FORMAT) {
reader->puti=res;
if (!tear_down_and_select_mode(reader)) {
return tsf_false;
}
return tsf_adaptive_reader_read(reader,data,len);
}
}
tocopy=tsf_min(res,len);
memcpy(data,reader->buf,tocopy);
data+=tocopy;
len-=tocopy;
if (len==0) {
reader->puti=res;
reader->geti=tocopy;
break;
}
}
}
break;
}
case TSF_ZIP_ZLIB:
case TSF_ZIP_BZIP2: {
reader->abstract.next_out=data;
reader->abstract.avail_out=len;
for (;;) {
int res;
/* is there ever a case where we would want to call inflate even though
the input buffer is empty? */
if (reader->abstract.avail_in!=0) {
res=tsf_zip_abstract_inflate(reader->mode,
reader->stream,
&(reader->abstract),
TSF_ZIP_ACT_RUN);
if (res==TSF_ZIP_RES_ERROR) {
return tsf_false;
} else if (res==TSF_ZIP_RES_END) {
if (reader->abstract.avail_out!=0) {
tsf_set_error(TSF_E_PARSE_ERROR,
"A read request straddles a format change");
}
tear_to_none(reader);
}
if (reader->abstract.avail_out==0) {
break;
}
tsf_assert(reader->abstract.avail_in==0);
}
res=reader->reader(reader->reader_arg,
reader->buf,
reader->buf_size);
if (res==-1) {
if (tsf_get_error_code()==TSF_E_UNEXPECTED_EOF) {
tsf_set_error(TSF_E_ERRONEOUS_EOF,
"Got an EOF from the reader before the "
"decompressor had reached end of stream");
}
return tsf_false;
}
reader->abstract.next_in=reader->buf;
reader->abstract.avail_in=res;
}
break;
}
default:
tsf_set_error(TSF_E_INTERNAL,
"Invalid reader mode in tsf_adaptive_reader_read()");
return tsf_false;
}
return tsf_true;
}