summaryrefslogtreecommitdiff
path: root/apps/buffering.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/buffering.c')
-rw-r--r--apps/buffering.c85
1 files changed, 41 insertions, 44 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index 18f3ba6900..5fd8c24122 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -970,51 +970,70 @@ int bufadvance(int handle_id, off_t offset)
970 return bufseek(handle_id, newpos); 970 return bufseek(handle_id, newpos);
971} 971}
972 972
973/* Copy data from the given handle to the dest buffer. 973/* Used by bufread and bufgetdata to prepare the buffer and retrieve the
974 Return the number of bytes copied or < 0 for failure (handle not found). 974 * actual amount of data available for reading. This function explicitly
975 The caller is blocked until the requested amount of data is available. 975 * does not check the validity of the input handle. It does do range checks
976*/ 976 * on size and returns a valid (and explicit) amount of data for reading */
977ssize_t bufread(int handle_id, size_t size, void *dest) 977static size_t prep_bufdata(const struct memory_handle *h, size_t size)
978{ 978{
979 const struct memory_handle *h = find_handle(handle_id);
980 if (!h)
981 return ERR_HANDLE_NOT_FOUND;
982
983 size_t ret;
984 size_t avail = RINGBUF_SUB(h->widx, h->ridx); 979 size_t avail = RINGBUF_SUB(h->widx, h->ridx);
985 980
986 if (avail == 0 && h->filerem == 0) 981 if (avail == 0 && h->filerem == 0)
987 /* File is finished reading */ 982 /* File is finished reading */
988 return 0; 983 return 0;
989 984
990 if (h->filerem > 0 && (avail == 0 || avail < size)) 985 if (size == 0 || size > h->available + h->filerem)
986 size = h->available + h->filerem;
987
988 if (h->type == TYPE_PACKET_AUDIO && size > BUFFERING_DEFAULT_FILECHUNK)
989 {
990 /* If more than a filechunk is requested, log it and provide no more
991 * than the amount of data on buffer or one file chunk */
992 logf("data request > filechunk");
993 size = MAX(avail,BUFFERING_DEFAULT_FILECHUNK);
994 }
995
996 if (h->filerem > 0 && avail < size)
991 { 997 {
992 /* Data isn't ready. Request buffering */ 998 /* Data isn't ready. Request buffering */
993 buf_request_buffer_handle(handle_id); 999 buf_request_buffer_handle(h->id);
994 /* Wait for the data to be ready */ 1000 /* Wait for the data to be ready */
995 do 1001 do
996 { 1002 {
997 sleep(1); 1003 sleep(1);
998 avail = RINGBUF_SUB(h->widx, h->ridx); 1004 avail = RINGBUF_SUB(h->widx, h->ridx);
999 } 1005 }
1000 while (h->filerem > 0 && (avail == 0 || avail < size)); 1006 while (h->filerem > 0 && avail < size);
1001 } 1007 }
1002 1008
1003 ret = MIN(size, avail); 1009 return MIN(size,avail);
1010}
1004 1011
1005 if (h->ridx + ret > buffer_len) 1012/* Copy data from the given handle to the dest buffer.
1013 Return the number of bytes copied or < 0 for failure (handle not found).
1014 The caller is blocked until the requested amount of data is available.
1015*/
1016ssize_t bufread(int handle_id, size_t size, void *dest)
1017{
1018 const struct memory_handle *h = find_handle(handle_id);
1019 if (!h)
1020 return ERR_HANDLE_NOT_FOUND;
1021
1022 size = prep_bufdata(h, size);
1023
1024 if (h->ridx + size > buffer_len)
1006 { 1025 {
1007 /* the data wraps around the end of the buffer */ 1026 /* the data wraps around the end of the buffer */
1008 size_t read = buffer_len - h->ridx; 1027 size_t read = buffer_len - h->ridx;
1009 memcpy(dest, &buffer[h->ridx], read); 1028 memcpy(dest, &buffer[h->ridx], read);
1010 memcpy(dest+read, buffer, ret - read); 1029 memcpy(dest+read, buffer, size - read);
1011 } 1030 }
1012 else 1031 else
1013 { 1032 {
1014 memcpy(dest, &buffer[h->ridx], ret); 1033 memcpy(dest, &buffer[h->ridx], size);
1015 } 1034 }
1016 1035
1017 return ret; 1036 return size;
1018} 1037}
1019 1038
1020/* Update the "data" pointer to make the handle's data available to the caller. 1039/* Update the "data" pointer to make the handle's data available to the caller.
@@ -1032,41 +1051,19 @@ ssize_t bufgetdata(int handle_id, size_t size, void **data)
1032 if (!h) 1051 if (!h)
1033 return ERR_HANDLE_NOT_FOUND; 1052 return ERR_HANDLE_NOT_FOUND;
1034 1053
1035 ssize_t ret; 1054 size = prep_bufdata(h, size);
1036 size_t avail = RINGBUF_SUB(h->widx, h->ridx);
1037 1055
1038 if (avail == 0 && h->filerem == 0) 1056 if (h->ridx + size > buffer_len)
1039 /* File is finished reading */
1040 return 0;
1041
1042 if (h->filerem > 0 && (avail == 0 || avail < size))
1043 {
1044 /* Data isn't ready. Request buffering */
1045 buf_request_buffer_handle(handle_id);
1046 /* Wait for the data to be ready */
1047 do
1048 {
1049 sleep(1);
1050 avail = RINGBUF_SUB(h->widx, h->ridx);
1051 }
1052 while (h->filerem > 0 && (avail == 0 || avail < size));
1053 }
1054
1055 if (h->ridx + size > buffer_len && avail >= size)
1056 { 1057 {
1057 /* the data wraps around the end of the buffer : 1058 /* the data wraps around the end of the buffer :
1058 use the guard buffer to provide the requested amount of data. */ 1059 use the guard buffer to provide the requested amount of data. */
1059 size_t copy_n = MIN(h->ridx + size - buffer_len, GUARD_BUFSIZE); 1060 size_t copy_n = MIN(h->ridx + size - buffer_len, GUARD_BUFSIZE);
1060 memcpy(guard_buffer, (unsigned char *)buffer, copy_n); 1061 memcpy(guard_buffer, (unsigned char *)buffer, copy_n);
1061 ret = buffer_len - h->ridx + copy_n; 1062 size = buffer_len - h->ridx + copy_n;
1062 }
1063 else
1064 {
1065 ret = MIN(avail, buffer_len - h->ridx);
1066 } 1063 }
1067 1064
1068 *data = &buffer[h->ridx]; 1065 *data = &buffer[h->ridx];
1069 return ret; 1066 return size;
1070} 1067}
1071 1068
1072/* 1069/*