autoFileInMemory FileInMemory_create (MelderFile file) { try { if (! MelderFile_readable (file)) { Melder_throw (U"File not readable."); } long length = MelderFile_length (file); if (length <= 0) { Melder_throw (U"File is empty."); } autoFileInMemory me = Thing_new (FileInMemory); my d_path = Melder_dup (file -> path); my d_id = Melder_dup (MelderFile_name (file)); my d_numberOfBytes = length; my ownData = true; my d_data = NUMvector <char> (0, my d_numberOfBytes); // includes room for a final null byte in case the file happens to contain text MelderFile_open (file); for (long i = 0; i < my d_numberOfBytes; i++) { unsigned int number = bingetu1 (file -> filePointer); my d_data[i] = number; } my d_data[my d_numberOfBytes] = 0; // one extra MelderFile_close (file); return me; } catch (MelderError) { Melder_throw (U"FileInMemory not created from \"", Melder_fileToPath (file), U"\"."); } }
FileInMemory FileInMemory_create (MelderFile file) { try { if (! MelderFile_readable (file)) { Melder_throw ("File not readable."); } long length = MelderFile_length (file); if (length <= 0) { Melder_throw ("File is empty."); } autoFileInMemory me = Thing_new (FileInMemory); my d_path = Melder_wcsdup (file -> path); my d_id = Melder_wcsdup (MelderFile_name (file)); my d_numberOfBytes = length; my d_data = NUMvector <char> (0, my d_numberOfBytes); // one extra for 0-byte at end if text MelderFile_open (file); for (long i = 0; i < my d_numberOfBytes; i++) { unsigned int number = bingetu1 (file -> filePointer); my d_data[i] = number; } my d_data[my d_numberOfBytes] = 0; // one extra MelderFile_close (file); return me.transfer(); } catch (MelderError) { Melder_throw ("FileInMemory not created from \"", Melder_fileToPath (file), "\"."); } }
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(); }