Logo Search packages:      
Sourcecode: libgphoto2 version File versions

int gp_file_copy ( CameraFile destination,
CameraFile source 
)

Parameters:
destination a CameraFile
source a CameraFile
Returns:
a gphoto2 error code.

Definition at line 659 of file gphoto2-file.c.

References CHECK_NULL, GP_ERROR, GP_ERROR_IO, GP_ERROR_IO_READ, GP_ERROR_IO_WRITE, GP_ERROR_NO_MEMORY, GP_FILE_ACCESSTYPE_FD, GP_FILE_ACCESSTYPE_MEMORY, gp_log(), GP_LOG_DEBUG, GP_LOG_ERROR, and GP_OK.

{
      CHECK_NULL (destination && source);

      gp_log (GP_LOG_DEBUG, "gphoto2-file", "Copying '%s' onto '%s'...",
            source->name, destination->name);

      /* struct members we can just copy. All generic ones, but not refcount. */
      memcpy (destination->name, source->name, sizeof (source->name));
      memcpy (destination->mime_type, source->mime_type, sizeof (source->mime_type));
      destination->type = source->type;
      destination->mtime = source->mtime;

      if ((destination->accesstype == GP_FILE_ACCESSTYPE_MEMORY) &&
          (source->accesstype == GP_FILE_ACCESSTYPE_MEMORY)) {
            if (destination->data) {
                  free (destination->data);
                  destination->data = NULL;
            }
            destination->size = source->size;
            destination->data = malloc (sizeof (char) * source->size);
            if (!destination->data)
                  return (GP_ERROR_NO_MEMORY);
            memcpy (destination->data, source->data, source->size);
            return (GP_OK);
      }
      if (  (destination->accesstype == GP_FILE_ACCESSTYPE_MEMORY) &&
            (source->accesstype == GP_FILE_ACCESSTYPE_FD)
      ) {
            off_t offset;
            unsigned long int curread = 0;

            if (destination->data) {
                  free (destination->data);
                  destination->data = NULL;
            }
            if (-1 == lseek (source->fd, 0, SEEK_END)) {
                  if (errno == EBADF) return GP_ERROR_IO;
                  /* Might happen for pipes or sockets. Umm. Hard. */
                  /* FIXME */
            }
            if (-1 == (offset = lseek (source->fd, 0, SEEK_CUR))) {
                  /* should not happen if we passed the above case */
                  gp_log (GP_LOG_ERROR, "gphoto2-file", "Encountered error %d lseekin to CUR.", errno);
                  return GP_ERROR_IO_READ;
            }
            if (-1 == lseek (source->fd, 0, SEEK_SET)) {
                  /* should not happen if we passed the above cases */
                  gp_log (GP_LOG_ERROR, "gphoto2-file", "Encountered error %d lseekin to CUR.", errno);
                  return GP_ERROR_IO_READ;
            }
            destination->size = offset;
            destination->data = malloc (offset);
            if (!destination->data)
                  return GP_ERROR_NO_MEMORY;
            while (curread < offset) {
                  unsigned int res = read (source->fd, destination->data+curread, offset-curread);
                  if (res == -1) {
                        free (destination->data);
                        gp_log (GP_LOG_ERROR, "gphoto2-file", "Encountered error %d reading.", errno);
                        return GP_ERROR_IO_READ;
                  }
                  if (res == 0) {
                        free (destination->data);
                        gp_log (GP_LOG_ERROR, "gphoto2-file", "No progress during reading.");
                        return GP_ERROR_IO_READ;
                  }
                  curread += res;
            }
            return GP_OK;
      }
      if (  (destination->accesstype == GP_FILE_ACCESSTYPE_FD) &&
            (source->accesstype == GP_FILE_ACCESSTYPE_FD)
      ) {
            char *data;

            lseek (destination->fd, 0, SEEK_SET);
            ftruncate (destination->fd, 0);
            lseek (source->fd, 0, SEEK_SET);
            data = malloc (65536);
            while (1) {
                  unsigned long curwritten = 0;
                  int res;

                  res = read (source->fd, data, 65536);
                  if (res == -1) {
                        free (data);
                        return GP_ERROR_IO_READ;
                  }
                  if (res == 0)
                        break;
                  while (curwritten < res) {
                        int res2 = write (destination->fd, data+curwritten, res-curwritten);
                        if (res2 == -1) {
                              free (data);
                              return GP_ERROR_IO_WRITE;
                        }
                        if (res2 == 0)
                              break;
                        curwritten += res2;
                  }
                  if (res < 65536) /* end of file */
                        break;
            }
            return GP_OK;
      }
      if (  (destination->accesstype == GP_FILE_ACCESSTYPE_FD) &&
            (source->accesstype == GP_FILE_ACCESSTYPE_MEMORY)
      ) {
            unsigned long curwritten = 0;
            while (curwritten < source->size) {
                  int res = write (destination->fd, source->data+curwritten, source->size-curwritten);

                  if (res == -1)
                        return GP_ERROR_IO_WRITE;
                  if (!res) /* no progress? */
                        return GP_ERROR_IO_WRITE;
                  curwritten += res;
            }
            return GP_OK;
      }
      gp_log (GP_LOG_ERROR, "gphoto2-file", "Unhandled cases in gp_copy_file. Bad!");
      return GP_ERROR;
}


Generated by  Doxygen 1.6.0   Back to index