📄 esignal.c
字号:
return WriteHeader(list, arch, output, annotate);}/* * Size in bytes of one record for a given format, * according to a given field list. */longRecordSize(FieldList list, int arch){ switch (arch) { case EDR1: return EdrRecordSize(list, EDR1); break; case EDR2: return EdrRecordSize(list, EDR2); break; case NATIVE: return NativeRecordSize(list); break; case ASCII: return -1; break; default: return -1; break; }}/* * Read one record from a file, in the format for a given architecture, * into the "data" members of the field specs on a NULL-terminated * linear array of REQUIRED and OPTIONAL fields, like those produced * by TypeOrder and FieldOrder. The order of the array must correspond * exactly, without omissions, to the actual order of fields in the file * (field order or type order). * Return TRUE on success, FALSE on failure. */intReadRecord(FieldSpec **fields, int arch, FILE *file){ if (file == NULL) return FALSE; switch (arch) { case NATIVE: if (!ReadNativeRecord(fields, file)) return FALSE; break; case EDR1: if (!ReadEdrRecord(fields, file, EDR1)) return FALSE; /* * On machines whose native architecture is EDR1, could call * ReadNativeRecord here. */ break; case EDR2: if (!ReadEdrRecord(fields, file, EDR2)) return FALSE; /* * On machines whose native architecture is EDR2, could call * ReadNativeRecord here. */ break; case ASCII: if (!ReadAsciiRecord(fields, file)) return FALSE; break; default: return FALSE; /* Unsupported architecture. */ break; } return TRUE;}/* * Write one record to a file, in the format for a given architecture, * from the "data" members of the field specs on a NULL-terminated * linear array of REQUIRED and OPTIONAL fields, like those produced by * TypeOrder and FieldOrder. * If annotate != NULL, add annotations in "[]" for readability. * Return TRUE on success, FALSE on failure. */intWriteRecord(FieldSpec **fields, int arch, FILE *file, Annot *annotate){ if (file == NULL) return FALSE; switch (arch) { case NATIVE: if (!WriteNativeRecord(fields, file)) return FALSE; break; case EDR1: if (!WriteEdrRecord(fields, file, EDR1)) return FALSE; /* * On machines whose native architecture is EDR1, could call * WriteNativeRecord here. */ break; case EDR2: if (!WriteEdrRecord(fields, file, EDR2)) return FALSE; /* * On machines whose native architecture is EDR2, could call * WriteNativeRecord here. */ break; case ASCII: if (!WriteAsciiRecord(fields, file, annotate)) return FALSE; break; default: return FALSE; /* Unsupported architecture. */ break; } return TRUE;}/* * Read "nrec" one-field records from "file", in the format given by * the integer code "arch", into the array indicated by "data". * The field is specified by "fields", a NULL-terminated linear array * like those produced by TypeOrder and FieldOrder and containing * exactly one REQUIRED field. Return the number of complete records * read. */longReadSamples(void *data, long nrec, FieldSpec **fields, int arch, FILE *file){ if (data == NULL) return 0; if (nrec <= 0) return 0; if (fields == NULL || fields[0] == NULL || fields[1] != NULL || fields[0]->occurrence != REQUIRED) return 0; if (file == NULL) return 0; switch (arch) { case NATIVE: return ReadNativeSamples(data, nrec, fields, file); case EDR1: return ReadEdrSamples(data, nrec, fields, file, EDR1); case EDR2: return ReadEdrSamples(data, nrec, fields, file, EDR2); case ASCII: return ReadAsciiSamples(data, nrec, fields, file); default: return 0; /* Unsupported architecture. */ break; }}/* * Write "nrec" one-field records to "file" in the format given by * the integer code "arch", from the array indicated by "data". * The field is specified by "fields", a NULL-terminated linear * array like those produced by TypeOrder and FieldOrder * and containing exactly one REQUIRED field. * Return the number of complete records written. */longWriteSamples(void *data, long nrec, FieldSpec **fields, int arch, FILE *file, Annot *annotate){ if (data == NULL) return 0; if (nrec <= 0) return 0; if (fields == NULL || fields[0] == NULL || fields[1] != NULL || fields[0]->occurrence != REQUIRED) return 0; if (file == NULL) return 0; switch (arch) { case NATIVE: return WriteNativeSamples(data, nrec, fields, file); case EDR1: return WriteEdrSamples(data, nrec, fields, file, EDR1); case EDR2: return WriteEdrSamples(data, nrec, fields, file, EDR2); case ASCII: return WriteAsciiSamples(data, nrec, fields, file, annotate); default: return 0; /* Unsupported architecture. */ break; }}/* * Allocate sufficient storage for "nrec" one-field records. * The field is specified by "fields", a NULL-terminated linear * array like those produced by TypeOrder and FieldOrder * and containing exactly one REQUIRED field. * Return NULL in case of failure. */void *AllocSamples(long nrec, FieldSpec **fields){ if (fields == NULL || fields[0] == NULL || fields[1] != NULL || fields[0]->occurrence != REQUIRED) return NULL; return malloc(nrec * FieldLength(fields[0]) * InternTypeSize(fields[0]->type));}/* * LOCAL FUNCTION DEFINITIONS *//* * Number of fields in a NULL-terminated linear array. */static intFieldArrayLength(FieldSpec **fields){ int i; /* array index */ if (fields == NULL) return 0; for (i = 0; fields[i] != NULL; i++) { } return i;}/* * Make NULL-terminated linear array in field order of REQUIRED * and OPTIONAL fields (and subfields ...) of a field list. * Fill in "fullname" members; if "prefix" is non-NULL, prefix it * to each "fullname" with a connecting dot ("."). */static FieldSpec **SubFieldOrder(FieldList list, char *prefix){ FieldSpec **fields; /* linear array of fields */ FieldSpec **old_fields; /* prior value of fields */ long nfld; /* number of fields */ long i, j; /* list indices */ FieldSpec *fld; /* top-level field */ FieldSpec **subfields; /* linear array of subfields */ long nsub; /* number of subfields */ long preflen = 0L; /* length of prefix */ char *fullname; /* name including prefix & dot */ if (list == NULL) return NULL; fields = NULL; nfld = 0; if (prefix != NULL) preflen = strlen(prefix); for (i = 0; list[i] != NULL; i++) { fld = list[i]; if (prefix == NULL) fullname = StrDup(fld->name); else { fullname = (char *) malloc(preflen + strlen(fld->name) + 2); sprintf(fullname, "%s.%s", prefix, fld->name); } fld->fullname = fullname; if (fld->occurrence != VIRTUAL) { if (fld->occurrence != GLOBAL && fld->type != NO_TYPE) /* REQUIRED or OPTIONAL */ { old_fields = fields; fields = (FieldSpec **) ((fields == NULL) ? malloc((nfld + 2) * sizeof(*fields)) : realloc(fields, (nfld + 2) * sizeof(*fields))); if (fields == NULL) /* Allocation failure. */ { free(old_fields); return NULL; } /* Could use AddField here, depending on field lists being * implemented as NULL-terminated arrays of pointers. E.g.: * * if (!AddField(&fields, fld)) * { * if (fields != NULL) * free(fields); * return NULL; * } */ fields[nfld] = fld; nfld++; fields[nfld] = NULL; } subfields = SubFieldOrder(fld->subfields, fullname); if (subfields != NULL) { /* Append subfields to fields. */ nsub = FieldArrayLength(subfields); old_fields = fields; fields = (FieldSpec **) ((fields == NULL) ? malloc((nfld + nsub + 1) * sizeof(*fields)) : realloc(fields, (nfld + nsub + 1) * sizeof(*fields))); if (fields == NULL) /* Allocation failure. */ { free(old_fields); free(subfields); return NULL; } for (j = 0; j < nsub; j++, nfld++) fields[nfld] = subfields[j]; fields[nfld] = NULL; free(subfields); } } } return fields;}/* * Find field specification with given name at top level on given * field list. */static FieldSpec *GetField(FieldList list, /* field list */ char *name) /* component name */{ int i; /* index into list */ if (list == NULL || name == NULL) return NULL; /* Search NULL-terminated list for field spec with matching name. */ for (i = 0; list[i] != NULL && strcmp(name, list[i]->name) != 0; i++) { } return list[i];}/* * Copy first component of field name: everything up to * first dot if any or whole string if none. */static char *FirstComponent(char *name){ char *tail; /* pointer to first dot */ long len; /* length of first component */ int terminator; /* delimiting char: '.' or null */ char *head; /* copy of first component */ char *p; /* pointer into copy */ if (name == NULL) return NULL; /* Parse name. */ tail = strchr(name, DOT); if (tail == NULL) /* Just one component. */ { len = strlen(name); terminator = '\0'; } else /* More than one component. */ { len = tail - name; terminator = DOT; } /* Allocate space for copy including final null. */ head = (char *) malloc(1 + len); if (head == NULL) return NULL; /* Copy. */ p = head; while (*name != terminator) *p++ = *name++; *p = '\0'; return head;}/* * Read line of length len (including '\n') from file into buf. * Check length of line, presence of terminating newline, * and absence of trailing blanks. * Trim newline and leading blanks and supply terminating null. * Return TRUE on success, FALSE on failure. */static intGetLine(char *buf, int len, FILE *file){ int i, j; fgets(buf, len+1, file); if (strlen(buf) != len || buf[len-1] != '\n') return FALSE; buf[len-1] = '\0'; /* count leading blanks */ for (j = 0; buf[j] == ' '; j++) { } if (j < len - 1 && buf[len-2] == ' ') return FALSE; /* not right justified */ if (j == 0) return TRUE; /* remove leading blanks */ for (i = 0; buf[j] != '\0'; i++,j++) buf[i] = buf[j]; buf[i] = '\0'; return TRUE; /* success */}/* * Read line of length len (including '\n') from file. Check length of * line and presence of terminating newline. Convert to long integer, * assign result through pointer val if non-NULL. Check for garbage * characters following the constant. Return TRUE on success, FALSE * on failure. */static intGetLong(long *val, int len, FILE *file){ char *buf; char *ptr; /* end-of-scan pointer from strtol */ long value; /* converted value */ buf = (char *) malloc(len+1); /* len + 1 for terminating null */ if (buf == NULL) return FALSE; /* Allocation failure. */ /* Read line; check length. */ fgets(buf, len+1, file); if (strlen(buf) != len || buf[len-1] != '\n') { free(buf); return FALSE; } /* Convert; check for bad format. */ value = strtol(buf, &ptr, 10); if (ptr != buf + (len-1)) { free(buf); return FALSE; } /* Clean up; return. */ free(buf); if (val != NULL) *val = value; return TRUE; /* success */}/* * If the value of the indicated type, located at "src" can be represented * as a long, convert to long, store the result at "dest", and return * TRUE. Otherwise return FALSE. */static intLongVal(void *src, int type, long *dest){ switch (type) { case BOOL: *dest = *(Bool *) src; break; case UCHAR: *dest = *(Uchar *) src; break; case CHAR: *dest = *(char *) src; break; case WCHAR: *dest = *(Wchar *) src; break; case SCHAR: *dest = *(Schar *) src; break; case SHORT: *dest = *(short *) src; break; case USHORT: *dest = *(Ushort *) src; break; case LONG: *dest = *(long *) src; break; case ULONG: if (*(Ulong *) src > LONG_MAX) return FALSE; *dest = *(Ulong *) src; break; case FLOAT: /* Fall through */ case DOUBLE: /* Fall through */ case FLOAT_COMPLEX: /* Fall through */ case DOUBLE_COMPLEX: { double x=0.0; switch (type) { case FLOAT: x = *(float *) src; break; case DOUBLE: x = *(double *) src; break; case FLOAT_COMPLEX: if (((FloatComplex *) src)->imag != 0.0) return FALSE; x = ((FloatComplex *) src)->real; break; case DOUBLE_COMPLEX: if (((DoubleComplex *) src)->imag != 0.0) return FALSE; x = ((DoubleComplex *) src)->real; break; } if (x != floor(x) || x > LONG_MAX || x < LONG_MIN) return FALSE; *dest = (long) x; } break; case SCHAR_COMPLEX: if (((ScharComplex *) src)->imag != 0) return FALSE; *dest = ((ScharComplex *) src)->real; break; case SHORT_COMPLEX: if (((ShortComplex *) src)->imag != 0) return FALSE; *dest = ((ShortComplex *) src)->real; break; case LONG_COMPLEX: if (((LongComplex *) src)->imag != 0) return FALSE; *dest = ((LongComplex *) src)->real; break; default: return FALSE; } return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -