/* * cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, * unsigned long len) * Scope: PUBLIC * Description * Read incoming file data off the network into a buffer of length len. * * Return Value: * Sucess: number of bytes read into buf * Failure: -1 */ int cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) { cmyth_file_t file; int rc; cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) {\n", __FUNCTION__, __FILE__, __LINE__); if (!rec || !rec->rec_connected) { return -EINVAL; } if ((file=cmyth_livetv_current_file(rec)) == NULL) { return -1; } rc = cmyth_file_get_block(file, buf, len); ref_release(file); cmyth_dbg(CMYTH_DBG_DEBUG, "%s [%s:%d]: (trace) }\n", __FUNCTION__, __FILE__, __LINE__); return rc; }
static int fill_buffer(int i, char *buf, size_t size) { int tot, len, n = 0; tot = 0; len = cmyth_file_request_block(files[i].file, size); while (tot < len) { n = cmyth_file_get_block(files[i].file, buf+tot, len-tot); if (n > 0) { tot += n; } if (n <= 0) { return -1; } } debug("%s(): tot %d len %d n %d size %lld\n", __FUNCTION__, tot, len, n, (long long)size); if (len < 0) { return -1; } return tot; }
/* * cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, * unsigned long len) * Scope: PUBLIC * Description * Read incoming file data off the network into a buffer of length len. * * Return Value: * Sucess: number of bytes read into buf * Failure: -1 */ int cmyth_livetv_chain_get_block(cmyth_recorder_t rec, char *buf, unsigned long len) { if (!rec) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: no connection\n", __FUNCTION__); return -EINVAL; } return cmyth_file_get_block(rec->rec_livetv_file, buf, len); }
/* * cmyth_file_seek() * * Scope: PUBLIC * * Description * * Seek to a new position in the file based on the value of whence: * WHENCE_SET * The offset is set to offset bytes. * WHENCE_CUR * The offset is set to the current position plus offset bytes. * WHENCE_END * The offset is set to the size of the file minus offset bytes. * * Return Value: * * Sucess: 0 * * Failure: an int containing -errno */ int64_t cmyth_file_seek(cmyth_file_t file, int64_t offset, int8_t whence) { char msg[128]; int err; int count; int64_t c; int r; int64_t ret; if (file == NULL) return -EINVAL; if ((offset == 0) && (whence == WHENCE_CUR)) return file->file_pos; if ((offset == file->file_pos) && (whence == WHENCE_SET)) return file->file_pos; pthread_mutex_lock(&mutex); ret = 0; while(file->file_pos < file->file_req) { c = file->file_req - file->file_pos; if(c > sizeof(msg)) c = sizeof(msg); if ((ret = cmyth_file_get_block(file, msg, (size_t)c)) < 0) break; } if (ret < 0) goto out; if (file->file_control->conn_version >= 66) { /* * Since protocol 66 mythbackend expects to receive a single 64 bit integer rather than * two 32 bit hi and lo integers. */ snprintf(msg, sizeof(msg), "QUERY_FILETRANSFER %"PRIu32"[]:[]SEEK[]:[]%"PRId64"[]:[]%"PRId8"[]:[]%"PRId64, file->file_id, offset, whence, file->file_pos); } else { snprintf(msg, sizeof(msg), "QUERY_FILETRANSFER %"PRIu32"[]:[]SEEK[]:[]%"PRId32"[]:[]%"PRId32"[]:[]%"PRId8"[]:[]%"PRId32"[]:[]%"PRId32, file->file_id, (int32_t)(offset >> 32), (int32_t)(offset & 0xffffffff), whence, (int32_t)(file->file_pos >> 32), (int32_t)(file->file_pos & 0xffffffff)); } if ((err = cmyth_send_message(file->file_control, msg)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message() failed (%d)\n", __FUNCTION__, err); ret = err; goto out; } if ((count=cmyth_rcv_length(file->file_control)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_length() failed (%d)\n", __FUNCTION__, count); ret = count; goto out; } if ((r=cmyth_rcv_int64(file->file_control, &err, &c, count)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_int64() failed (%d)\n", __FUNCTION__, r); ret = err; goto out; } file->file_pos = c; file->file_req = file->file_pos; if(file->file_pos > file->file_length) file->file_length = file->file_pos; ret = file->file_pos; out: pthread_mutex_unlock(&mutex); return ret; }
/* * cmyth_file_seek(cmyth_file_t file, long long offset, int whence) * * Scope: PUBLIC * * Description * * Seek to a new position in the file based on the value of whence: * SEEK_SET * The offset is set to offset bytes. * SEEK_CUR * The offset is set to the current position plus offset bytes. * SEEK_END * The offset is set to the size of the file minus offset bytes. * * Return Value: * * Sucess: 0 * * Failure: an int containing -errno */ long long cmyth_file_seek(cmyth_file_t file, long long offset, int whence) { char msg[128]; int err; int count; int64_t c; long r; long long ret; if (file == NULL) return -EINVAL; if ((offset == 0) && (whence == SEEK_CUR)) return file->file_pos; if ((offset == file->file_pos) && (whence == SEEK_SET)) return file->file_pos; while(file->file_pos < file->file_req) { c = file->file_req - file->file_pos; if(c > sizeof(msg)) c = sizeof(msg); if (cmyth_file_get_block(file, msg, (unsigned long)c) < 0) return -1; } pthread_mutex_lock(&mutex); if (file->file_control->conn_version >= 66) { /* * Since protocol 66 mythbackend expects to receive a single 64 bit integer rather than * two 32 bit hi and lo integers. */ snprintf(msg, sizeof(msg), "QUERY_FILETRANSFER %ld[]:[]SEEK[]:[]%"PRIu64"[]:[]%d[]:[]%"PRIu64, file->file_id, (int64_t)offset, whence, (int64_t)file->file_pos); } else { snprintf(msg, sizeof(msg), "QUERY_FILETRANSFER %ld[]:[]SEEK[]:[]%d[]:[]%d[]:[]%d[]:[]%d[]:[]%d", file->file_id, (int32_t)(offset >> 32), (int32_t)(offset & 0xffffffff), whence, (int32_t)(file->file_pos >> 32), (int32_t)(file->file_pos & 0xffffffff)); } if ((err = cmyth_send_message(file->file_control, msg)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message() failed (%d)\n", __FUNCTION__, err); ret = err; goto out; } if ((count=cmyth_rcv_length(file->file_control)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_length() failed (%d)\n", __FUNCTION__, count); ret = count; goto out; } if ((r=cmyth_rcv_int64(file->file_control, &err, &c, count)) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_int64() failed (%d)\n", __FUNCTION__, r); ret = err; goto out; } switch (whence) { case SEEK_SET: file->file_pos = offset; break; case SEEK_CUR: file->file_pos += offset; break; case SEEK_END: file->file_pos = file->file_length - offset; break; } file->file_req = file->file_pos; if(file->file_pos > file->file_length) file->file_length = file->file_pos; ret = file->file_pos; out: pthread_mutex_unlock(&mutex); return ret; }