1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2025-03-20 10:45:43 +00:00

(trunk, libT) #4160: apply mike.dld's patch: 4160-05a-file-fmt.patch

This commit is contained in:
Jordan Lee 2014-09-21 17:57:45 +00:00
parent d9d66e3e42
commit 90bbbaefc3
3 changed files with 177 additions and 0 deletions

View file

@ -30,6 +30,7 @@ libtransmission_a_SOURCES = \
crypto.c \
error.c \
fdlimit.c \
file.c \
handshake.c \
history.c \
inout.c \

View file

@ -1152,6 +1152,105 @@ test_file_map (void)
return 0;
}
static int
test_file_utilities (void)
{
char * const test_dir = create_test_dir (__FUNCTION__);
tr_error * err = NULL;
char * path1;
tr_sys_file_t fd;
char buffer[16];
path1 = tr_buildPath (test_dir, "a", NULL);
libtest_create_file_with_string_contents (path1, "a\nbc\r\ndef\nghij\r\n\n\nklmno\r");
fd = tr_sys_file_open (path1, TR_SYS_FILE_READ, 0, NULL);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("a", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("bc", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("def", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("ghij", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("", buffer);
check (tr_sys_file_read_line (fd, buffer, 4, &err));
check (err == NULL);
check_streq ("klmn", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("o", buffer);
check (!tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("o", buffer); /* on EOF, buffer stays unchanged */
tr_sys_file_close (fd, NULL);
fd = tr_sys_file_open (path1, TR_SYS_FILE_READ | TR_SYS_FILE_WRITE | TR_SYS_FILE_TRUNCATE, 0, NULL);
check (tr_sys_file_write_line (fd, "p", &err));
check (err == NULL);
check (tr_sys_file_write_line (fd, "", &err));
check (err == NULL);
check (tr_sys_file_write_line (fd, "qr", &err));
check (err == NULL);
check (tr_sys_file_write_fmt (fd, "s%cu\r\n", &err, 't'));
check (err == NULL);
check (tr_sys_file_write_line (fd, "", &err));
check (err == NULL);
check (tr_sys_file_write_line (fd, "", &err));
check (err == NULL);
check (tr_sys_file_write_fmt (fd, "v%sy%d", &err, "wx", 2));
check (err == NULL);
tr_sys_file_seek (fd, 0, TR_SEEK_SET, NULL, NULL);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("p", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("qr", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("stu", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("", buffer);
check (tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("vwxy2", buffer);
check (!tr_sys_file_read_line (fd, buffer, sizeof (buffer) / sizeof (*buffer), &err));
check (err == NULL);
check_streq ("vwxy2", buffer); /* on EOF, buffer stays unchanged */
tr_sys_file_close (fd, NULL);
tr_sys_path_remove (path1, NULL);
tr_free (path1);
tr_free (test_dir);
return 0;
}
static int
test_dir_create (void)
{
@ -1309,6 +1408,7 @@ main (void)
test_file_truncate,
test_file_preallocate,
test_file_map,
test_file_utilities,
test_dir_create,
test_dir_read
};

View file

@ -35,10 +35,16 @@ extern "C" {
#define TR_BAD_SYS_FILE (-1)
/** @brief Platform-specific directory descriptor type. */
typedef void * tr_sys_dir_t;
/** @brief Platform-specific end-of-line sequence. */
#define TR_NATIVE_EOL_STR "\n"
/** @brief Platform-specific end-of-line sequence length. */
#define TR_NATIVE_EOL_STR_SIZE 1
#else
typedef HANDLE tr_sys_file_t;
#define TR_BAD_SYS_FILE INVALID_HANDLE_VALUE
typedef struct tr_sys_dir_win32 * tr_sys_dir_t;
#define TR_NATIVE_EOL_STR "\r\n"
#define TR_NATIVE_EOL_STR_SIZE 2
#endif
/** @brief Platform-specific invalid directory descriptor constant. */
@ -509,6 +515,76 @@ bool tr_sys_file_unmap (const void * address,
uint64_t size,
tr_error ** error);
/* File-related wrappers (utility) */
/**
* @brief Portability wrapper for `fgets ()`, removing EOL internally.
*
* Special care should be taken when reading from one of standard input streams
* (@ref tr_std_sys_file_t) since no UTF-8 conversion is currently being made.
*
* Reading from other streams (files, pipes) also leaves data untouched, so it
* should already be in UTF-8 encoding, or whichever else you expect.
*
* @param[in] handle Valid file descriptor.
* @param[out] buffer Buffer to store read zero-terminated string to.
* @param[in] buffer_size Buffer size in bytes, taking '\0' character into
* account.
* @param[out] error Pointer to error object. Optional, pass `NULL` if you
* are not interested in error details.
*
* @return `True` on success, `false` otherwise (with `error` set accordingly).
* Note that `false` will also be returned in case of end of file; if
* you need to distinguish the two, check if `error` is `NULL`
* afterwards.
*/
bool tr_sys_file_read_line (tr_sys_file_t handle,
char * buffer,
size_t buffer_size,
tr_error ** error);
/**
* @brief Portability wrapper for `fputs ()`, appending EOL internally.
*
* Special care should be taken when writing to one of standard output streams
* (@ref tr_std_sys_file_t) since no UTF-8 conversion is currently being made.
*
* Writing to other streams (files, pipes) also leaves data untouched, so it
* should already be in UTF-8 encoding, or whichever else you expect.
*
* @param[in] handle Valid file descriptor.
* @param[in] buffer Zero-terminated string to write.
* @param[out] error Pointer to error object. Optional, pass `NULL` if you are
* not interested in error details.
*
* @return `True` on success, `false` otherwise (with `error` set accordingly).
*/
bool tr_sys_file_write_line (tr_sys_file_t handle,
const char * buffer,
tr_error ** error);
/**
* @brief Portability wrapper for `fprintf ()`.
*
* Special care should be taken when writing to one of standard output streams
* (@ref tr_std_sys_file_t) since no UTF-8 conversion is currently being made.
*
* Writing to other streams (files, pipes) also leaves data untouched, so it
* should already be in UTF-8 encoding, or whichever else you expect.
*
* @param[in] handle Valid file descriptor.
* @param[in] format String format to write.
* @param[out] error Pointer to error object. Optional, pass `NULL` if you are
* not interested in error details.
* @param[in] ... Format arguments.
*
* @return `True` on success, `false` otherwise (with `error` set accordingly).
*/
bool tr_sys_file_write_fmt (tr_sys_file_t handle,
const char * format,
tr_error ** error,
...);
/* Directory-related wrappers */
/**