/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ /* * Copyright (C) 1997 University of Chicago. * See COPYRIGHT notice in top-level directory. */ #include "adio.h" #include "adio_extern.h" #ifdef HAVE_UNISTD_H #include #endif ADIO_Offset ADIOI_GEN_SeekIndividual(ADIO_File fd, ADIO_Offset offset, int whence, int *error_code) { /* implemented for whence=SEEK_SET only. SEEK_CUR and SEEK_END must be converted to the equivalent with SEEK_SET before calling this routine. */ /* offset is in units of etype relative to the filetype */ ADIO_Offset off; ADIOI_Flatlist_node *flat_file; int i; ADIO_Offset n_etypes_in_filetype, n_filetypes, etype_in_filetype; ADIO_Offset abs_off_in_filetype=0; ADIO_Offset size_in_filetype, sum; MPI_Count filetype_size, etype_size; int filetype_is_contig; MPI_Aint filetype_extent, lb; ADIOI_UNREFERENCED_ARG(whence); ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig); etype_size = fd->etype_size; if (filetype_is_contig) off = fd->disp + etype_size * offset; else { flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype) flat_file = flat_file->next; MPI_Type_get_extent(fd->filetype, &lb, &filetype_extent); MPI_Type_size_x(fd->filetype, &filetype_size); if ( ! filetype_size ) { /* Since offset relative to the filetype size, we can't do compute the offset when that result is zero. Return zero for the offset for now */ *error_code = MPI_SUCCESS; return 0; } n_etypes_in_filetype = filetype_size/etype_size; n_filetypes = offset / n_etypes_in_filetype; etype_in_filetype = offset % n_etypes_in_filetype; size_in_filetype = etype_in_filetype * etype_size; sum = 0; for (i=0; icount; i++) { sum += flat_file->blocklens[i]; if (sum > size_in_filetype) { abs_off_in_filetype = flat_file->indices[i] + size_in_filetype - (sum - flat_file->blocklens[i]); break; } } /* abs. offset in bytes in the file */ off = fd->disp + n_filetypes * filetype_extent + abs_off_in_filetype; } /* * we used to call lseek here and update both fp_ind and fp_sys_posn, but now * we don't seek and only update fp_ind (ROMIO's idea of where we are in the * file). We leave the system file descriptor and fp_sys_posn alone. * The fs-specifc ReadContig and WriteContig will seek to the correct place in * the file before reading/writing if the 'offset' parameter doesn't match * fp_sys_posn */ fd->fp_ind = off; *error_code = MPI_SUCCESS; return off; }