/// <summary> /// Updates the data size and CRC in the file header /// Updates file CRC /// </summary> public void Close() { if (open == false) { throw new FitException("Encode:Close - Encode not opened yet, must call Encode:Open()"); } // Rewrites the header now that the datasize is known header.DataSize = (uint)(fitDest.Length - header.Size); header.UpdateCRC(); header.Write(fitDest); // Compute and write the file CRC to the end of the file byte[] data = new byte[fitDest.Length]; fitDest.Position = 0; fitDest.Read(data, 0, data.Length); ushort fileCrc = CRC.Calc16(data, data.Length); byte[] buffer = BitConverter.GetBytes(fileCrc); fitDest.Write(buffer, 0, 2); }
/// <summary> /// Reads a FIT binary file. /// </summary> /// <param name="fitStream">Seekable (file)stream to parse.</param> /// <returns> /// Returns true if reading finishes successfully. /// </returns> public bool Read(Stream fitStream) { bool readOK = true; try { // Attempt to read header fileHeader = new Header(fitStream); readOK &= fileHeader.IsValid(); if (!readOK) { throw new FitException("FIT decode error: File is not FIT format. Check file header data type."); } if ((fileHeader.ProtocolVersion & Fit.ProtocolVersionMajorMask) > (Fit.ProtocolMajorVersion << Fit.ProtocolVersionMajorShift)) { // The decoder does not support decode accross protocol major revisions throw new FitException(String.Format("FIT decode error: Protocol Version {0}.X not supported by SDK Protocol Ver{1}.{2} ", (fileHeader.ProtocolVersion & Fit.ProtocolVersionMajorMask) >> Fit.ProtocolVersionMajorShift, Fit.ProtocolMajorVersion, Fit.ProtocolMinorVersion)); } // Read data messages and definitions while (fitStream.Position < fitStream.Length - 2) { DecodeNextMessage(fitStream); } // Is the file CRC ok? byte[] data = new byte[fitStream.Length]; fitStream.Position = 0; fitStream.Read(data, 0, data.Length); readOK &= (CRC.Calc16(data, data.Length) == 0x0000); } catch (EndOfStreamException e) { readOK = false; Debug.WriteLine("{0} caught and ignored. ", e.GetType().Name); throw new FitException("Decode:Read - Unexpected End of File", e); } return(readOK); }
/// <summary> /// Reads a FIT binary File /// </summary> /// <param name="fitStream">Seekable (file)stream to parse.</param> /// <param name="mode">Decode Mode to use for reading the file</param> /// <returns> /// Returns true if reading finishes successfully. /// </returns> public bool Read(Stream fitStream, DecodeMode mode) { bool readOK = true; long fileSize = 0; long filePosition = fitStream.Position; try { // Attempt to read header if (mode == DecodeMode.Normal) { fileHeader = new Header(fitStream); readOK &= fileHeader.IsValid(); // Get the file size from the header // When the data size is invalid set the file size to the fitstream length if (!invalidDataSize) { fileSize = fileHeader.Size + fileHeader.DataSize + CRCSIZE; } else { fileSize = fitStream.Length; } if (!readOK) { throw new FitException("FIT decode error: File is not FIT format. Check file header data type. Error at stream position: " + fitStream.Position); } if ((fileHeader.ProtocolVersion & Fit.ProtocolVersionMajorMask) > (Fit.ProtocolMajorVersion << Fit.ProtocolVersionMajorShift)) { // The decoder does not support decode accross protocol major revisions throw new FitException(String.Format("FIT decode error: Protocol Version {0}.X not supported by SDK Protocol Ver{1}.{2} ", (fileHeader.ProtocolVersion & Fit.ProtocolVersionMajorMask) >> Fit.ProtocolVersionMajorShift, Fit.ProtocolMajorVersion, Fit.ProtocolMinorVersion)); } } else if (mode == DecodeMode.InvalidHeader) { // When skipping the header force the stream position to be at the beginning of the data // Also the fileSize is the length of the filestream. fitStream.Position += Fit.HeaderWithCRCSize; fileSize = fitStream.Length; } else if (mode == DecodeMode.DataOnly) { // When the stream is only data move the position of the stream // to the start. FileSize is the length of the stream fitStream.Position = 0; fileSize = fitStream.Length; } else { throw new FitException("Invalid Decode Mode Provided to read"); } // Read data messages and definitions while (fitStream.Position < (filePosition + fileSize - CRCSIZE)) { DecodeNextMessage(fitStream); } // Is the file CRC ok? if ((mode == DecodeMode.Normal) && !invalidDataSize) { byte[] data = new byte[fileSize]; fitStream.Position = filePosition; fitStream.Read(data, 0, data.Length); readOK &= (CRC.Calc16(data, data.Length) == 0x0000); fitStream.Position = filePosition + fileSize; } } catch (EndOfStreamException e) { readOK = false; Debug.WriteLine("{0} caught and ignored. ", e.GetType().Name); throw new FitException("Decode:Read - Unexpected End of File at stream position" + fitStream.Position, e); } catch (FitException e) { // When attempting to decode files with invalid data size this indicates the EOF. if (!invalidDataSize) { throw e; } } return(readOK); }