From 060a191bb55d1969da53c4a5e929b1413eb3dbad Mon Sep 17 00:00:00 2001 From: User Date: Tue, 1 Dec 2015 13:19:55 +0100 Subject: [PATCH] - Detect generic file type and abort reading it it is unknown - Make buildable by VS2015 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Michal Malý --- include/libhpcs.h | 1 + libhpcs.c | 100 ++++++++++++++++++++++++++++++++++++++++++++-- libhpcs_p.h | 18 +++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) diff --git a/include/libhpcs.h b/include/libhpcs.h index d3dcfa9..a010aed 100644 --- a/include/libhpcs.h +++ b/include/libhpcs.h @@ -33,6 +33,7 @@ enum HPCS_RetCode { HPCS_E_CANT_OPEN, HPCS_E_PARSE_ERROR, HPCS_E_UNKNOWN_TYPE, + HPCS_E_INCOMPATIBLE_FILE, HPCS_E_NOTIMPL }; diff --git a/libhpcs.c b/libhpcs.c index 7360f99..951fa9f 100644 --- a/libhpcs.c +++ b/libhpcs.c @@ -68,6 +68,8 @@ const char* hpcs_error_to_string(const enum HPCS_RetCode err) return HPCS_E_PARSE_ERROR_STR; case HPCS_E_UNKNOWN_TYPE: return HPCS_E_UNKNOWN_TYPE_STR; + case HPCS_E_INCOMPATIBLE_FILE: + return HPCS_E_INCOMPATIBLE_FILE_STR; default: return HPCS_E__UNKNOWN_EC_STR; } @@ -109,6 +111,7 @@ enum HPCS_RetCode hpcs_read_mdata(const char* filename, struct HPCS_MeasuredData FILE* datafile; enum HPCS_ParseCode pret; enum HPCS_RetCode ret; + enum HPCS_GenType gentype; if (mdata == NULL) return HPCS_E_NULLPTR; @@ -117,6 +120,19 @@ enum HPCS_RetCode hpcs_read_mdata(const char* filename, struct HPCS_MeasuredData if (datafile == NULL) return HPCS_E_CANT_OPEN; + pret = read_generic_type(datafile, &gentype); + if (pret != PARSE_OK) { + PR_DEBUG("Cannot read generic file type\n"); + ret = HPCS_E_PARSE_ERROR; + goto out; + } + + if (!gentype_is_readable(gentype)) { + PR_DEBUGF("%s: %d\n", "Incompatible file type", gentype); + ret = HPCS_E_INCOMPATIBLE_FILE; + goto out; + } + pret = read_file_header(datafile, mdata); if (pret != PARSE_OK) { PR_DEBUG("Cannot read the header\n"); @@ -162,9 +178,10 @@ out: enum HPCS_RetCode hpcs_read_mheader(const char* filename, struct HPCS_MeasuredData* mdata) { - FILE* datafile; + FILE* datafile; enum HPCS_ParseCode pret; enum HPCS_RetCode ret; + enum HPCS_GenType gentype; if (mdata == NULL) return HPCS_E_NULLPTR; @@ -173,12 +190,26 @@ enum HPCS_RetCode hpcs_read_mheader(const char* filename, struct HPCS_MeasuredDa if (datafile == NULL) return HPCS_E_CANT_OPEN; + pret = read_generic_type(datafile, &gentype); + if (pret != PARSE_OK) { + PR_DEBUG("Cannot read generic file type\n"); + ret = HPCS_E_PARSE_ERROR; + goto out; + } + + if (!gentype_is_readable(gentype)) { + PR_DEBUGF("%s: %d\n", "Incompatible file type", gentype); + ret = HPCS_E_INCOMPATIBLE_FILE; + goto out; + } + pret = read_file_header(datafile, mdata); if (pret != PARSE_OK) ret = HPCS_E_PARSE_ERROR; else ret = HPCS_OK; +out: fclose(datafile); return ret; } @@ -247,6 +278,62 @@ static enum HPCS_DataCheckCode check_for_marker(const char* segment, size_t* con return DCHECK_NO_MARKER; } +static bool gentype_is_readable(const enum HPCS_GenType gentype) +{ + switch (gentype) { + case GENTYPE_ADC_LC2: + return true; + default: + return false; + } +} + +static enum HPCS_ParseCode read_generic_type(FILE* datafile, enum HPCS_GenType* gentype) +{ + enum HPCS_ParseCode ret; + uint8_t len; + char* gentype_str; + + fseek(datafile, DATA_OFFSET_GENTYPE, SEEK_SET); + if (feof(datafile)) + return PARSE_E_OUT_OF_RANGE; + if (ferror(datafile)) + return PARSE_E_CANT_READ; + + if (fread(&len, SMALL_SEGMENT_SIZE, 1, datafile) < SMALL_SEGMENT_SIZE) + return PARSE_E_CANT_READ; + + gentype_str = malloc((sizeof(char) * len) + 1); + if (gentype_str == NULL) + return PARSE_E_NO_MEM; + + if (fread(gentype_str, SMALL_SEGMENT_SIZE, len, datafile) < SMALL_SEGMENT_SIZE * len) { + ret = PARSE_E_CANT_READ; + goto out; + } + + if (feof(datafile)) { + ret = PARSE_E_OUT_OF_RANGE; + goto out; + } + if (ferror(datafile)) { + ret = PARSE_E_CANT_READ; + goto out; + } + + gentype_str[len] = '\0'; + + PR_DEBUGF("Generic type: %s\n", gentype_str); + + *gentype = strtol(gentype_str, NULL, 10); + ret = PARSE_OK; + +out: + free(gentype_str); + + return ret; +} + static HPCS_step guess_current_step(const struct HPCS_MeasuredData* mdata) { if (strcmp(mdata->cs_ver, CHEMSTAT_VER_B0625) == 0) @@ -266,8 +353,6 @@ static HPCS_step guess_elec_sigstep(const struct HPCS_MeasuredData* mdata) } } - - return CE_WORK_PARAM_STEP; } @@ -885,7 +970,12 @@ static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, ch WCHAR* w_value; enum HPCS_ParseCode ret; +#if _MSC_VER >= 1900 + w_name = wcstok(line, EQUALITY_SIGN, NULL); +#else w_name = wcstok(line, EQUALITY_SIGN); +#endif + if (w_name == NULL) return PARSE_E_NOT_FOUND; @@ -894,7 +984,11 @@ static enum HPCS_ParseCode __win32_parse_native_method_info_line(char** name, ch if (ret != PARSE_OK) return ret; +#if _MSC_VER >= 1900 + w_value = wcstok(line, EQUALITY_SIGN, NULL); +#else w_value = wcstok(NULL, EQUALITY_SIGN); +#endif if (w_value == NULL) { /* Add an empty string if there is no value */ *value = malloc(1); diff --git a/libhpcs_p.h b/libhpcs_p.h index 918e850..1fdf7cc 100644 --- a/libhpcs_p.h +++ b/libhpcs_p.h @@ -91,6 +91,7 @@ const HPCS_step CE_WORK_PARAM_OLD_STEP = 0.000083333333; const double CE_WORK_PARAM_SAMPRATE = 1.67; /* Offsets containing data of interest in .ch files */ +const HPCS_offset DATA_OFFSET_GENTYPE = 0x000; const HPCS_offset DATA_OFFSET_FILE_DESC = 0x15B; const HPCS_offset DATA_OFFSET_SAMPLE_INFO = 0x35A; const HPCS_offset DATA_OFFSET_OPERATOR_NAME = 0x758; @@ -103,6 +104,20 @@ const HPCS_offset DATA_OFFSET_Y_UNITS = 0x104C; const HPCS_offset DATA_OFFSET_DEVSIG_INFO = 0x1075; const HPCS_offset DATA_OFFSET_DATA_START = 0x1800; +/* General data file types */ +enum HPCS_GenType { + GENTYPE_GC_MS = 2, + GENTYPE_ADC_LC = 30, + GENTYPE_UV_SPECT = 31, + GENTYPE_GC_A = 8, + GENTYPE_GC_A2 = 81, + GENTYPE_GC_B = 179, + GENTYPE_GC_B2 = 180, + GENTYPE_GC_B3 = 181, + GENTYPE_ADC_LC2 = 130, + GENTYPE_ADC_UV2 = 131 +}; + /* Known ChemStation format versions */ const char CHEMSTAT_VER_B0625[] = "B.06.25 [0003]"; @@ -120,6 +135,7 @@ const char HPCS_E_NULLPTR_STR[] = "Null pointer to measured data struct."; const char HPCS_E_CANT_OPEN_STR[] = "Cannot open the specified file."; const char HPCS_E_PARSE_ERROR_STR[] = "Cannot parse the specified file, it might be corrupted or of unknown type."; const char HPCS_E_UNKNOWN_TYPE_STR[] = "The specified file contains an unknown type of measurement."; +const char HPCS_E_INCOMPATIBLE_FILE_STR[] = "The specified file is of type that is unreadable by libHPCS."; const char HPCS_E__UNKNOWN_EC_STR[] = "Unknown error code."; #ifdef _WIN32 @@ -132,6 +148,7 @@ UChar* CR_LF; static enum HPCS_ParseCode autodetect_file_type(FILE* datafile, enum HPCS_FileType* file_type, const bool p_means_pressure); static enum HPCS_DataCheckCode check_for_marker(const char* segment, size_t* const next_marker_idx); +static bool gentype_is_readable(const enum HPCS_GenType gentype); static HPCS_step guess_current_step(const struct HPCS_MeasuredData* mdata); static HPCS_step guess_elec_sigstep(const struct HPCS_MeasuredData *mdata); static bool guess_p_meaning(const struct HPCS_MeasuredData* mdata); @@ -143,6 +160,7 @@ static enum HPCS_ParseCode read_dad_wavelength(FILE* datafile, struct HPCS_Wavel static uint8_t month_to_number(const char* month); static enum HPCS_ParseCode read_date(FILE* datafile, struct HPCS_Date* date); static enum HPCS_ParseCode read_file_header(FILE* datafile, struct HPCS_MeasuredData* mdata); +static enum HPCS_ParseCode read_generic_type(FILE* datafile, enum HPCS_GenType* gentype); static enum HPCS_ParseCode read_method_info_file(HPCS_UFH fh, struct HPCS_MethodInfo* minfo); static enum HPCS_ParseCode read_signal(FILE* datafile, struct HPCS_TVPair** pairs, size_t* pairs_count, const HPCS_step step, const double sampling_rate); -- 2.43.5