/// <summary> /// Reads a binary file from the mount service and writes it into a memory stream /// </summary> /// <param name="filename">Relative path to the file on the mount service</param> /// <param name="readReaderPort">Response port</param> /// <returns></returns> private IEnumerator <ITask> ReadFileFromMountService(string filename, FileReaderPort readReaderPort) { if (string.IsNullOrEmpty(filename)) { Exception exception = new ArgumentException( "Cannot read file from mount service. No filename specified" ); LogWarning(exception); readReaderPort.Post(exception); yield break; } // Construct URI to file string fileUri = "http://localhost" + ServicePaths.MountPoint; if (!filename.StartsWith("/")) { fileUri += "/"; } fileUri += filename; // Establish channel with mount service mnt.MountServiceOperations mountPort = ServiceForwarder <mnt.MountServiceOperations>(fileUri); // Set up byte query mnt.QueryBytesRequest queryBytesRequest = new mnt.QueryBytesRequest(); mnt.QueryBytes queryBytes = new mnt.QueryBytes(queryBytesRequest); queryBytesRequest.Offset = 0; queryBytesRequest.Length = MountServiceReadBlockSize; // Read file in blocks from mount service MemoryStream memoryStream = new MemoryStream(); int bytesRead = (int)queryBytesRequest.Length; while (bytesRead == queryBytesRequest.Length) { mountPort.Post(queryBytes); yield return((Choice)queryBytes.ResponsePort); Fault fault = (Fault)queryBytes.ResponsePort; if (fault != null) { LogWarning(fault.ToException()); readReaderPort.Post(fault.ToException()); yield break; } mnt.QueryBytesResponse byteQueryResponse = (mnt.QueryBytesResponse)queryBytes.ResponsePort; bytesRead = byteQueryResponse.Data.Length; memoryStream.Write(byteQueryResponse.Data, 0, bytesRead); queryBytesRequest.Offset += bytesRead; } memoryStream.Position = 0; readReaderPort.Post(memoryStream); }
/// <summary> /// Writes a binary file from a stream to the mount service /// </summary> /// <param name="filename">Filename and path where the file shall be store on the mount service</param> /// <param name="fileStream">Stream containing the file data</param> /// <param name="responsePort">File writer response port</param> /// <returns></returns> private IEnumerator <ITask> WriteFileToMountService( string filename, Stream fileStream, SuccessFailurePort responsePort) { // Stream needs to support seeking, otherwise we will never know when the end // is reached if (!fileStream.CanSeek) { throw new ArgumentException("File stream needs to support seeking"); } // Construct URI to file string fileUri = "http://localhost" + ServicePaths.MountPoint; if (!filename.StartsWith("/")) { fileUri += "/"; } fileUri += filename; // Establish channel with mount service mnt.MountServiceOperations mountPort = ServiceForwarder <mnt.MountServiceOperations>(fileUri); // Set up byte update message mnt.UpdateBytesRequest updateBytesRequest = new mnt.UpdateBytesRequest(); mnt.UpdateBytes updateBytes = new mnt.UpdateBytes(updateBytesRequest); updateBytesRequest.Offset = 0; updateBytesRequest.Truncate = false; // Write file in blocks to mount service updateBytesRequest.Data = new byte[MountServiceWriteBlockSize]; fileStream.Position = 0; int writeOffset = 0; while (fileStream.Position < fileStream.Length) { // Fill buffer int offset = 0; while (offset < MountServiceWriteBlockSize && fileStream.Position < fileStream.Length) { int bytesRead = fileStream.Read( updateBytesRequest.Data, offset, MountServiceWriteBlockSize - offset ); offset += bytesRead; } if (offset < MountServiceWriteBlockSize) { // Last message will most probably not contain a completely filled buffer Array.Resize <byte>(ref updateBytesRequest.Data, offset); } if (fileStream.Position >= fileStream.Length) { // End of stream reached, truncate file on mount service // to current position updateBytesRequest.Truncate = true; } updateBytesRequest.Offset = writeOffset; // Send message to mount service mountPort.Post(updateBytes); yield return((Choice)updateBytes.ResponsePort); Fault fault = (Fault)updateBytes.ResponsePort; if (fault != null) { Exception exception = fault.ToException(); LogWarning(exception); responsePort.Post(exception); yield break; } // Clear response port DefaultUpdateResponseType success = (DefaultUpdateResponseType)updateBytes.ResponsePort; writeOffset += updateBytesRequest.Data.Length; } responsePort.Post(SuccessResult.Instance); }