* read_cdda_data() needs to know the last frame of the track, so that it can

cut down the buffer size on the last request. This fixes bug #2565.
* cdda_read() did report an incorrect number of bytes read. This fixes bug
  #2511, and also that you couldn't copy tracks via "cp".
* cdda_read_stat() did not include the WAV header in its reported size.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26853 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-08-07 07:29:29 +00:00
parent 72ebbe4244
commit a89962b923
3 changed files with 17 additions and 14 deletions
@@ -602,7 +602,7 @@ read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length)
status_t
read_cdda_data(int fd, off_t offset, void *data, size_t length,
read_cdda_data(int fd, off_t endFrame, off_t offset, void *data, size_t length,
off_t bufferOffset, void *buffer, size_t bufferSize)
{
if (bufferOffset >= 0 && bufferOffset <= offset + length
@@ -627,12 +627,14 @@ read_cdda_data(int fd, off_t offset, void *data, size_t length,
length -= bytes;
}
// we don't handle the case we would need to split the request
// we don't handle the case where we would need to split the request
}
while (length > 0) {
off_t frame = offset / kFrameSize;
uint32 count = bufferSize / kFrameSize;
if (frame + count > endFrame)
count = endFrame - frame;
status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
if (status < B_OK)
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2007, Axel Dörfler, [email protected].
* Copyright 2007-2008, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef CDDA_H
@@ -30,7 +30,7 @@ struct cdtext {
status_t read_cdtext(int fd, cdtext &text);
status_t read_table_of_contents(int fd, scsi_toc_toc *toc, size_t length);
status_t read_cdda_data(int fd, off_t offset, void *data, size_t length,
off_t bufferOffset, void *buffer, size_t bufferSize);
status_t read_cdda_data(int fd, off_t endFrame, off_t offset, void *data,
size_t length, off_t bufferOffset, void *buffer, size_t bufferSize);
#endif // CDDA_H
@@ -388,7 +388,6 @@ read_attributes(int fd, Inode *inode)
return false;
count = B_BENDIAN_TO_HOST_INT32(count);
dprintf("inode %s read %lu attrs\n", inode->Name(), count);
if (count > kMaxAttributes)
return false;
@@ -405,7 +404,6 @@ dprintf("inode %s read %lu attrs\n", inode->Name(), count);
type = B_BENDIAN_TO_HOST_INT32(type);
size = B_BENDIAN_TO_HOST_INT32(size);
name[length] = '\0';
dprintf(" type %08lx, size %lu, name %s\n", type, size, name);
Attribute *attribute = new Attribute(name, type);
if (attribute->SetSize(size) != B_OK
@@ -431,7 +429,7 @@ fill_stat_buffer(Volume *volume, Inode *inode, Attribute *attribute,
stat.st_mode = S_ATTR | 0666;
stat.st_type = attribute->Type();
} else {
stat.st_size = inode->Size();
stat.st_size = inode->Size() + sizeof(wav_header);
stat.st_mode = inode->Type();
stat.st_type = 0;
}
@@ -782,7 +780,6 @@ Volume::_OpenAttributes(int mode, enum attr_mode attrMode)
} else
strlcat(path, "/shared", B_PATH_NAME_LENGTH);
dprintf("PATH: %s\n", path);
int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644);
free(path);
@@ -807,7 +804,6 @@ Volume::_RestoreAttributes()
return;
}
dprintf("VOLUME %s\n", line);
SetName(line);
for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) {
@@ -815,7 +811,6 @@ dprintf("VOLUME %s\n", line);
break;
inode->SetName(line);
dprintf("INODE %s\n", line);
}
if (read_attributes(fd, fRootNode)) {
@@ -1546,17 +1541,20 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset,
length = maxSize - offset;
status_t status = B_OK;
size_t bytesRead = 0;
if (offset < sizeof(wav_header)) {
// read fake WAV header
size_t size = sizeof(wav_header) - offset;
size = min_c(size, length);
if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size) < B_OK)
if (user_memcpy(buffer, (uint8 *)inode->WAVHeader() + offset, size)
< B_OK)
return B_BAD_ADDRESS;
buffer = (void *)((uint8 *)buffer + size);
length -= size;
bytesRead += size;
offset = 0;
} else
offset -= sizeof(wav_header);
@@ -1565,11 +1563,14 @@ cdda_read(fs_volume *_volume, fs_vnode *_node, void *_cookie, off_t offset,
// read actual CD data
offset += inode->StartFrame() * kFrameSize;
status = read_cdda_data(volume->Device(), offset, buffer, length,
status = read_cdda_data(volume->Device(),
inode->StartFrame() + inode->FrameCount(), offset, buffer, length,
cookie->buffer_offset, cookie->buffer, volume->BufferSize());
bytesRead += length;
}
if (status == B_OK)
*_length = length;
*_length = bytesRead;
return status;
}