gboolean li_chunkqueue_extract_to_bytearr(liVRequest *vr, liChunkQueue *cq, goffset len, GByteArray *dest) { liChunkIter ci; goffset coff, clen; g_byte_array_set_size(dest, 0); if (len > cq->length) return FALSE; g_byte_array_set_size(dest, len); g_byte_array_set_size(dest, 0); ci = li_chunkqueue_iter(cq); while (len > 0) { coff = 0; clen = li_chunkiter_length(ci); while (coff < clen) { gchar *buf; off_t we_have; if (LI_HANDLER_GO_ON != li_chunkiter_read(vr, ci, coff, len, &buf, &we_have)) goto error; g_byte_array_append(dest, (guint8*) buf, we_have); coff += we_have; len -= we_have; if (len <= 0) return TRUE; } li_chunkiter_next(&ci); } return TRUE; error: g_byte_array_set_size(dest, 0); return FALSE; }
static gboolean on_gnupg_source_input (GcrGnupgProcess *self, GnupgSource *gnupg_source, gint fd) { gssize read; if (gnupg_source->input_buf == NULL || gnupg_source->input_buf->len == 0) { if (self->pv->input == NULL) return FALSE; if (!gnupg_source->input_buf) gnupg_source->input_buf = g_byte_array_new (); g_byte_array_set_size (gnupg_source->input_buf, 4096); read = g_input_stream_read (self->pv->input, gnupg_source->input_buf->data, gnupg_source->input_buf->len, gnupg_source->cancellable, NULL); g_byte_array_set_size (gnupg_source->input_buf, read < 0 ? 0 : read); if (read < 0) return FALSE; if (read == 0) return FALSE; } if (!write_input (fd, gnupg_source->input_buf)) { g_warning ("couldn't write output data to gnupg process"); return FALSE; } return TRUE; }
static void read_from_stream (GTask *task, gpointer source_obj, gpointer task_data, GCancellable *cancellable) { LoadData *data = task_data; GError *error = NULL; gssize res; data->pos = 0; g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1); while ((res = g_input_stream_read (data->stream, data->content->data + data->pos, GET_DATA_BLOCK_SIZE, cancellable, &error)) > 0) { data->pos += res; g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1); } if (res < 0) { g_task_return_error (task, error); return; } /* zero-terminate the content; we allocated an extra byte for this */ data->content->data[data->pos] = 0; g_task_return_boolean (task, TRUE); }
/** * Closes the #fb_mqtt connection. * * @param mqtt The #fb_mqtt. **/ void fb_mqtt_close(fb_mqtt_t *mqtt) { g_return_if_fail(mqtt != NULL); if (mqtt->wev > 0) { b_event_remove(mqtt->wev); mqtt->wev = 0; } if (mqtt->rev > 0) { b_event_remove(mqtt->rev); mqtt->rev = 0; } if (mqtt->tev > 0) { b_event_remove(mqtt->tev); mqtt->tev = 0; } if (mqtt->ssl != NULL) { ssl_disconnect(mqtt->ssl); mqtt->ssl = NULL; } #ifdef DEBUG_FACEBOOK if (mqtt->wbuf->len > 0) FB_UTIL_DEBUGLN("Closing with unwritten data"); #endif /* DEBUG_FACEBOOK */ mqtt->connected = FALSE; g_clear_error(&mqtt->err); g_byte_array_set_size(mqtt->rbuf, 0); g_byte_array_set_size(mqtt->wbuf, 0); }
static gboolean dispatch_input (gint fd, GIOCondition cond, gpointer user_data) { CockpitPipe *self = (CockpitPipe *)user_data; gssize ret = 0; gsize len; gboolean eof; g_return_val_if_fail (self->priv->in_source, FALSE); len = self->priv->in_buffer->len; /* * Enable clean shutdown by not reading when we just get * G_IO_HUP. Note that when we get G_IO_ERR we do want to read * just so we can get the appropriate detailed error message. */ if (cond != G_IO_HUP) { g_debug ("%s: reading input", self->priv->name); g_byte_array_set_size (self->priv->in_buffer, len + 1024); ret = read (self->priv->in_fd, self->priv->in_buffer->data + len, 1024); if (ret < 0) { g_byte_array_set_size (self->priv->in_buffer, len); if (errno != EAGAIN && errno != EINTR) { set_problem_from_errno (self, "couldn't read", errno); close_immediately (self, NULL); /* problem already set */ return FALSE; } return TRUE; } } g_byte_array_set_size (self->priv->in_buffer, len + ret); if (ret == 0) { g_debug ("%s: end of input", self->priv->name); stop_input (self); } g_object_ref (self); eof = (self->priv->in_source == NULL); g_signal_emit (self, cockpit_pipe_sig_read, 0, self->priv->in_buffer, eof); if (eof) close_maybe (self); g_object_unref (self); return TRUE; }
static gboolean dispatch_error (gint fd, GIOCondition cond, gpointer user_data) { CockpitPipe *self = (CockpitPipe *)user_data; gssize ret = 0; gsize len; gboolean eof; g_return_val_if_fail (self->priv->err_source, FALSE); len = self->priv->err_buffer->len; /* * Enable clean shutdown by not reading when we just get * G_IO_HUP. Note that when we get G_IO_ERR we do want to read * just so we can get the appropriate detailed error message. */ if (cond != G_IO_HUP) { g_debug ("%s: reading error", self->priv->name); g_byte_array_set_size (self->priv->err_buffer, len + 1024); ret = read (self->priv->err_fd, self->priv->err_buffer->data + len, 1024); if (ret < 0) { g_byte_array_set_size (self->priv->err_buffer, len); if (errno != EAGAIN && errno != EINTR) { g_warning ("%s: couldn't read error: %s", self->priv->name, g_strerror (errno)); close_immediately (self, "internal-error"); return FALSE; } return TRUE; } } g_byte_array_set_size (self->priv->err_buffer, len + ret); if (ret == 0) { g_debug ("%s: end of error", self->priv->name); stop_error (self); } g_object_ref (self); eof = (self->priv->err_source == NULL); if (eof) close_maybe (self); g_object_unref (self); return TRUE; }
/** * json_parser_load_from_stream: * @parser: a #JsonParser * @stream: an open #GInputStream * @cancellable: (allow-none): a #GCancellable, or %NULL * @error: the return location for a #GError, or %NULL * * Loads the contents of an input stream and parses them. * * If @cancellable is not %NULL, then the operation can be cancelled by * triggering the @cancellable object from another thread. If the * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be set * on the passed @error. * * Return value: %TRUE if the data stream was successfully read and * parsed, and %FALSE otherwise * * Since: 0.12 */ gboolean json_parser_load_from_stream (JsonParser *parser, GInputStream *stream, GCancellable *cancellable, GError **error) { GByteArray *content; gsize pos; gssize res; gboolean retval = FALSE; GError *internal_error; g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; content = g_byte_array_new (); pos = 0; g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1); while ((res = g_input_stream_read (stream, content->data + pos, GET_DATA_BLOCK_SIZE, cancellable, error)) > 0) { pos += res; g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1); } if (res < 0) { /* error has already been set */ retval = FALSE; goto out; } /* zero-terminate the content; we allocated an extra byte for this */ content->data[pos] = 0; internal_error = NULL; retval = json_parser_load (parser, (const gchar *) content->data, content->len, &internal_error); if (internal_error != NULL) g_propagate_error (error, internal_error); out: g_byte_array_free (content, TRUE); return retval; }
static void _gba_randomize(GRand *r, GByteArray *gba) { gint i, max; g_byte_array_set_size(gba, 0); max = g_rand_int_range(r, 1, 15); for (i=0; i<max ; i+=4) { guint32 u32 = g_rand_int(r); g_byte_array_append(gba, (guint8*)&u32, sizeof(u32)); } g_byte_array_set_size(gba, max); }
static gboolean on_request_input (GObject *pollable_input, gpointer user_data) { GPollableInputStream *input = (GPollableInputStream *)pollable_input; CockpitRequest *request = user_data; GError *error = NULL; gsize length; gssize count; length = request->buffer->len; g_byte_array_set_size (request->buffer, length + 4096); count = g_pollable_input_stream_read_nonblocking (input, request->buffer->data + length, 4096, NULL, &error); if (count < 0) { g_byte_array_set_size (request->buffer, length); /* Just wait and try again */ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) { g_error_free (error); return TRUE; } if (!should_suppress_request_error (error)) g_warning ("couldn't read from connection: %s", error->message); cockpit_request_finish (request); g_error_free (error); return FALSE; } g_byte_array_set_size (request->buffer, length + count); if (count == 0) { if (request->eof_okay) close_io_stream (request->io); else g_debug ("caller closed connection early"); cockpit_request_finish (request); return FALSE; } /* Once we receive data EOF is unexpected (until possible next request) */ request->eof_okay = FALSE; return parse_and_process_request (request); }
static void _dummy_gba(GByteArray *gba, guint v, register guint len) { g_byte_array_set_size(gba, 0); for (register guint i=0; i<len ;++i) gba = g_byte_array_append(gba, (guint8*)&v, sizeof(v)); }
static void do_md5sum (SoupMessage *msg, SoupXMLRPCParams *params) { GVariant *args; GVariant *child; GChecksum *checksum; GByteArray *digest; gsize digest_len = 16; if (!(args = parse_params (msg, params, "(ay)"))) return; child = g_variant_get_child_value (args, 0); checksum = g_checksum_new (G_CHECKSUM_MD5); g_checksum_update (checksum, g_variant_get_data (child), g_variant_get_size (child)); digest = g_byte_array_new (); g_byte_array_set_size (digest, digest_len); g_checksum_get_digest (checksum, digest->data, &digest_len); g_checksum_free (checksum); soup_xmlrpc_message_set_response (msg, g_variant_new_from_data (G_VARIANT_TYPE_BYTESTRING, digest->data, digest_len, TRUE, NULL, NULL), NULL); g_byte_array_free (digest, TRUE); g_variant_unref (child); g_variant_unref (args); }
void packet_add_jdouble(packet_constructor_t *pc, jdouble v) { packet_add_field(pc); g_byte_array_set_size(pc->data, pc->offset + 8); jdouble_write(pc->data->data + pc->offset, v); pc->offset += 8; }
void * _cogl_buffer_map_for_fill_or_fallback (CoglBuffer *buffer) { CoglContext *ctx = buffer->context; void *ret; _COGL_RETURN_VAL_IF_FAIL (!ctx->buffer_map_fallback_in_use, NULL); ctx->buffer_map_fallback_in_use = TRUE; ret = cogl_buffer_map (buffer, COGL_BUFFER_ACCESS_WRITE, COGL_BUFFER_MAP_HINT_DISCARD); if (ret) return ret; else { /* If the map fails then we'll use a temporary buffer to fill the data and then upload it using cogl_buffer_set_data when the buffer is unmapped. The temporary buffer is shared to avoid reallocating it every time */ g_byte_array_set_size (ctx->buffer_map_fallback_array, buffer->size); buffer->flags |= COGL_BUFFER_FLAG_MAPPED_FALLBACK; return ctx->buffer_map_fallback_array->data; } }
void packet_add_jshort(packet_constructor_t *pc, jshort v) { packet_add_field(pc); g_byte_array_set_size(pc->data, pc->offset + 2); jshort_write(pc->data->data + pc->offset, v); pc->offset += 2; }
void packet_add_jfloat(packet_constructor_t *pc, jfloat v) { packet_add_field(pc); g_byte_array_set_size(pc->data, pc->offset + 4); jfloat_write(pc->data->data + pc->offset, v); pc->offset += 4; }
static void complete_read_buffer (GcrImporter *self, gssize count, GError *error) { g_assert (GCR_IS_IMPORTER (self)); g_assert (self->pv->buffer); /* A failure */ if (count == -1) { g_propagate_error (&self->pv->error, error); next_state (self, state_failure); } else { g_return_if_fail (count >= 0 && count <= BLOCK); g_byte_array_set_size (self->pv->buffer, self->pv->buffer->len - (BLOCK - count)); /* Finished reading */ if (count == 0) { /* Optimization, unref input early */ g_object_unref (self->pv->input); self->pv->input = NULL; next_state (self, state_parse_buffer); /* Read the next block */ } else { next_state (self, state_read_buffer); } } }
int main( int argc, char** argv ) { w12ibe_pub_params* pub; w12ibe_sk_id* sk; int file_len; GByteArray* aes_buf; GByteArray* plt; GByteArray* ct_buf; w12ibe_ct* ct; element_t m; parse_args(argc, argv); pub = w12ibe_pub_unserialize(suck_file(pub_file), 1); sk = w12ibe_sk_id_unserialize(pub, suck_file(prv_file), 1); read_w12ibe_file(in_file, &ct_buf, &file_len, &aes_buf); ct = w12ibe_ct_unserialize(pub, ct_buf, 1); if( !w12ibe_dec(pub, ct, sk, m) ) die("%s", w12ibe_error()); w12ibe_ct_free(ct); plt = aes_128_cbc_decrypt(aes_buf, m); g_byte_array_set_size(plt, file_len); g_byte_array_free(aes_buf, 1); //maybe I should free the sk too. However, it should be automatically been free when execution ends. spit_file(out_file, plt, 1); if( !keep ) unlink(in_file); return 0; }
static void do_md5sum (SoupMessage *msg, GValueArray *params) { GChecksum *checksum; GByteArray *data, *digest; gsize digest_len = 16; if (params->n_values != 1) { args_error (msg, params, 1); return; } if (!soup_value_array_get_nth (params, 0, SOUP_TYPE_BYTE_ARRAY, &data)) { type_error (msg, SOUP_TYPE_BYTE_ARRAY, params, 0); return; } checksum = g_checksum_new (G_CHECKSUM_MD5); g_checksum_update (checksum, data->data, data->len); digest = g_byte_array_new (); g_byte_array_set_size (digest, digest_len); g_checksum_get_digest (checksum, digest->data, &digest_len); g_checksum_free (checksum); soup_xmlrpc_set_response (msg, SOUP_TYPE_BYTE_ARRAY, digest); g_byte_array_free (digest, TRUE); }
RxBuffer* lx_read_stream_into_buffer(int fd, RxBuffer *buf, GError **error) { g_assert(buf != NULL); g_assert(error != NULL); gint32 total_length; gsize datalen = sizeof(gint32); gint noctets = lx_read_full(fd, &total_length, datalen); if (noctets < 0) { LX_ERROR_SYSCALL(error); return NULL; } else if (noctets < datalen) { LX_ERROR_MESSAGE_EOF(error, datalen, noctets); return NULL; } else { total_length = GINT32_FROM_BE(total_length); g_printf(" total_length=%d", total_length); } g_byte_array_set_size(buf->array, total_length); lx_read_full(fd, buf->array->data, total_length); g_printf(" values:%d,%d,%d,%d", (gint)buf->array->data[0], (gint)buf->array->data[1], (gint)buf->array->data[2], (gint)buf->array->data[3]); return buf; }
static void state_read_buffer (GcrImporter *self, gboolean async) { GError *error = NULL; gssize count; gsize at; g_assert (GCR_IS_IMPORTER (self)); g_assert (G_IS_INPUT_STREAM (self->pv->input)); if (!self->pv->buffer) self->pv->buffer = g_byte_array_sized_new (BLOCK); at = self->pv->buffer->len; g_byte_array_set_size (self->pv->buffer, at + BLOCK); if (async) { g_input_stream_read_async (self->pv->input, self->pv->buffer->data + at, BLOCK, G_PRIORITY_DEFAULT, self->pv->cancel, on_read_buffer, self); } else { count = g_input_stream_read (self->pv->input, self->pv->buffer->data + at, BLOCK, self->pv->cancel, &error); complete_read_buffer (self, count, error); } }
static JSBool byte_array_length_setter(JSContext *context, JS::HandleObject obj, JS::HandleId id, JSBool strict, JS::MutableHandleValue value_p) { ByteArrayInstance *priv; gsize len = 0; priv = priv_from_js(context, obj); if (priv == NULL) return JS_TRUE; /* prototype, not instance */ byte_array_ensure_array(priv); if (!gjs_value_to_gsize(context, value_p, &len)) { gjs_throw(context, "Can't set ByteArray length to non-integer"); return JS_FALSE; } g_byte_array_set_size(priv->array, len); return JS_TRUE; }
static JSBool byte_array_set_index(JSContext *context, JS::HandleObject obj, ByteArrayInstance *priv, gsize idx, JS::MutableHandleValue value_p) { guint8 v; if (!gjs_value_to_byte(context, value_p, &v)) { return JS_FALSE; } byte_array_ensure_array(priv); /* grow the array if necessary */ if (idx >= priv->array->len) { g_byte_array_set_size(priv->array, idx + 1); } g_array_index(priv->array, guint8, idx) = v; /* Stop JS from storing a copy of the value */ value_p.set(JSVAL_VOID); return JS_TRUE; }
static void copy_stack_data (MonoThreadInfo *info, void* stackdata_begin) { MonoThreadUnwindState *state; int stackdata_size; void* stackdata_end = return_stack_ptr (); SAVE_REGS_ON_STACK; state = &info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]; stackdata_size = (char*)stackdata_begin - (char*)stackdata_end; if (((gsize) stackdata_begin & (SIZEOF_VOID_P - 1)) != 0) g_error ("stackdata_begin (%p) must be %d-byte aligned", stackdata_begin, SIZEOF_VOID_P); if (((gsize) stackdata_end & (SIZEOF_VOID_P - 1)) != 0) g_error ("stackdata_end (%p) must be %d-byte aligned", stackdata_end, SIZEOF_VOID_P); if (stackdata_size <= 0) g_error ("stackdata_size = %d, but must be > 0, stackdata_begin = %p, stackdata_end = %p", stackdata_size, stackdata_begin, stackdata_end); g_byte_array_set_size (info->stackdata, stackdata_size); state->gc_stackdata = info->stackdata->data; memcpy (state->gc_stackdata, stackdata_end, stackdata_size); state->gc_stackdata_size = stackdata_size; }
static void interleaved_read_tcp_cb( struct ev_loop *loop, ev_io *w, int revents) { GByteArray *pkt; uint16_t ne_n; char buffer[RTSP_BUFFERSIZE + 1]; RTSP_interleaved_channel *intlvd = w->data; RTSP_Client *rtsp = intlvd->local->data; int n; if ((n = Sock_read(intlvd->local, buffer, RTSP_BUFFERSIZE, NULL, MSG_DONTWAIT)) < 0) { fnc_log(FNC_LOG_WARN, "Error reading from local socket\n"); return; } ne_n = htons((uint16_t)n); pkt = g_byte_array_sized_new(n+4); g_byte_array_set_size(pkt, n+4); pkt->data[0] = '$'; pkt->data[1] = (uint8_t)intlvd->channel; memcpy(&pkt->data[2], &ne_n, sizeof(ne_n)); memcpy(&pkt->data[4], buffer, n); g_queue_push_head(rtsp->out_queue, pkt); ev_io_start(rtsp->srv->loop, &rtsp->ev_io_write); }
/** * json_parser_load_from_stream_async: * @parser: a #JsonParser * @stream: a #GInputStream * @cancellable: (allow-none): a #GCancellable, or %NULL * @callback: a #GAsyncReadyCallback to call when the request is satisfied * @user_data: the data to pass to @callback * * Asynchronously reads the contents of @stream. * * For more details, see json_parser_load_from_stream() which is the * synchronous version of this call. * * When the operation is finished, @callback will be called. You should * then call json_parser_load_from_stream_finish() to get the result * of the operation. * * Since: 0.12 */ void json_parser_load_from_stream_async (JsonParser *parser, GInputStream *stream, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { LoadStreamData *data; g_return_if_fail (JSON_IS_PARSER (parser)); g_return_if_fail (G_IS_INPUT_STREAM (stream)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); data = g_new0 (LoadStreamData, 1); if (cancellable != NULL) data->cancellable = g_object_ref (cancellable); data->callback = callback; data->user_data = user_data; data->content = g_byte_array_new (); data->parser = g_object_ref (parser); g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE); g_input_stream_read_async (stream, data->content->data + data->pos, GET_DATA_BLOCK_SIZE, 0, data->cancellable, load_stream_data_read_callback, data); }
/* returns padding length */ static guint8 stream_build_fcgi_record(GByteArray *buf, guint8 type, guint16 requestid, guint16 datalen) { guint16 w; guint8 padlen = (8 - (datalen & 0x7)) % 8; /* padding must be < 8 */ g_byte_array_set_size(buf, FCGI_HEADER_LEN); g_byte_array_set_size(buf, 0); l_byte_array_append_c(buf, FCGI_VERSION_1); l_byte_array_append_c(buf, type); w = htons(requestid); g_byte_array_append(buf, (const guint8*) &w, sizeof(w)); w = htons(datalen); g_byte_array_append(buf, (const guint8*) &w, sizeof(w)); l_byte_array_append_c(buf, padlen); l_byte_array_append_c(buf, 0); return padlen; }
static void _client_reset_reply(struct gridd_client_s *client) { client->size = 0; if (!client->reply) client->reply = g_byte_array_new(); else if (client->reply->len > 0) g_byte_array_set_size(client->reply, 0); }
static void do_lookup_records (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { LookupRecordsData *lrd = task_data; GList *records; GError *error = NULL; #if defined(G_OS_UNIX) gint len = 512; gint herr; GByteArray *answer; gint rrtype; rrtype = g_resolver_record_type_to_rrtype (lrd->record_type); answer = g_byte_array_new (); for (;;) { g_byte_array_set_size (answer, len * 2); len = res_query (lrd->rrname, C_IN, rrtype, answer->data, answer->len); /* If answer fit in the buffer then we're done */ if (len < 0 || len < (gint)answer->len) break; /* * On overflow some res_query's return the length needed, others * return the full length entered. This code works in either case. */ } herr = h_errno; records = g_resolver_records_from_res_query (lrd->rrname, rrtype, answer->data, len, herr, &error); g_byte_array_free (answer, TRUE); #else DNS_STATUS status; DNS_RECORD *results = NULL; WORD dnstype; dnstype = g_resolver_record_type_to_dnstype (lrd->record_type); status = DnsQuery_A (lrd->rrname, dnstype, DNS_QUERY_STANDARD, NULL, &results, NULL); records = g_resolver_records_from_DnsQuery (lrd->rrname, dnstype, status, results, &error); if (results != NULL) DnsRecordListFree (results, DnsFreeRecordList); #endif if (records) g_task_return_pointer (task, records, (GDestroyNotify) free_records); else g_task_return_error (task, error); }
/** * cockpit_web_response_gunzip: * @bytes: the compressed bytes * @error: place to put an error * * Perform gzip decompression on the @bytes. * * Returns: the uncompressed bytes, caller owns return value. */ GBytes * cockpit_web_response_gunzip (GBytes *bytes, GError **error) { GConverter *converter; GConverterResult result; const guint8 *in; gsize inl, outl, read, written; GByteArray *out; converter = G_CONVERTER (g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP)); in = g_bytes_get_data (bytes, &inl); out = g_byte_array_new (); do { outl = out->len; g_byte_array_set_size (out, outl + inl); result = g_converter_convert (converter, in, inl, out->data + outl, inl, G_CONVERTER_INPUT_AT_END, &read, &written, error); if (result == G_CONVERTER_ERROR) break; g_byte_array_set_size (out, outl + written); in += read; inl -= read; } while (result != G_CONVERTER_FINISHED); g_object_unref (converter); if (result != G_CONVERTER_FINISHED) { g_byte_array_unref (out); return NULL; } else { return g_byte_array_free_to_bytes (out); } }
static gboolean read_headers (SoupMessage *msg, gboolean blocking, GCancellable *cancellable, GError **error) { SoupMessagePrivate *priv = SOUP_MESSAGE_GET_PRIVATE (msg); SoupMessageIOData *io = priv->io_data; gssize nread, old_len; gboolean got_lf; while (1) { old_len = io->read_header_buf->len; g_byte_array_set_size (io->read_header_buf, old_len + RESPONSE_BLOCK_SIZE); nread = soup_filter_input_stream_read_line (io->istream, io->read_header_buf->data + old_len, RESPONSE_BLOCK_SIZE, blocking, &got_lf, cancellable, error); io->read_header_buf->len = old_len + MAX (nread, 0); if (nread == 0) { soup_message_set_status (msg, SOUP_STATUS_MALFORMED); g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, _("Connection terminated unexpectedly")); } if (nread <= 0) return FALSE; if (got_lf) { if (nread == 1 && old_len >= 2 && !strncmp ((char *)io->read_header_buf->data + io->read_header_buf->len - 2, "\n\n", 2)) break; else if (nread == 2 && old_len >= 3 && !strncmp ((char *)io->read_header_buf->data + io->read_header_buf->len - 3, "\n\r\n", 3)) break; } } /* We need to "rewind" io->read_header_buf back one line. * That SHOULD be two characters (CR LF), but if the * web server was stupid, it might only be one. */ if (io->read_header_buf->len < 3 || io->read_header_buf->data[io->read_header_buf->len - 2] == '\n') io->read_header_buf->len--; else io->read_header_buf->len -= 2; io->read_header_buf->data[io->read_header_buf->len] = '\0'; return TRUE; }