static autoDaata bdfFileRecognizer (int nread, const char * /* header */, MelderFile file) { const char32 *fileName = MelderFile_name (file); bool isBdfFile = Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".bdf") || Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".BDF"); bool isEdfFile = Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".edf") || Melder_stringMatchesCriterion (fileName, kMelder_string_ENDS_WITH, U".EDF"); if (nread < 512 || (! isBdfFile && ! isEdfFile)) return autoDaata (); return EEG_readFromBdfFile (file); }
autoDaata Data_readFromFile (MelderFile file) { int nread, i; char header [513]; autofile f = Melder_fopen (file, "rb"); nread = fread (& header [0], 1, 512, f); f.close (file); header [nread] = 0; /***** 1. Is this file a text file as defined in Data.cpp? *****/ if (nread > 11) { char *p = strstr (header, "TextFile"); if (p && p - header < nread - 8 && p - header < 40) return Data_readFromTextFile (file); } if (nread > 22) { char headerCopy [101]; memcpy (headerCopy, header, 100); headerCopy [100] = '\0'; for (i = 0; i < 100; i ++) if (headerCopy [i] == '\0') headerCopy [i] = '\001'; char *p = strstr (headerCopy, "T\001e\001x\001t\001F\001i\001l\001e"); if (p && p - headerCopy < nread - 15 && p - headerCopy < 80) return Data_readFromTextFile (file); } /***** 2. Is this file a binary file as defined in Data.cpp? *****/ if (nread > 13) { char *p = strstr (header, "BinaryFile"); if (p && p - header < nread - 10 && p - header < 40) return Data_readFromBinaryFile (file); } /***** 3. Is this file of a type for which a recognizer has been installed? *****/ MelderFile_getParentDir (file, & Data_directoryBeingRead); for (i = 1; i <= numFileTypeRecognizers; i ++) { autoDaata object = fileTypeRecognizers [i] (nread, header, file); if (object) { if (object -> classInfo == classDaata) // dummy object? the recognizer could have had a side effect, such as drawing a picture return autoDaata (); return object; } } /***** 4. Is this a common text file? *****/ for (i = 0; i < nread; i ++) if (header [i] < 32 || header [i] > 126) // not ASCII? break; if (i >= nread) return Data_readFromTextFile (file); Melder_throw (U"File ", file, U" not recognized."); }
autoDaata _Data_copy (Daata me) { try { if (! me) return autoDaata(); autoDaata thee = Thing_newFromClass (my classInfo).static_cast_move <structDaata> (); my v_copy (thee.peek()); Thing_setName (thee.peek(), my name); return thee; } catch (MelderError) { Melder_throw (me, U": not copied."); } }
autoDaata IDXFormattedMatrixFileRecognizer (int numberOfBytesRead, const char *header, MelderFile file) { unsigned int numberOfDimensions, type, pos = 4; /* * 9: minumum size is 4 bytes (magic number) + 4 bytes for 1 dimension + 1 value of 1 byte */ if (numberOfBytesRead < 9 || header[0] != 0 || header[1] != 0 || (type = header[2]) < 8 || numberOfBytesRead < 4 + (numberOfDimensions = header[3]) * 4) { // each dimension occupies 4 bytes return autoDaata (); } trace (U"dimensions = ", numberOfDimensions, U" type = ", type); /* * Check if the file size (bytes) equals the number of data cells in the matrix times the size of each cell (bytes) plus thee * offset of the data (4 + numberOfDimensions * 4) */ double numberOfCells = 1.0; // double because sizes of the dimensions could turn out to be very large if not an IDX format file for (long i = 1; i <= numberOfDimensions; i ++, pos += 4) { unsigned char b1 = header[pos], b2 = header[pos + 1], b3 = header[pos + 2], b4 = header[pos + 3]; long size = ((uint32) b1 << 24) + ((uint32) b2 << 16) + ((uint32) b3 << 8) + (uint32) b4; trace (U"size = ", size, U" ", b1, U" ", b2, U" ", b3, U" ", b4); numberOfCells *= size; } trace (U"Number of cells =", numberOfCells); /* * Check how many bytes each cell needs */ long cellSizeBytes = (type == 0x08 || type == 0x09) ? 1 : type == 0x0B ? 2 : (type == 0x0C || type == 0x0D) ? 4 : type == 0x0E ? 8 : 0; if (cellSizeBytes == 0) { return autoDaata (); } trace (U"Cell size =", cellSizeBytes); double numberOfBytes = numberOfCells * cellSizeBytes + 4 + numberOfDimensions * 4; trace (U"Number of bytes =", numberOfBytes); long numberOfBytesInFile = MelderFile_length (file); trace (U"File size = ", numberOfBytesInFile); if (numberOfBytes > numberOfBytesInFile || (long) numberOfBytes < numberOfBytesInFile) { // may occur if it is not an IDX file return autoDaata (); } autoMatrix thee = Matrix_readFromIDXFormatFile (file); return thee.move(); }