📄 diskread.c
字号:
ervar.param = (fd[channel].ch_type==2) ? next : (fd[channel].next-1) / fd[channel].format[2*fd[channel].v+1] + 1 + block_num; if (auto_er) error_exit(-30); return(-30); } p = block_num * fd[channel].byte_p_blk; lseek(fd[channel].fd, p, 1); } fd[channel].next = next; return(next);}/* ------------------------ READ BLOCK ROUTINE -------------------------- *//* DESCRIPTION: position = read_block ( chan_id, val_pntr ) This routine returns one block of values from the file connected tochannel "chan_id". "val_pntr" is an array of pointers having one element foreach block variable. The calling routine sets each pointer in the array tospecify where the values for each block variable are to go. Thus, val_pntr[0]is the address where the first value of the first block variable will be stored;val_pntr[1] is the address where the first value of the second block variablewill be stored; etc. Subsequent values of the variables are stored insequential locations following the address of the first value.Returned value: If there are no errors, the returned value indicates the current fileposition (the block number of the next block to be read by read_block). Avalid block number is 1 or greater. If an error occurs, the value is < 0.The following errors are detected: - channel number is outside valid range - specified channel is not open - this routine is for use only with block channel types - error during the file read operation - EOF encountered on the data file*/read_block ( channel, val_pntr )char *val_pntr[];int channel;{ int i, err; short num_left, num_to_read; struct iovec { char *iov_base; int iov_length; }; struct iovec io_vector[MAX_VARS_PER_BLK]; strcpy(ervar.routine, "read_block"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name *//* * do the easy error checking: */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } strcpy(ervar.name, fd[channel].filename); if (fd[channel].ch_type != 2) /* not a "block" channel */ { if (auto_er) error_exit(-8); return(-8); }/* * write the input vector: */ for (i=0; i<fd[channel].format[1]; i++) { io_vector[i].iov_base = val_pntr[i]; io_vector[i].iov_length = fd[channel].bytes[i]; }/* * read the block in chunks of 16 variables at a time (readv limitation): */ i = 0; num_left = fd[channel].format[1]; while (num_left > 0) { num_to_read = 16; if (num_left < 16) num_to_read = num_left; err = readv(fd[channel].fd, &io_vector[i], num_to_read); if (err == -1) /* error during read */ { perror("The system call error in disk read is"); if (auto_er) error_exit(-6); return(-6); } if (err == 0) /* EOF encountered */ { if (auto_er) error_exit(-5); return(-5); } i += num_to_read; num_left -= num_to_read; } return(++fd[channel].next);}/* ----------------------- CLOSE CHANNEL ROUTINE ------------------------ *//* DESCRIPTION: status = close_channel ( chan_id ) This routine closes the specified channel. Doing so makes the channel idavailable for re-assignment.Returned value: The returned value indicates the error status of the routine. If no erroroccurs, the returned value is 0. If an error occurs, the value is < 0.The following errors are detected: - channel number is outside valid range - specified channel is not open*/close_channel ( channel )int channel;{ strcpy(ervar.routine, "close_channel"); strcpy(ervar.name, "UNKNOWN"); /* the first 2 errors have no f or v name */ if (channel < 0 || channel >= MAX_CHANNELS) /* bogus channel # */ { ervar.param = channel; if (auto_er) error_exit(-3); return(-3); } if (fd[channel].open != 1) /* channel not open */ { ervar.param = channel; if (auto_er) error_exit(-4); return(-4); } fd[channel].open = 0; close (fd[channel].fd); return(0);}/* ------------------- PRINT DISK READ ERROR ROUTINE -------------------- *//* DESCRIPTION: print_disk_read_error ( err_num ) This routine prints an error message which corresponds to "err_num".It is printed on stderr.*/print_disk_read_error ( err_num )int err_num;{ char *disk_read_error (); if (err_num < 0) { fprintf(stderr, "Disk_IO error in routine '%s'.\n", ervar.routine); fprintf(stderr, "The filename or variable name associated with the offending call is:\n"); fprintf(stderr, "%s\n", ervar.name); fprintf(stderr, disk_read_error(err_num) ); if (ervar.param != PARAM_OK) { fprintf(stderr, "Its value was: %d\n", ervar.param); ervar.param = PARAM_OK; } } else fprintf(stderr, disk_read_error(err_num) ); return;}/* ---------------------- DISK READ ERROR ROUTINE ----------------------- *//* DESCRIPTION: error_string = disk_read_error ( err_num ) The disk_read_error routine returns a brief error message whichcorresponds to "err_num".*/char *disk_read_error ( err_num )int err_num;{ static char err_string[70]; static char *err_msg[] = { "No error", /* 0 *//* * COMMON ERRORS: */ "unassigned", /* 1 */ "Filename is too long", /* 2 */ "Channel number is outside valid range", /* 3 */ "Specified channel is not open", /* 4 */ "EOF encountered on the data file", /* 5 */ "Error during the file read operation", /* 6 */ "This routine is for use only with variable channel types", /* 7 */ "This routine is for use only with block channel types", /* 8 */ "The file connected to this channel prohibits positioning", /* 9 */ "Invalid extension in filename", /* 10 */ "unassigned", /* 11 *//* * OPEN CHANNEL ERRORS: */ "There is a format file problem", /* 12 */ "The data file could not be opened", /* 13 */ "All channels are open", /* 14 */ "The specified variable was not found", /* 15 */ "No data file found", /* 16 */ "unassigned", /* 17 */ "unassigned", /* 18 *//* * READ FORMAT ERRORS: */ "The format file could not be opened", /* 19 */ "The format file is not complete", /* 20 */ "Invalid value read for file type", /* 21 */ "Invalid value read for variables/block", /* 22 */ "Invalid value read for data type", /* 23 */ "Invalid value read for values/block", /* 24 */ "No data file found, so can't determine format", /* 25 *//* * FILE LENGTH ERRORS: */ "unassigned", /* 26 *//* * GOTO SAMPLE ERRORS: */ "Effective sample_num is < 1", /* 27 */ "unassigned", /* 28 *//* * READ VARIABLE ERRORS: */ "unassigned", /* 29 *//* * GOTO BLOCK ERRORS: */ "Effective block_num is < 1", /* 30 */ "unassigned", /* 31 *//* * READ BLOCK ERRORS: */ "unassigned", /* 32 *//* * CLOSE CHANNEL ERRORS: */ "unassigned", /* 33 *//* * ALL OTHER ERRORS: */ "Bad value for error number" /* 34 */ };#define NUM 34 if (err_num > 0) err_num = 0; /* force positive arguments to give no error */ strcpy(err_string, (-err_num < NUM) ? err_msg[-err_num] : err_msg[NUM] ); strcat(err_string, ".\n"); return(err_string);}/* -------------------------- SUPPORT ROUTINES -------------------------- *//* ----------------------- TEST FILENAME ROUTINE ------------------------ *//* DESCRIPTION: This routine examines the filename "in_file" and returns in "out_file" thedata file or format file name which corresponds to "in_file". "out_file_type"specifies whether to return the name of a data file (if 1) or the format filename (if 2). This is the routine which implements the filename flexibilitywhich read_format and the open channel routines have.The return value of the function indicates the following: -2 - invalid extension -1 - data file not found 0 - in_file is .sg file type 1 - in_file is .spd file type ( value increases by 1 for each added data file type )*/static test_filename ( in_file, out_file, out_file_type )char in_file[], out_file[];int out_file_type;{ char extn[MAX_FILENAME_LENG]; if (rindex(in_file, '.') == NULL) /* in_file does not have an extension */ { strcpy(out_file, in_file); strcat(out_file, DFE); /* out_file = in_file.DFE */ if (access(out_file, 0) == 0) /* out_file.DFE exists */ { if (out_file_type == 2) /* output the format file name instead */ { strcpy(out_file, in_file); strcat(out_file, FFE); /* out_file = in_file.FFE */ } return(0); /* .sg file type */ } strcpy(out_file, in_file); strcat(out_file, ".spd"); /* out_file = in_file.spd */ if (access(out_file, 0) == 0) return(1); /* .spd file type */ return(-1); /* could not find a data file */ } else /* in_file has an extension */ { strcpy(extn, rindex(in_file, '.') ); /* extn = the extension */ strcpy(out_file, ""); /* out_file = extensionless in_file */ strncat(out_file, in_file, strlen(in_file)-strlen(extn) ); if (strcmp(extn, DFE) == 0) /* the extension is DFE */ { if (out_file_type == 1) strcat(out_file, DFE); if (out_file_type == 2) strcat(out_file, FFE); return(0); /* .sg file type */ } if (strcmp(extn, FFE) == 0) /* the extension is FFE */ { if (out_file_type == 1) return(-2); if (out_file_type == 2) strcat(out_file, FFE); return(0); /* .sg file type */ } if (strcmp(extn, ".spd") == 0) /* the extension is .spd */ { strcpy(out_file, in_file); return(1); /* .spd file type */ } return(-2); /* invalid extension */ }}/* ----------------------- READ SUNGRAPH DATA FILE ---------------------- *//* DESCRIPTION: This routine is like "read" but instead reads data files which are in theSUNGRAPH format. It operates with channels opened for single variable access.It fetches the next "samp" samples of the variable that "channel" was opened toread. The function value is the actual number of samples read, unless "read"or "lseek" returns -1, in which case -1 is the function value.*/static read_sg ( channel, values, samp )char values[];int channel, samp;{ register int bytes_per_samp, index, left; int n, bytes, total; total = 0; index = 0; left = samp; bytes_per_samp = bytes_in[fd[channel].format[2*fd[channel].v] -1]; while (left > 0) { if (left >= fd[channel].samp_avail) /* read to end of current block */ { bytes = bytes_per_samp * fd[channel].samp_avail; n = read(fd[channel].fd, &values[index], bytes); if (n == -1) return(-1); /* read error */ if (n != bytes) /* EOF reached */ { fd[channel].samp_avail -= n / bytes_per_samp; return(total + n/bytes_per_samp); } total += fd[channel].samp_avail; left -= fd[channel].samp_avail; index += bytes; lseek(fd[channel].fd, (long) fd[channel].gap_total, 1); fd[channel].samp_avail = fd[channel].format[2*fd[channel].v + 1]; } else /* read just the number of samples left to fetch for this call */ { bytes = bytes_per_samp * left; n = read(fd[channel].fd, &values[index], bytes); if (n == -1) return(-1); /* read error */ if (n != bytes) /* EOF reached */ { fd[channel].samp_avail -= n / bytes_per_samp; return(total + n/bytes_per_samp); } total += left; fd[channel].samp_avail -= left; left = 0; } } return(total);}/* ----------------------------- ERROR_EXIT ----------------------------- */static error_exit(err_num)int err_num;{ print_disk_read_error(err_num); exit(-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -