void fast_session_free(struct fast_session *self) { if (!self) return; fast_message_free(self->rx_messages, FAST_TEMPLATE_MAX_NUMBER); buffer_delete(self->tx_message_buffer); buffer_delete(self->tx_pmap_buffer); buffer_delete(self->rx_buffer); free(self); }
// Delete data between self and other int mark_delete_between_mark(mark_t* self, mark_t* other) { bint_t offset_a; bint_t offset_b; buffer_get_offset(self->bline->buffer, self->bline, self->col, &offset_a); buffer_get_offset(other->bline->buffer, other->bline, other->col, &offset_b); if (offset_a == offset_b) { return MLBUF_OK; } else if (offset_a > offset_b) { return buffer_delete(self->bline->buffer, offset_b, offset_a - offset_b); } return buffer_delete(self->bline->buffer, offset_a, offset_b - offset_a); }
static int luastream_release (lua_State *L) { lua_Stream *self = (lua_Stream *)luaL_checkudata(L, 1, LUA_STREAM); if (self->buf) buffer_delete(&self->buf); return 0; }
static int luastream_insert (lua_State *L) { int i, top = lua_gettop(L); struct writer_t W; lua_Stream *self = (lua_Stream *)luaL_checkudata(L, 1, LUA_STREAM); size_t size, pos = luaL_checkint(L, 2); luaL_check(self->buf, "%s (released) #1", LUA_STREAM); luaL_check(pos <= buffer_tell(&self->buf), "out of range #2"); W.count = 0; if (pos < buffer_tell(&self->buf)) { buffer_t buf = buffer_new(BUFF_SIZE); for (i = 3, W.pos = 0; i <= top; ++i, W.pos = buffer_tell(&buf)) buffer_writeobject(L, &buf, i, &W); size = buffer_tell(&buf); buffer_insert(&self->buf, pos, buffer_ptr(&buf), size); buffer_delete(&buf); } else { for (i = 3, W.pos = pos; i <= top; ++i, W.pos = buffer_tell(&self->buf)) buffer_writeobject(L, &self->buf, i, &W); size = buffer_tell(&self->buf) - pos; } lua_pushnumber(L, pos); lua_pushnumber(L, pos + size); return 2; }
static bool replicator_send_buf(struct replicator_connection *conn, buffer_t *buf) { const unsigned char *data = buf->data; unsigned int len = IO_BLOCK_SIZE; /* try to send about IO_BLOCK_SIZE amount of data, but only full lines */ if (len > buf->used) len = buf->used; for (;; len++) { i_assert(len < buf->used); /* there is always LF */ if (data[len] == '\n') { len++; break; } } if (o_stream_send(conn->output, data, len) < 0) { replicator_connection_disconnect(conn); return FALSE; } buffer_delete(buf, 0, len); return TRUE; }
static int o_stream_ssl_flush_buffer(struct ssl_ostream *sstream) { size_t pos = 0; int ret = 1; while (pos < sstream->buffer->used) { /* we're writing plaintext data to OpenSSL, which it encrypts and writes to bio_int's buffer. ssl_iostream_bio_sync() reads it from there and adds to plain_output stream. */ ret = SSL_write(sstream->ssl_io->ssl, CONST_PTR_OFFSET(sstream->buffer->data, pos), sstream->buffer->used - pos); if (ret <= 0) { ret = openssl_iostream_handle_write_error(sstream->ssl_io, ret, "SSL_write"); if (ret < 0) { io_stream_set_error(&sstream->ostream.iostream, "%s", sstream->ssl_io->last_error); sstream->ostream.ostream.stream_errno = errno; break; } if (ret == 0) break; } else { pos += ret; (void)openssl_iostream_bio_sync(sstream->ssl_io); } } buffer_delete(sstream->buffer, 0, pos); return ret <= 0 ? ret : 1; }
/* variable_destroy */ static void _variable_destroy(Variable * variable) { switch(variable->type) { case VT_NULL: case VT_BOOL: case VT_INT8: case VT_UINT8: case VT_INT16: case VT_UINT16: case VT_INT32: case VT_UINT32: case VT_INT64: case VT_UINT64: case VT_FLOAT: case VT_DOUBLE: break; case VT_BUFFER: buffer_delete(variable->u.buffer); break; case VT_STRING: string_delete(variable->u.string); break; } }
/* ssl_client_send */ static int _ssl_client_send(SSLTransport * ssl, AppTransportClient * client, AppMessage * message) { size_t i; SSLSocket * s; Buffer * buffer; if(ssl->mode != ATM_SERVER) return -error_set_code(1, "%s", "Not a server"); /* lookup the client */ for(i = 0; i < ssl->u.server.clients_cnt; i++) { s = ssl->u.server.clients[i]; if(s->client == client) break; } if(i == ssl->u.server.clients_cnt) return -error_set_code(1, "%s", "Unknown client"); /* send the message */ if((buffer = buffer_new(0, NULL)) == NULL) return -1; if(appmessage_serialize(message, buffer) != 0 || _ssl_socket_queue(s, buffer) != 0) { buffer_delete(buffer); return -1; } return 0; }
void CPeerBase::Destroy() { Disconnect(); if (m_outBuffer) { buffer_delete(m_outBuffer); m_outBuffer = NULL; } if (m_inBuffer) { buffer_delete(m_inBuffer); m_inBuffer = NULL; } }
static int _serialize_call(AppMessage * message, Buffer * buffer, Buffer * b) { int ret; Variable * v; size_t i; if(_serialize_id(message, buffer, b) != 0) return -1; if((v = variable_new(VT_STRING, message->t.call.method)) == NULL) return -1; ret = (variable_serialize(v, b, 0) == 0 && _serialize_append(buffer, b) == 0) ? 0 : -1; variable_delete(v); if(ret != 0) return ret; for(i = 0; i < message->t.call.args_cnt; i++) { if(message->t.call.args[i].direction == AMCD_OUT) continue; if(variable_serialize(message->t.call.args[i].arg, b, 1) != 0 || _serialize_append(buffer, b) != 0) break; } buffer_delete(b); return (i == message->t.call.args_cnt) ? 0 : -1; }
int ast_assign_execute( struct ast_assign *a, time_t stoptime ) { int result; if(a->expr) { char *value; char *word; value = expr_eval(a->expr,stoptime); if(value) { word = ast_bareword_execute(a->line,value); if(word) { ftsh_error(FTSH_ERROR_COMMAND,a->line,"%s=%s",a->name->text,word); if(buffer_save(a->name->text,word)) { result=1; } else { ftsh_error(FTSH_ERROR_FAILURE,a->line,"couldn't store variable '%s': %s",a->name->text,strerror(errno)); result=0; } free(word); } else { result = 0; } free(value); } else { result=0; } } else { ftsh_error(FTSH_ERROR_COMMAND,a->line,"%s=",a->name->text); buffer_delete(a->name->text); result = 1; } return result; }
char *chirp_ticket_tostring(struct chirp_ticket *ct) { size_t n; const char *s; char *result; buffer_t *B; B = buffer_create(); buffer_printf(B, "subject \"%s\"\n", ct->subject); buffer_printf(B, "ticket \"%s\"\n", ct->ticket); buffer_printf(B, "expiration \"%lu\"\n", (unsigned long) ct->expiration); for(n = 0; n < ct->nrights; n++) { buffer_printf(B, "rights \"%s\" \"%s\"\n", ct->rights[n].directory, ct->rights[n].acl); } s = buffer_tostring(B, &n); result = xxmalloc(n + 1); memset(result, 0, n + 1); memcpy(result, s, n); buffer_delete(B); return result; }
void test_boe_replay_complete(void) { struct boe_message *msg = (void *) recv_buffer; struct buffer *buf; int fd; buf = buffer_new(1024); fd = open(DATA_PATH "replay-complete-message.bin", O_RDONLY); fail_if(fd < 0); fail_if(buffer_xread(buf, fd) < 0); fail_if(boe_message_decode(buf, msg, BOE_MAX_MESSAGE_LEN) < 0); assert_int_equals(BOE_MAGIC, msg->header.StartOfMessage); assert_int_equals(8, msg->header.MessageLength); assert_int_equals(ReplayComplete, msg->header.MessageType); assert_int_equals(0, msg->header.MatchingUnit); assert_int_equals(0, msg->header.SequenceNumber); buffer_delete(buf); fail_if(close(fd) < 0); }
static void teardown(void) { buffer_delete(buf); mbt_quote_message_delete(mbt_msg); mbt_msg = NULL; }
/* ssl_socket_queue */ static int _ssl_socket_queue(SSLSocket * sslsocket, Buffer * buffer) { uint32_t len; char * p; Variable * v; Buffer * b = NULL; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d)\n", __func__, sslsocket->fd); #endif /* serialize the buffer */ v = variable_new(VT_BUFFER, buffer); b = buffer_new(0, NULL); if(v == NULL || b == NULL || variable_serialize(v, b, 0) != 0) { if(v != NULL) variable_delete(v); if(b != NULL) buffer_delete(b); return -1; } variable_delete(v); len = buffer_get_size(b); /* FIXME queue the serialized buffer directly as a message instead */ if((p = realloc(sslsocket->bufout, sslsocket->bufout_cnt + len)) == NULL) { buffer_delete(b); return -1; } sslsocket->bufout = p; memcpy(&p[sslsocket->bufout_cnt], buffer_get_data(b), len); /* register the callback if necessary */ if(sslsocket->bufout_cnt == 0) event_register_io_write(sslsocket->transport->helper->event, sslsocket->fd, (EventIOFunc)_ssl_socket_callback_write, sslsocket); sslsocket->bufout_cnt += len; buffer_delete(b); #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d) => %d\n", __func__, sslsocket->fd, 0); #endif return 0; }
int cbfs_image_delete(struct cbfs_image *image) { if (image == NULL) return 0; buffer_delete(&image->buffer); image->header = NULL; return 0; }
/* ssl_send */ static int _ssl_send(SSLTransport * ssl, AppMessage * message) { Buffer * buffer; if(ssl->mode != ATM_CLIENT) return -error_set_code(1, "%s", "Not a client"); /* send the message */ if((buffer = buffer_new(0, NULL)) == NULL) return -1; if(appmessage_serialize(message, buffer) != 0 || _ssl_socket_queue(&ssl->u.client, buffer) != 0) { buffer_delete(buffer); return -1; } buffer_delete(buffer); return 0; }
void test_boe_login_response(void) { struct boe_login_response *login; struct boe_message *msg = (void *) recv_buffer; struct buffer *buf; int fd; buf = buffer_new(1024); fd = open(DATA_PATH "login-response-message.bin", O_RDONLY); fail_if(fd < 0); fail_if(buffer_xread(buf, fd) < 0); fail_if(boe_message_decode(buf, msg, BOE_MAX_MESSAGE_LEN) < 0); login = boe_message_payload(msg); assert_int_equals(BOE_MAGIC, msg->header.StartOfMessage); assert_int_equals(183, msg->header.MessageLength); assert_int_equals(LoginResponse, msg->header.MessageType); assert_int_equals(0, msg->header.MatchingUnit); assert_int_equals(0, msg->header.SequenceNumber); assert_int_equals('A', login->LoginResponseStatus); assert_mem_equals("Accepted", login->LoginResponseText, strlen("Accepted")); assert_int_equals(0, login->NoUnspecifiedUnitReplay); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderAcknowledgementBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderRejectedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderModifiedBitfields); assert_int_equals(0, login->OrderRestatedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->UserModifyRejectedBitfields); assert_int_equals(0, login->OrderCancelledBitfields); assert_int_equals(0, login->CancelRejectedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderExecutionBitfields); assert_int_equals(Symbol, login->TradeCancelOrCorrectBitfields); assert_int_equals(0, login->ReservedBitfields1); assert_int_equals(0, login->ReservedBitfields2); assert_int_equals(4, login->NumberOfUnits); assert_int_equals(1, login->Units[0].UnitNumber); assert_int_equals(113482, login->Units[0].UnitSequence); assert_int_equals(2, login->Units[1].UnitNumber); assert_int_equals(0, login->Units[1].UnitSequence); assert_int_equals(3, login->Units[2].UnitNumber); assert_int_equals(0, login->Units[2].UnitSequence); assert_int_equals(4, login->Units[3].UnitNumber); assert_int_equals(41337, login->Units[3].UnitSequence); buffer_delete(buf); fail_if(close(fd) < 0); }
int advertise_master_to_catalog(const char *catalog_host, int catalog_port, const char *project_name, const char *master_address, struct work_queue_stats *s, struct work_queue_resources *r, const char *workers_by_pool ) { char address[DATAGRAM_ADDRESS_MAX]; char owner[USERNAME_MAX]; buffer_t *buffer = NULL; const char *text; size_t text_size; if(!outgoing_datagram) { outgoing_datagram = datagram_create(0); if(!outgoing_datagram) { fprintf(stderr, "Failed to advertise master to catalog server: couldn't create outgoing udp datagram!\n"); return 0; } } if(!username_get(owner)) { strcpy(owner,"unknown"); } buffer = buffer_create(); int total_workers_working = s->workers_busy + s->workers_full; int total_workers = total_workers_working + s->workers_ready; debug(D_WQ,"%s advertising resources to the Catalog -- cores:%d memory:%d disk:%d\n",project_name,r->cores.total,r->memory.total,r->disk.total); //debug to see if information is being passed buffer_printf(buffer, "type wq_master\n" "project %s\nstarttime %llu\npriority %d\n" "port %d\nlifetime %d\n" "tasks_waiting %d\ntasks_complete %d\ntasks_running %d\ntotal_tasks_dispatched %d\n" "workers_init %d\nworkers_ready %d\nworkers_busy %d\nworkers %d\nworkers_by_pool %s\n" "cores_total %d\nmemory_total %d\ndisk_total %d\n" "capacity %d\n" "my_master %s\n" "version %d.%d.%s\nowner %s", project_name, (s->start_time)/1000000, s->priority, s->port, WORK_QUEUE_CATALOG_MASTER_AD_LIFETIME, s->tasks_waiting, s->total_tasks_complete, s->tasks_running, s->total_tasks_dispatched, s->workers_init, s->workers_ready, total_workers_working, total_workers, workers_by_pool, r->cores.total, r->memory.total, r->disk.total, s->capacity, master_address, CCTOOLS_VERSION_MAJOR, CCTOOLS_VERSION_MINOR, CCTOOLS_VERSION_MICRO, owner); text = buffer_tostring(buffer, &text_size); if(domain_name_cache_lookup(catalog_host, address)) { debug(D_WQ, "Advertising master status to the catalog server at %s:%d ...", catalog_host, catalog_port); datagram_send(outgoing_datagram, text, strlen(text), address, catalog_port); } buffer_delete(buffer); return 1; }
void test_boe_login_request(void) { struct boe_login_request *login; struct boe_message *msg = (void *) recv_buffer; struct buffer *buf; int fd; buf = buffer_new(1024); fd = open(DATA_PATH "login-request-message.bin", O_RDONLY); fail_if(fd < 0); fail_if(buffer_xread(buf, fd) < 0); fail_if(boe_message_decode(buf, msg, BOE_MAX_MESSAGE_LEN) < 0); login = boe_message_payload(msg); assert_int_equals(BOE_MAGIC, msg->header.StartOfMessage); assert_int_equals(131, msg->header.MessageLength); assert_int_equals(LoginRequest, msg->header.MessageType); assert_int_equals(0, msg->header.MatchingUnit); assert_int_equals(0, msg->header.SequenceNumber); assert_mem_equals("0001", login->SessionSubID, ARRAY_SIZE(login->SessionSubID)); assert_mem_equals("TEST", login->Username, ARRAY_SIZE(login->Username)); assert_mem_equals("TESTING\0\0\0", login->Password, ARRAY_SIZE(login->Password)); assert_int_equals(0, login->NoUnspecifiedUnitReplay); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderAcknowledgementBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderRejectedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderModifiedBitfields); assert_int_equals(0, login->OrderRestatedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->UserModifyRejectedBitfields); assert_int_equals(0, login->OrderCancelledBitfields); assert_int_equals(0, login->CancelRejectedBitfields); assert_int_equals(Symbol|ClearingFirm|ClearingAccount, login->OrderExecutionBitfields); assert_int_equals(Symbol, login->TradeCancelOrCorrectBitfields); assert_int_equals(0, login->ReservedBitfields1); assert_int_equals(0, login->ReservedBitfields2); assert_int_equals(3, login->NumberOfUnits); assert_int_equals(1, login->Units[0].UnitNumber); assert_int_equals(113482, login->Units[0].UnitSequence); assert_int_equals(2, login->Units[1].UnitNumber); assert_int_equals(0, login->Units[1].UnitSequence); assert_int_equals(4, login->Units[2].UnitNumber); assert_int_equals(41337, login->Units[2].UnitSequence); buffer_delete(buf); fail_if(close(fd) < 0); }
/* video_destroy */ static void _video_destroy(VideoPhonePlugin * video) { if(video->window != NULL) gtk_widget_destroy(video->window); if(video->source != 0) g_source_remove(video->source); if(video->fd >= 0) close(video->fd); buffer_delete(video->buffer); object_delete(video); }
void partitioned_file_close(partitioned_file_t *file) { if (!file) return; file->fmap = NULL; buffer_delete(&file->buffer); if (file->stream) { fclose(file->stream); file->stream = NULL; } free(file); }
TEST(Buffer, Simple) { buffer * buf = NULL; buf = buffer_new(8); EXPECT_TRUE(buf != NULL); EXPECT_EQ(buf->used, 0); EXPECT_EQ(buf->size, 8); buffer_delete(buf); EXPECT_EQ(buf->used, 0); buffer_destroy(buf); }
static ssize_t old_fashioned_read(struct text *text) { char *raw; ssize_t got, total = 0; size_t max; #define CHUNK 1024 do { buffer_insert(text->buffer, NULL, total, CHUNK); max = buffer_raw(text->buffer, &raw, total, CHUNK); errno = 0; got = read(text->fd, raw, max); if (got < 0) { message("%s: can't read", path_format(text->path)); buffer_delete(text->buffer, 0, total + CHUNK); return -1; } buffer_delete(text->buffer, total + got, CHUNK - got); total += got; } while (got); return total; }
static void unhash_link(storage_t storage, const char *path, const struct element *elem) { char *download_path; struct buffer *descr; if (options['v']) printf("%s\n", path); download_path = path_concat("objects", elem->hash); if ((descr = storage_retrieve_buffer(storage, download_path)) == NULL) errx(EXIT_FAILURE, "unable to retrieve: %s", path); free(download_path); if (symlink((char *) descr->data, path) == -1 && errno != EEXIST) err(EXIT_FAILURE, "unable to restore: %s", path); buffer_delete(descr); }
int advertise_pool_decision_to_catalog(const char *catalog_host, int catalog_port, const char *pool_name, pid_t pid, time_t start_time, const char *decision, int workers_requested) { char address[DATAGRAM_ADDRESS_MAX]; char owner[USERNAME_MAX]; buffer_t *buffer = NULL; const char *text; size_t text_size; static time_t last_update_time = 0; if(time(0) - last_update_time < WORK_QUEUE_CATALOG_POOL_UPDATE_INTERVAL) return 1; if(!outgoing_datagram) { outgoing_datagram = datagram_create(0); if(!outgoing_datagram) { fprintf(stderr, "Couldn't create outgoing udp port, thus work queue master info won't be sent to the catalog server!\n"); return 0; } } if(!username_get(owner)) { strcpy(owner,"unknown"); } // port = MAX_TCP_PORT + process id, this is for the catalog server to // distinguish the worker pools from the same host. See make_hash_key() // function in catalog_server.c INT64_T port = 65535 + pid; buffer = buffer_create(); buffer_printf(buffer, "type wq_pool\npool_name %s\nport %lld\nstarttime %llu\ndecision %s\nworkers_requested %d\nowner %s\nlifetime %d", pool_name, port, start_time, decision, workers_requested, owner, WORK_QUEUE_CATALOG_POOL_AD_LIFETIME); text = buffer_tostring(buffer, &text_size); debug(D_WQ, "Pool AD: \n%s\n", text); if(domain_name_cache_lookup(catalog_host, address)) { debug(D_WQ, "Sending the pool decision to the catalog server at %s:%d ...", catalog_host, catalog_port); datagram_send(outgoing_datagram, text, text_size, address, catalog_port); } buffer_delete(buffer); last_update_time = time(0); return 1; }
static void unhash_file(storage_t storage, const char *path, const struct element *elem) { FILE *res; char *download_path; FILE *descr; char buf[4096]; char *blob_hash; struct buffer *blob; if (options['v']) printf("%s\n", path); if ((res = fopen(path, "wb")) == NULL) err(EXIT_FAILURE, "unable to restore: %s", path); download_path = path_concat("objects", elem->hash); if ((descr = storage_retrieve_file(storage, download_path)) == NULL) errx(EXIT_FAILURE, "unable to retrieve: %s", path); free(download_path); while ((blob_hash = fgets(buf, 4096, descr)) != NULL) { size_t size, full_size; size = strlen(blob_hash); if (blob_hash[size - 1] != '\n') errx(EXIT_FAILURE, "invalid description file: %s", path); blob_hash[size - 1] = '\0'; blob = unhash_blob(storage, path, blob_hash); full_size = 0; while ((size = fwrite(blob->data + full_size, 1, blob->used - full_size, res)) > 0) full_size += size; buffer_delete(blob); } if (ferror(descr)) errx(EXIT_FAILURE, "unable to restore: %s", path); fclose(res); fclose(descr); }
void test_boe_logout(void) { struct boe_logout *logout; struct boe_message *msg = (void *) recv_buffer; struct buffer *buf; int fd; buf = buffer_new(1024); fd = open(DATA_PATH "logout-message.bin", O_RDONLY); fail_if(fd < 0); fail_if(buffer_xread(buf, fd) < 0); fail_if(boe_message_decode(buf, msg, BOE_MAX_MESSAGE_LEN) < 0); logout = boe_message_payload(msg); assert_int_equals(BOE_MAGIC, msg->header.StartOfMessage); assert_int_equals(89, msg->header.MessageLength); assert_int_equals(Logout, msg->header.MessageType); assert_int_equals(0, msg->header.MatchingUnit); assert_int_equals(0, msg->header.SequenceNumber); assert_int_equals('U', logout->LogoutReason); assert_mem_equals("User", logout->LogoutReasonText, 4); assert_int_equals(103231, logout->LastReceivedSequenceNumber); assert_int_equals(3, logout->NumberOfUnits); assert_int_equals(1, logout->Units[0].UnitNumber); assert_int_equals(113482, logout->Units[0].UnitSequence); assert_int_equals(2, logout->Units[1].UnitNumber); assert_int_equals(0, logout->Units[1].UnitSequence); assert_int_equals(4, logout->Units[2].UnitNumber); assert_int_equals(41337, logout->Units[2].UnitSequence); buffer_delete(buf); fail_if(close(fd) < 0); }
framer_t * framer_create() { framer_t *framer = (framer_t*) malloc(sizeof(*framer)); if (framer == NULL) goto Error; memset(framer, 0, sizeof(*framer)); framer->parser = XML_ParserCreateNS(NULL, /* ':' */ '\xFF'); if (framer->parser == NULL) goto Error; XML_SetElementHandler( framer->parser, framer_start, framer_end); XML_SetUserData( framer->parser, framer); framer->level = 0; framer->error = 0; framer->index = 0; framer->buffer_index = 0; framer->head = framer->tail = NULL; /* TODO: create buffers with limited maximum length */ framer->buffer = buffer_create(0); if (framer->buffer == NULL) goto Error; return framer; Error: if (framer != NULL) { if (framer->buffer != NULL) buffer_delete(framer->buffer); if (framer->parser != NULL) XML_ParserFree(framer->parser); } return NULL; }
static ssize_t i_stream_callback_read(struct istream_private *stream) { struct callback_istream *cstream = (struct callback_istream *)stream; size_t pos; if (cstream->callback == NULL) { /* already returned EOF / error */ stream->istream.eof = TRUE; return -1; } if (stream->skip > 0) { buffer_delete(cstream->buf, 0, stream->skip); stream->pos -= stream->skip; cstream->prev_pos -= stream->skip; stream->skip = 0; } i_assert(cstream->buf->used >= cstream->prev_pos); pos = cstream->prev_pos; if (cstream->buf->used > pos) { /* data was added outside the callback */ } else if (!cstream->callback(cstream->buf, cstream->context)) { /* EOF / error */ stream->istream.eof = TRUE; cstream->callback = NULL; if (cstream->buf->used == pos || stream->istream.stream_errno != 0) return -1; /* EOF was returned with some data still added to the buffer. return the buffer first and EOF only on the next call. */ } else if (cstream->buf->used == pos) { /* buffer full */ i_assert(cstream->buf->used > 0); return -2; } i_assert(cstream->buf->used > pos); stream->buffer = cstream->buf->data; cstream->prev_pos = stream->pos = cstream->buf->used; return cstream->buf->used - pos; }