Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move serial cache from Canon to port library #856

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 3 additions & 21 deletions camlibs/canon/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,28 +218,10 @@ serial_set_timeout (GPPort *gdev, int to)
static int
canon_serial_get_byte (GPPort *gdev)
{
static unsigned char cache[512];
static unsigned char *cachep = cache;
static unsigned char *cachee = cache;
int recv;

/* if still data in cache, get it */
if (cachep < cachee) {
return (int) *cachep++;
}

recv = gp_port_read (gdev, (char *)cache, 1);
if (recv < 0) /* An error occurred */
char byte;
if (gp_port_read (gdev, (char *)&byte, 1) < 0)
return -1;

cachep = cache;
cachee = cache + recv;

if (recv) {
return (int) *cachep++;
}

return -1;
return byte;
}

/* ------------------------- Frame-level processing ------------------------- */
Expand Down
31 changes: 26 additions & 5 deletions libgphoto2_port/serial/unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@
struct _GPPortPrivateLibrary {
int fd; /* Device handle */
int baudrate; /* Current speed */

/* Internal cache for faster reading */
char cache[512];
const char *cachep;
const char *cachee;
};

static int gp_port_serial_check_speed (GPPort *dev);
Expand Down Expand Up @@ -512,7 +517,7 @@ gp_port_serial_read (GPPort *dev, char *bytes, int size)
FD_ZERO (&readfs);
FD_SET (dev->pl->fd, &readfs);

while (readen < size) {
while (size > 0) {

/* Set timeout value within input loop */
timeout.tv_usec = (dev->timeout % 1000) * 1000;
Expand Down Expand Up @@ -559,14 +564,30 @@ gp_port_serial_read (GPPort *dev, char *bytes, int size)
/* Ok, we read 1 byte and it is 0xff */
/* FALLTHROUGH */
}
} else if (dev->pl->cachep == dev->pl->cachee && size >= sizeof(dev->pl->cache)) {
/* We're trying to read a chunk larger than the cache and the cache is empty.
In this case, skip the cache entirely and read as much as we can directly into the destination. */
now = read (dev->pl->fd, bytes, size);
if (now < 0)
return GP_ERROR_IO_READ;
} else {
/* Just read the bytes */
now = read (dev->pl->fd, bytes, size - readen);
if (now < 0)
return GP_ERROR_IO_READ;
if (dev->pl->cachep == dev->pl->cachee) {
/* We're reading only a few bytes and the cache is empty; fill it up. */
now = read (dev->pl->fd, dev->pl->cache, sizeof(dev->pl->cache));
if (now < 0)
return GP_ERROR_IO_READ;
/* Reset cache pointers */
dev->pl->cachep = dev->pl->cache;
dev->pl->cachee = dev->pl->cache + now;
}
/* read up to the required chunk size from cache */
now = MIN(size, dev->pl->cachee - dev->pl->cachep);
memcpy(bytes, dev->pl->cachep, now);
dev->pl->cachep += now;
}
bytes += now;
readen += now;
size -= readen;
}

return readen;
Expand Down