* 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 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) off_t bufferOffset, void *buffer, size_t bufferSize)
{ {
if (bufferOffset >= 0 && bufferOffset <= offset + length 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; 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) { while (length > 0) {
off_t frame = offset / kFrameSize; off_t frame = offset / kFrameSize;
uint32 count = bufferSize / kFrameSize; uint32 count = bufferSize / kFrameSize;
if (frame + count > endFrame)
count = endFrame - frame;
status_t status = read_frames(fd, frame, (uint8 *)buffer, count); status_t status = read_frames(fd, frame, (uint8 *)buffer, count);
if (status < B_OK) 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. * Distributed under the terms of the MIT License.
*/ */
#ifndef CDDA_H #ifndef CDDA_H
@@ -30,7 +30,7 @@ struct cdtext {
status_t read_cdtext(int fd, cdtext &text); 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_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, status_t read_cdda_data(int fd, off_t endFrame, off_t offset, void *data,
off_t bufferOffset, void *buffer, size_t bufferSize); size_t length, off_t bufferOffset, void *buffer, size_t bufferSize);
#endif // CDDA_H #endif // CDDA_H
@@ -388,7 +388,6 @@ read_attributes(int fd, Inode *inode)
return false; return false;
count = B_BENDIAN_TO_HOST_INT32(count); count = B_BENDIAN_TO_HOST_INT32(count);
dprintf("inode %s read %lu attrs\n", inode->Name(), count);
if (count > kMaxAttributes) if (count > kMaxAttributes)
return false; return false;
@@ -405,7 +404,6 @@ dprintf("inode %s read %lu attrs\n", inode->Name(), count);
type = B_BENDIAN_TO_HOST_INT32(type); type = B_BENDIAN_TO_HOST_INT32(type);
size = B_BENDIAN_TO_HOST_INT32(size); size = B_BENDIAN_TO_HOST_INT32(size);
name[length] = '\0'; name[length] = '\0';
dprintf(" type %08lx, size %lu, name %s\n", type, size, name);
Attribute *attribute = new Attribute(name, type); Attribute *attribute = new Attribute(name, type);
if (attribute->SetSize(size) != B_OK 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_mode = S_ATTR | 0666;
stat.st_type = attribute->Type(); stat.st_type = attribute->Type();
} else { } else {
stat.st_size = inode->Size(); stat.st_size = inode->Size() + sizeof(wav_header);
stat.st_mode = inode->Type(); stat.st_mode = inode->Type();
stat.st_type = 0; stat.st_type = 0;
} }
@@ -782,7 +780,6 @@ Volume::_OpenAttributes(int mode, enum attr_mode attrMode)
} else } else
strlcat(path, "/shared", B_PATH_NAME_LENGTH); strlcat(path, "/shared", B_PATH_NAME_LENGTH);
dprintf("PATH: %s\n", path);
int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644); int fd = open(path, mode | (create ? O_CREAT | O_TRUNC : 0), 0644);
free(path); free(path);
@@ -807,7 +804,6 @@ Volume::_RestoreAttributes()
return; return;
} }
dprintf("VOLUME %s\n", line);
SetName(line); SetName(line);
for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) { for (Inode *inode = fFirstEntry; inode != NULL; inode = inode->Next()) {
@@ -815,7 +811,6 @@ dprintf("VOLUME %s\n", line);
break; break;
inode->SetName(line); inode->SetName(line);
dprintf("INODE %s\n", line);
} }
if (read_attributes(fd, fRootNode)) { 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; length = maxSize - offset;
status_t status = B_OK; status_t status = B_OK;
size_t bytesRead = 0;
if (offset < sizeof(wav_header)) { if (offset < sizeof(wav_header)) {
// read fake WAV header // read fake WAV header
size_t size = sizeof(wav_header) - offset; size_t size = sizeof(wav_header) - offset;
size = min_c(size, length); 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; return B_BAD_ADDRESS;
buffer = (void *)((uint8 *)buffer + size); buffer = (void *)((uint8 *)buffer + size);
length -= size; length -= size;
bytesRead += size;
offset = 0; offset = 0;
} else } else
offset -= sizeof(wav_header); 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 // read actual CD data
offset += inode->StartFrame() * kFrameSize; 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()); cookie->buffer_offset, cookie->buffer, volume->BufferSize());
bytesRead += length;
} }
if (status == B_OK) if (status == B_OK)
*_length = length; *_length = bytesRead;
return status; return status;
} }