size_t decoder_read(G_GNUC_UNUSED struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { return input_stream_read(is, buffer, length, NULL); }
size_t decoder_read(struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { size_t nbytes; assert(decoder == NULL || dc.state == DECODE_STATE_START || dc.state == DECODE_STATE_DECODE); assert(is != NULL); assert(buffer != NULL); if (length == 0) return 0; while (true) { /* XXX don't allow decoder==NULL */ if (decoder != NULL && /* ignore the SEEK command during initialization, the plugin should handle that after it has initialized successfully */ (dc.command != DECODE_COMMAND_SEEK || (dc.state != DECODE_STATE_START && !decoder->seeking)) && dc.command != DECODE_COMMAND_NONE) return 0; nbytes = input_stream_read(is, buffer, length); if (nbytes > 0 || input_stream_eof(is)) return nbytes; /* sleep for a fraction of a second! */ /* XXX don't sleep, wait for an event instead */ g_usleep(10000); } }
static int dump_input_stream(struct input_stream *is) { GError *error = NULL; char buffer[4096]; size_t num_read; ssize_t num_written; /* wait until the stream becomes ready */ while (!is->ready) { int ret = input_stream_buffer(is, &error); if (ret < 0) { /* error */ g_warning("%s", error->message); g_error_free(error); return 2; } if (ret == 0) /* nothing was buffered - wait */ g_usleep(10000); } /* print meta data */ if (is->mime != NULL) g_printerr("MIME type: %s\n", is->mime); /* read data and tags from the stream */ while (!input_stream_eof(is)) { struct tag *tag = input_stream_tag(is); if (tag != NULL) { g_printerr("Received a tag:\n"); tag_save(stderr, tag); tag_free(tag); } num_read = input_stream_read(is, buffer, sizeof(buffer), &error); if (num_read == 0) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } break; } num_written = write(1, buffer, num_read); if (num_written <= 0) break; } return 0; }
/** * Simple data fetcher. * @param url path or url of data to fetch. * @return data fetched, or NULL on error. Must be freed with g_free. */ static char * lastfm_get(const char *url, GMutex *mutex, GCond *cond) { struct input_stream *input_stream; GError *error = NULL; char buffer[4096]; size_t length = 0, nbytes; input_stream = input_stream_open(url, mutex, cond, &error); if (input_stream == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } return NULL; } g_mutex_lock(mutex); input_stream_wait_ready(input_stream); do { nbytes = input_stream_read(input_stream, buffer + length, sizeof(buffer) - length, &error); if (nbytes == 0) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } if (input_stream_eof(input_stream)) break; /* I/O error */ g_mutex_unlock(mutex); input_stream_close(input_stream); return NULL; } length += nbytes; } while (length < sizeof(buffer)); g_mutex_unlock(mutex); input_stream_close(input_stream); return g_strndup(buffer, length); }
static ya_result zdb_zone_axfr_input_stream_read(input_stream* stream_, u8* buffer, u32 len) { zdb_zone_axfr_input_stream_data* stream = (zdb_zone_axfr_input_stream_data*)stream_->data; bool first_chance_eof = FALSE; for(;;) { ya_result n = input_stream_read(&stream->filtered, buffer, len); // ERROR or SUCCESS if(n != 0) { /* log_debug("zdb_zone_axfr_input_stream_read: got %d", n); */ return n; } // EOF ... or is it ? if(first_chance_eof) { // already broken once : EOF /* log_debug("zdb_zone_axfr_input_stream_read: final EOF"); */ return 0; } if((stream->zone->axfr_timestamp != 0) || (stream->zone->axfr_serial != stream->serial)) { // file written OR file written and a new one starts to be written => done /* log_debug("zdb_zone_axfr_input_stream_read: first chance EOF"); */ first_chance_eof = TRUE; } else { // just wait /* log_debug("zdb_zone_axfr_input_stream_read: wait"); */ } usleep(100000); // 10ms } }
static sf_count_t sndfile_vio_read(void *ptr, sf_count_t count, void *user_data) { struct input_stream *is = user_data; GError *error = NULL; size_t nbytes; nbytes = input_stream_read(is, ptr, count, &error); if (nbytes == 0 && error != NULL) { g_warning("%s", error->message); g_error_free(error); return -1; } return nbytes; }
static ssize_t audiofile_file_read(AFvirtualfile *vfile, void *data, size_t length) { struct input_stream *is = (struct input_stream *) vfile->closure; GError *error = NULL; size_t nbytes; nbytes = input_stream_read(is, data, length, &error); if (nbytes == 0 && error != NULL) { g_warning("%s", error->message); g_error_free(error); return -1; } return nbytes; }
size_t decoder_read(struct decoder *decoder, struct input_stream *is, void *buffer, size_t length) { const struct decoder_control *dc = decoder != NULL ? decoder->dc : NULL; GError *error = NULL; size_t nbytes; assert(decoder == NULL || dc->state == DECODE_STATE_START || dc->state == DECODE_STATE_DECODE); assert(is != NULL); assert(buffer != NULL); if (length == 0) return 0; while (true) { /* XXX don't allow decoder==NULL */ if (decoder != NULL && /* ignore the SEEK command during initialization, the plugin should handle that after it has initialized successfully */ (dc->command != DECODE_COMMAND_SEEK || (dc->state != DECODE_STATE_START && !decoder->seeking)) && dc->command != DECODE_COMMAND_NONE) return 0; nbytes = input_stream_read(is, buffer, length, &error); if (G_UNLIKELY(nbytes == 0 && error != NULL)) { g_warning("%s", error->message); g_error_free(error); return 0; } if (nbytes > 0 || input_stream_eof(is)) return nbytes; /* sleep for a fraction of a second! */ /* XXX don't sleep, wait for an event instead */ g_usleep(10000); } }
static bool bz2_fillbuffer(struct bz2_input_stream *bis, GError **error_r) { size_t count; bz_stream *bzstream; bzstream = &bis->bzstream; if (bzstream->avail_in > 0) return true; count = input_stream_read(bis->archive->istream, bis->buffer, sizeof(bis->buffer), error_r); if (count == 0) return false; bzstream->next_in = bis->buffer; bzstream->avail_in = count; return true; }
static ya_result buffer_input_stream_read(input_stream* stream, u8* buffer, u32 len) { buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data; u8* src = data->buffer; ya_result ret; u32 remaining = data->buffer_size - data->buffer_offset; if(len <= remaining) { MEMCOPY(buffer, &src[data->buffer_offset], len); data->buffer_offset += len; /* There are still some bytes available */ return len; } /* len >= remaining : copy what remains in the buffer */ MEMCOPY(buffer, &src[data->buffer_offset], remaining); len -= remaining; buffer += remaining; /* NOTE: at this point the internal buffer is empty */ if(len >= data->buffer_maxsize) { /* It would be pointless to buffer a read bigger than the buffer */ data->buffer_offset = data->buffer_size; /* mark the buffer as "empty" */ if(ISOK(ret = input_stream_read(&data->filtered, buffer, len))) { return remaining + ret; /* the chunk we've read from the buffer + the chunk we've read from the stream */ } else // 'remaining' bytes may have been copied already, if so, return that before the error { return (remaining > 0)?remaining:ret; } } #ifdef DEBUG memset(data->buffer, 0xee, data->buffer_maxsize); #endif // What remains to read is smaller than the buffer max size: // read a full buffer if((ret = input_stream_read(&data->filtered, data->buffer, data->buffer_maxsize)) <= 0) { data->buffer_size = 0; data->buffer_offset = 0; // 'remaining' bytes may have been copied already, if so, return that before the error return (remaining > 0) ? remaining : ERROR /* eof */; } if(len > ret) { len = ret; } MEMCOPY(buffer, data->buffer, len); /* starts at offset 0 */ data->buffer_size = ret; data->buffer_offset = len; return remaining + len; }
ya_result buffer_input_stream_read_line(input_stream* stream, char* buffer, u32 len) { assert(stream->vtbl == &buffer_input_stream_vtbl); buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data; assert(data->buffer_offset <= data->buffer_size); char *src = (char*)data->buffer; if(len == 0) { return BUFFER_WOULD_OVERFLOW; } len--; u32 total = 0; /* * look for '\n' in the remaining bytes */ char *b = &src[data->buffer_offset]; s32 n = data->buffer_size - data->buffer_offset; if(n == 0) { if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0) { data->buffer_offset = 0; data->buffer_size = 0; return n /* eof */; } data->buffer_offset = 0; data->buffer_size = n; b = src; } for(;;) { n = MIN((s32)len, n); #if 0 /* fix */ #else // char *eol = (char*)memchr(b, '\n', n); if(eol != NULL) { ++eol; u32 len = eol - b; data->buffer_offset = eol - src; memcpy(buffer, b, len); buffer[len] = '\0'; return total + len; } memcpy(buffer, b, n); buffer += n; #endif // total += n; len -= (s32)n; if(len == 0) { data->buffer_offset += len; *buffer = '\0'; return total; } /* What remains to read is smaller than the buffer max size */ data->buffer_offset = 0; if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0) { data->buffer_size = 0; *buffer = '\0'; return (total > 0) ? total : ERROR /* eof */; } data->buffer_size = n; b = src; } }
ya_result buffer_input_stream_read_line(input_stream* stream, char* buffer, u32 len) { assert(stream->vtbl == &buffer_input_stream_vtbl); buffer_input_stream_data* data = (buffer_input_stream_data*)stream->data; assert(data->buffer_offset <= data->buffer_size); char *src = (char*)data->buffer; if(len == 0) { return ERROR; } len--; u32 total = 0; /* * look for '\n' in the remaining bytes */ char *b = &src[data->buffer_offset]; s32 n = data->buffer_size - data->buffer_offset; if(n == 0) { if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0) { data->buffer_offset = 0; data->buffer_size = 0; return n /* eof */; } data->buffer_offset = 0; data->buffer_size = n; b = src; } for(;;) { n = MIN((s32)len, n); char *l = &b[n]; char *p = b; while(p < l) { char c = *p++; *buffer++ = c; if(c == '\n') { data->buffer_offset = p - src; *buffer = '\0'; return total + p - b; } } total += n; len -= (s32)n; if(len == 0) { data->buffer_offset += len; *buffer = '\0'; return total; } # /* What remains to read is smaller than the buffer max size */ data->buffer_offset = 0; if((n = input_stream_read(&data->filtered, (u8*)src, data->buffer_maxsize)) <= 0) { data->buffer_size = 0; *buffer = '\0'; return (total > 0) ? total : ERROR /* eof */; } data->buffer_size = n; b = src; } }
static ssize_t audiofile_file_read(AFvirtualfile *vfile, void *data, size_t nbytes) { struct input_stream *is = (struct input_stream *) vfile->closure; return input_stream_read(is, data, nbytes); }
static ya_result xfr_input_stream_read(input_stream *is, u8 *buffer, u32 len) { xfr_input_stream_data *data = (xfr_input_stream_data*)is->data; input_stream *source_stream = &data->source_stream; message_data *message = data->message; #if DNSCORE_HAS_TSIG_SUPPORT const tsig_item *tsig = message->tsig.tsig; #endif packet_unpack_reader_data *reader = &data->reader; if(FAIL(data->last_error)) { return data->last_error; } ya_result return_value = SUCCESS; /* while there is not enough bytes on the input */ while(pipe_stream_read_available(&data->pipe_stream_input) < len) { /* read the packet and write on the output (so it can be read back on the input) */ if(FAIL(return_value = xfr_input_stream_read_packet(data))) { break; } if(data->eos) { break; } if(data->ancount > 0) { break; } /* next TCP chunk */ #ifdef DEBUG memset(&message->buffer[0], 0xee, sizeof(message->buffer)); #endif u16 tcplen; return_value = input_stream_read_nu16(source_stream, &tcplen); /* this is wrong ... */ if(return_value != 2) { #ifdef DEBUG log_debug("xfr_input_stream_read: next message is %ld bytes long", return_value); #endif break; } if(tcplen == 0) { return_value = UNEXPECTED_EOF; break; } if(FAIL(return_value = input_stream_read_fully(source_stream, message->buffer, tcplen))) { break; } #if DEBUG_XFR_INPUT_STREAM log_memdump(g_system_logger, MSG_DEBUG1, &message->buffer[0], tcplen, 32); #endif message->received = return_value; #ifdef DEBUG memset(&message->buffer[tcplen], 0xdd, DNSPACKET_MAX_LENGTH + 1 - tcplen); #endif /* * Check the headers */ const u64 *h64 = (u64*)message->buffer; const u64 m64 = AXFR_NEXT_MESSAGE_HEADER_MASK; const u64 r64 = AXFR_NEXT_MESSAGE_HEADER_RESULT; if(((*h64&m64) != r64) || (MESSAGE_NS(message->buffer) != 0)) { u8 code = MESSAGE_RCODE(message->buffer); if(code != 0) { return_value = MAKE_DNSMSG_ERROR(code); } else { return_value = UNPROCESSABLE_MESSAGE; } break; } #if DNSCORE_HAS_TSIG_SUPPORT if((data->last_message_had_tsig = (tsig != NULL))) { /* verify the TSIG * * AR > 0 * skip ALL the records until the last AR * it MUST be a TSIG * It's the first TSIG answering to our query * verify it * */ message->tsig.tsig = NULL; if(FAIL(return_value = tsig_message_extract(message))) { break; } if((return_value == 1) && (message->tsig.tsig != tsig)) { /* This is not the one we started with */ log_debug("xfr_input_stream: signature key does not match"); return_value = TSIG_BADSIG; break; } if(FAIL(return_value = tsig_verify_tcp_next_message(message))) { break; } } #endif message_header *header = (message_header*)message->buffer; data->ancount = ntohs(header->ancount); packet_reader_init(reader, message->buffer, message->received); reader->offset = DNS_HEADER_LENGTH; u16 n = ntohs(header->qdcount); while(n > 0) { if(FAIL(return_value = packet_reader_skip_fqdn(reader))) { break; } packet_reader_skip(reader, 4); n--; } } // for(;;) /* process all TCP chunks */ if(ISOK(return_value)) { if((return_value = pipe_stream_read_available(&data->pipe_stream_input)) > 0) // never fails { if(FAIL(return_value = input_stream_read(&data->pipe_stream_input, buffer, len))) { #if DNSCORE_HAS_TSIG_SUPPORT if(data->need_cleanup_tsig) { tsig_verify_tcp_last_message(message); data->need_cleanup_tsig = FALSE; } #endif } } else { // here, return_value == 0 #if DNSCORE_HAS_TSIG_SUPPORT if(tsig != NULL) { tsig_verify_tcp_last_message(message); data->need_cleanup_tsig = FALSE; if(!data->last_message_had_tsig) { /* * The stream didn't end with a TSIG * It's bad. * */ log_err("xfr_input_stream: TSIG enabled answer didn't ended with a signed packet"); return_value = TSIG_BADSIG; } } #endif } } else { #if DNSCORE_HAS_TSIG_SUPPORT // cleanup tsig_verify_tcp_last_message(message); data->need_cleanup_tsig = FALSE; #endif } data->last_error = return_value; return return_value; }
static int dump_input_stream(struct input_stream *is) { GError *error = NULL; char buffer[4096]; size_t num_read; ssize_t num_written; input_stream_lock(is); /* wait until the stream becomes ready */ input_stream_wait_ready(is); if (!input_stream_check(is, &error)) { g_warning("%s", error->message); g_error_free(error); input_stream_unlock(is); return EXIT_FAILURE; } /* print meta data */ if (is->mime != NULL) g_printerr("MIME type: %s\n", is->mime); /* read data and tags from the stream */ while (!input_stream_eof(is)) { struct tag *tag = input_stream_tag(is); if (tag != NULL) { g_printerr("Received a tag:\n"); tag_save(stderr, tag); tag_free(tag); } num_read = input_stream_read(is, buffer, sizeof(buffer), &error); if (num_read == 0) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } break; } num_written = write(1, buffer, num_read); if (num_written <= 0) break; } if (!input_stream_check(is, &error)) { g_warning("%s", error->message); g_error_free(error); input_stream_unlock(is); return EXIT_FAILURE; } input_stream_unlock(is); return 0; }
/** * Read JSON data and parse it using the given YAJL parser. * @param url URL of the JSON data. * @param hand YAJL parser handle. * @return -1 on error, 0 on success. */ static int soundcloud_parse_json(const char *url, yajl_handle hand, GMutex* mutex, GCond* cond) { struct input_stream *input_stream; GError *error = NULL; char buffer[4096]; unsigned char *ubuffer = (unsigned char *)buffer; size_t nbytes; input_stream = input_stream_open(url, mutex, cond, &error); if (input_stream == NULL) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } return -1; } g_mutex_lock(mutex); input_stream_wait_ready(input_stream); yajl_status stat; int done = 0; while (!done) { nbytes = input_stream_read(input_stream, buffer, sizeof(buffer), &error); if (nbytes == 0) { if (error != NULL) { g_warning("%s", error->message); g_error_free(error); } if (input_stream_eof(input_stream)) { done = true; } else { g_mutex_unlock(mutex); input_stream_close(input_stream); return -1; } } if (done) stat = yajl_parse_complete(hand); else stat = yajl_parse(hand, ubuffer, nbytes); if (stat != yajl_status_ok && stat != yajl_status_insufficient_data) { unsigned char *str = yajl_get_error(hand, 1, ubuffer, nbytes); g_warning("%s", str); yajl_free_error(hand, str); break; } } g_mutex_unlock(mutex); input_stream_close(input_stream); return 0; }