size_t read_some_impl(char const * buf, size_t len) { m_alog->write(log::alevel::devel,"debug_con read_some"); if (!m_reading) { m_elog->write(log::elevel::devel,"write while not reading"); return 0; } size_t bytes_to_copy = (std::min)(len,m_len-m_cursor); std::copy(buf,buf+bytes_to_copy,m_buf+m_cursor); m_cursor += bytes_to_copy; if (m_cursor >= m_bytes_needed) { complete_read(lib::error_code()); } return bytes_to_copy; }
/* read an mp3 stream which does not have shoutcast style metadata */ static refbuf_t *mp3_get_no_meta (source_t *source) { refbuf_t *refbuf; mp3_state *source_mp3 = source->format->_state; if (complete_read (source) == 0) return NULL; refbuf = source_mp3->read_data; source_mp3->read_data = NULL; if (source_mp3->update_metadata) { mp3_set_title (source); source_mp3->update_metadata = 0; } refbuf->associated = source_mp3->metadata; refbuf_addref (source_mp3->metadata); refbuf->sync_point = 1; return refbuf; }
static void complete(iocp_result_t *result, bool success, DWORD num_transferred) { result->iocpd->ops_in_progress--; DWORD status = success ? 0 : GetLastError(); switch (result->type) { case IOCP_ACCEPT: complete_accept((accept_result_t *) result, status); break; case IOCP_CONNECT: complete_connect((connect_result_t *) result, status); break; case IOCP_WRITE: complete_write((write_result_t *) result, num_transferred, status); break; case IOCP_READ: complete_read((read_result_t *) result, num_transferred, status); break; default: assert(false); } }
/* read mp3 data with inlined metadata from the source. Filter out the * metadata so that the mp3 data itself is store on the queue and the * metadata is is associated with it */ static refbuf_t *mp3_get_filter_meta (source_t *source) { refbuf_t *refbuf; format_plugin_t *plugin = source->format; mp3_state *source_mp3 = plugin->_state; unsigned char *src; unsigned int bytes, mp3_block; if (complete_read (source) == 0) return NULL; refbuf = source_mp3->read_data; source_mp3->read_data = NULL; src = (unsigned char *)refbuf->data; if (source_mp3->update_metadata) { mp3_set_title (source); source_mp3->update_metadata = 0; } /* fill the buffer with the read data */ bytes = source_mp3->read_count; refbuf->len = 0; while (bytes > 0) { unsigned int metadata_remaining; mp3_block = source_mp3->inline_metadata_interval - source_mp3->offset; /* is there only enough to account for mp3 data */ if (bytes <= mp3_block) { refbuf->len += bytes; source_mp3->offset += bytes; break; } /* we have enough data to get to the metadata * block, but only transfer upto it */ if (mp3_block) { src += mp3_block; bytes -= mp3_block; refbuf->len += mp3_block; source_mp3->offset += mp3_block; continue; } /* process the inline metadata, len == 0 indicates not seen any yet */ if (source_mp3->build_metadata_len == 0) { memset (source_mp3->build_metadata, 0, sizeof (source_mp3->build_metadata)); source_mp3->build_metadata_offset = 0; source_mp3->build_metadata_len = 1 + (*src * 16); } /* do we have all of the metatdata block */ metadata_remaining = source_mp3->build_metadata_len - source_mp3->build_metadata_offset; if (bytes < metadata_remaining) { memcpy (source_mp3->build_metadata + source_mp3->build_metadata_offset, src, bytes); source_mp3->build_metadata_offset += bytes; break; } /* copy all bytes except the last one, that way we * know a null byte terminates the message */ memcpy (source_mp3->build_metadata + source_mp3->build_metadata_offset, src, metadata_remaining-1); /* overwrite metadata in the buffer */ bytes -= metadata_remaining; memmove (src, src+metadata_remaining, bytes); /* assign metadata if it's greater than 1 byte, and the text has changed */ if (source_mp3->build_metadata_len > 1 && strcmp (source_mp3->build_metadata+1, source_mp3->metadata->data+1) != 0) { refbuf_t *meta = refbuf_new (source_mp3->build_metadata_len); memcpy (meta->data, source_mp3->build_metadata, source_mp3->build_metadata_len); ICECAST_LOG_DEBUG("shoutcast metadata %.*s", 4080, meta->data+1); if (strncmp (meta->data+1, "StreamTitle=", 12) == 0) { filter_shoutcast_metadata (source, source_mp3->build_metadata, source_mp3->build_metadata_len); refbuf_release (source_mp3->metadata); source_mp3->metadata = meta; source_mp3->inline_url = strstr (meta->data+1, "StreamUrl='"); } else { ICECAST_LOG_ERROR("Incorrect metadata format, ending stream"); source->running = 0; refbuf_release (refbuf); refbuf_release (meta); return NULL; } } source_mp3->offset = 0; source_mp3->build_metadata_len = 0; } /* the data we have just read may of just been metadata */ if (refbuf->len == 0) { refbuf_release (refbuf); return NULL; } refbuf->associated = source_mp3->metadata; refbuf_addref (source_mp3->metadata); refbuf->sync_point = 1; return refbuf; }
int scream_receive (int *thisblocknr, uint8_t *buf, int buflen) { int n, blocknr; FILE *fd; switch (protocol) { case SCM_PROTO_UDP: memset(buf,0,buflen); /* try to get 1077 bytes here */ n = read ( sockfd, buf, buflen); if ( n < 0 ) fatal (("recv failed - no UDP connection ?")); /* useful for writing the raw GCF records to file */ if ( dumpfile != NULL ) { fd = (FILE *) fopen (dumpfile, "a"); if ( fd != NULL ) { fwrite (buf, 1, 1077, fd); fclose (fd); } } if (DEBUG==1) printf("version = %d GCF_BLOCK_LEN=%d \n", buf[GCF_BLOCK_LEN], GCF_BLOCK_LEN); switch (buf[GCF_BLOCK_LEN]) { case 31: blocknr = buf[GCF_BLOCK_LEN+34]*256 + buf[GCF_BLOCK_LEN+35]; break; case 40: blocknr = buf[GCF_BLOCK_LEN+2]*256 + buf[GCF_BLOCK_LEN+3]; break; case 45: blocknr = buf[GCF_BLOCK_LEN+2]*256 + buf[GCF_BLOCK_LEN+3]; break; default: fprintf(stderr, "Scream version ID = %d\n", buf[GCF_BLOCK_LEN]); fatal (("Unknown version of scream protocol at remote end")); break; } if(DEBUG==1) printf("Got UDP blocknr = %d\n", blocknr); *thisblocknr = blocknr; break; case SCM_PROTO_TCP: if (dropflag) { printf("read failed, closing connection\n"); close(sockfd); sockfd = -1; return 1; } if (complete_read(sockfd, (char *) buf, SCREAM_INITIAL_LEN) != SCREAM_INITIAL_LEN) { printf("read failed, closing connection\n"); close(sockfd); sockfd = -1; return 1; } switch (buf[GCF_BLOCK_LEN]) { case 31: if (complete_read(sockfd, (char *) buf + SCREAM_INITIAL_LEN, SCREAM_V31_SUBSEQUENT) != SCREAM_V31_SUBSEQUENT) { printf("read failed: %m\n"); close(sockfd); sockfd = -1; return 1; } blocknr = buf[GCF_BLOCK_LEN+34]*256 + buf[GCF_BLOCK_LEN+35]; break; case 40: if (complete_read(sockfd, (char *) buf + SCREAM_INITIAL_LEN, SCREAM_V40_SUBSEQUENT) != SCREAM_V40_SUBSEQUENT) { printf("read failed: %m\n"); close(sockfd); sockfd = -1; return 1; } blocknr = buf[GCF_BLOCK_LEN+2]*256 + buf[GCF_BLOCK_LEN+3]; break; case 45: if (complete_read(sockfd, (char *) buf + SCREAM_INITIAL_LEN, SCREAM_V45_SUBSEQUENT) != SCREAM_V45_SUBSEQUENT) { printf("read failed: %m\n"); close(sockfd); sockfd = -1; return 1; } blocknr = buf[GCF_BLOCK_LEN+2]*256 + buf[GCF_BLOCK_LEN+3]; break; default: fatal (("Unknown version of scream protocol at remote end")); break; } if(DEBUG==1) printf("Got TCP blocknr = %d\n", blocknr); *thisblocknr = blocknr; break; } return 0; }