static void file_open_test (const char *filename) { SF_PRIVATE sf_data, *psf ; int error ; printf (" %-24s : ", "file_open_test") ; fflush (stdout) ; memset (&sf_data, 0, sizeof (sf_data)) ; psf = &sf_data ; /* Ensure that the file doesn't already exist. */ if (unlink (filename) != 0 && errno != ENOENT) { printf ("\n\nLine %d: unlink failed (%d) : %s\n\n", __LINE__, errno, strerror (errno)) ; exit (1) ; } ; strncpy (psf->filename, filename, sizeof (psf->filename)) ; /* Test that open for read fails if the file doesn't exist. */ error = psf_fopen (psf, psf->filename, SFM_READ) ; if (error == 0) { printf ("\n\nLine %d: psf_fopen() should have failed.\n\n", __LINE__) ; exit (1) ; } ; /* Reset error to zero. */ psf->error = SFE_NO_ERROR ; /* Test file open in write mode. */ psf->mode = SFM_WRITE ; test_open_or_die (psf, __LINE__) ; test_close_or_die (psf, __LINE__) ; unlink (psf->filename) ; /* Test file open in read/write mode for a non-existant file. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; test_close_or_die (psf, __LINE__) ; /* Test file open in read/write mode for an existing file. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; test_close_or_die (psf, __LINE__) ; unlink (psf->filename) ; puts ("ok") ; } /* file_open_test */
static void file_seek_with_offset_test (const char *filename) { SF_PRIVATE sf_data, *psf ; sf_count_t real_end ; const size_t fileoffset = 64 ; print_test_name ("Testing seek with offset") ; /* Open the file created by the previous test for reading. */ memset (&sf_data, 0, sizeof (sf_data)) ; psf = &sf_data ; psf->file.mode = SFM_READ ; snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ; test_open_or_die (psf, __LINE__) ; /* Gather basic info before setting offset. */ real_end = psf_fseek (psf, 0, SEEK_END) ; test_tell_or_die (psf, real_end, __LINE__) ; /* Set the fileoffset (usually in a real system this is due to an id3 tag). */ psf->fileoffset = fileoffset ; /* Check tell respects offset. */ test_tell_or_die (psf, real_end - fileoffset, __LINE__) ; /* Check seeking works as expected. */ test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, real_end - fileoffset, __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_seek_with_offset_test */
static void file_truncate_test (const char *filename) { SF_PRIVATE sf_data, *psf ; unsigned char buffer [256] ; int k ; /* ** Open a new file and write two blocks of data to the file. After each ** write, test that psf_get_filelen() returns the new length. */ printf (" %-24s : ", "file_truncate_test") ; fflush (stdout) ; memset (&sf_data, 0, sizeof (sf_data)) ; memset (buffer, 0xEE, sizeof (buffer)) ; psf = &sf_data ; strncpy (psf->filename, filename, sizeof (psf->filename)) ; /* ** Open the file write mode, write 0xEE data and then extend the file ** using truncate (the extended data should be 0x00). */ psf->mode = SFM_WRITE ; test_open_or_die (psf, __LINE__) ; test_write_or_die (psf, buffer, sizeof (buffer) / 2, 1, sizeof (buffer) / 2, __LINE__) ; psf_ftruncate (psf, sizeof (buffer)) ; test_close_or_die (psf, __LINE__) ; /* Open the file in read mode and check the data. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; test_read_or_die (psf, buffer, sizeof (buffer), 1, sizeof (buffer), __LINE__) ; test_close_or_die (psf, __LINE__) ; for (k = 0 ; k < SIGNED_SIZEOF (buffer) / 2 ; k++) if (buffer [k] != 0xEE) { printf ("\n\nLine %d : buffer [%d] = %d (should be 0xEE)\n\n", __LINE__, k, buffer [k]) ; exit (1) ; } ; for (k = SIGNED_SIZEOF (buffer) / 2 ; k < SIGNED_SIZEOF (buffer) ; k++) if (buffer [k] != 0) { printf ("\n\nLine %d : buffer [%d] = %d (should be 0)\n\n", __LINE__, k, buffer [k]) ; exit (1) ; } ; /* Open the file in read/write and shorten the file using truncate. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; psf_ftruncate (psf, sizeof (buffer) / 4) ; test_close_or_die (psf, __LINE__) ; /* Check the file length. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, SIGNED_SIZEOF (buffer) / 4, __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_truncate_test */
static void file_read_write_test (const char *filename) { static int data_out [512] ; static int data_in [512] ; SF_PRIVATE sf_data, *psf ; sf_count_t retval ; /* ** Open a new file and write two blocks of data to the file. After each ** write, test that psf_get_filelen() returns the new length. */ printf (" %-24s : ", "file_write_test") ; fflush (stdout) ; memset (&sf_data, 0, sizeof (sf_data)) ; psf = &sf_data ; strncpy (psf->filename, filename, sizeof (psf->filename)) ; /* Test file open in write mode. */ psf->mode = SFM_WRITE ; test_open_or_die (psf, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), sizeof (data_out), __LINE__) ; if ((retval = psf_get_filelen (psf)) != sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct (%ld should be %d).\n\n", __LINE__, (long) retval, (int) sizeof (data_out)) ; if (retval == 0) printf ("An fsync() may be necessary before fstat() in psf_get_filelen().\n\n") ; exit (1) ; } ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_write_or_die (psf, data_out, ARRAY_LEN (data_out), sizeof (data_out [0]), 2 * sizeof (data_out), __LINE__) ; if ((retval = psf_get_filelen (psf)) != 2 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 2 * ((int) sizeof (data_out))) ; exit (1) ; } ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Now open the file in read mode, check the file length and check ** that the data is correct. */ printf (" %-24s : ", "file_read_test") ; fflush (stdout) ; /* Test file open in write mode. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, sizeof (data_in [0]), ARRAY_LEN (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Open the file in read/write mode, seek around a bit and then seek to ** the end of the file and write another block of data (3rd block). Then ** go back and check that all three blocks are correct. */ printf (" %-24s : ", "file_seek_test") ; fflush (stdout) ; /* Test file open in read/write mode. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; test_seek_or_die (psf, -1 * SIGNED_SIZEOF (data_out), SEEK_CUR, (sf_count_t) sizeof (data_out), __LINE__) ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_CUR, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 3) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 3 * sizeof (data_out), __LINE__) ; test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_seek_or_die (psf, 2 * SIGNED_SIZEOF (data_out), SEEK_SET, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 3) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Now test operations with a non-zero psf->fileoffset field. This field ** sets an artificial file start positions so that a seek to the start of ** the file will actually be a seek to the value given by psf->fileoffset. */ printf (" %-24s : ", "file_offset_test") ; fflush (stdout) ; /* Test file open in read/write mode. */ psf->mode = SFM_RDWR ; psf->fileoffset = sizeof (data_out [0]) * ARRAY_LEN (data_out) ; test_open_or_die (psf, __LINE__) ; if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ; exit (1) ; } ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 5) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 2 * sizeof (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; /* final test with psf->fileoffset == 0. */ psf->mode = SFM_RDWR ; psf->fileoffset = 0 ; test_open_or_die (psf, __LINE__) ; if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ; exit (1) ; } ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 5) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_read_write_test */