public void WriteTo(byte[] array) { Debug.Assert(array.Length >= Size); Debug.Assert(Format.IsValidPosition(ChunkBeginPosition)); int offset = 0; UInt64LE.Write(array, ref offset, (ulong)ChunkBeginPosition); UInt64LE.Write(array, ref offset, SipHash.ComputeHash(array, 0, offset)); }
public void WriteTo(byte[] array) { Debug.Assert(array.Length >= Size); Debug.Assert(Format.IsValidContentLength(ContentLength)); int offset = 0; UserData.WriteTo(array, ref offset); UInt64LE.Write(array, ref offset, (ulong)ContentLength); UInt64LE.Write(array, ref offset, ContentHash); UInt64LE.Write(array, ref offset, SipHash.ComputeHash(array, 0, offset)); }
public Listener(IReadOnlyCollection <byte> fileId, Func <bool, Task <long> > flush) { // This mutex serves as a marker of the existence of flush listener. RemoteFLush.FlushAsync() looks at it. // We allow all authenticated users to access the mutex. var security = new MutexSecurity(); security.AddAccessRule( new MutexAccessRule( new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), MutexRights.Synchronize, AccessControlType.Allow)); _mutex = new Mutex(true, MutexName(fileId), out bool createdNew, security); try { _srv = new PipeServer(PipeName(fileId), 2, async(Stream strm, CancellationToken cancel) => { var buf = new byte[UInt64LE.Size]; if (await strm.ReadAsync(buf, 0, 1, cancel) != 1) { throw new Exception("Empty Flush request"); } if (buf[0] != 0 && buf[0] != 1) { throw new Exception("Invalid Flush request"); } bool flushToDisk = buf[0] == 1; try { long len = await flush.Invoke(flushToDisk); Debug.Assert(len >= 0); int offset = 0; UInt64LE.Write(buf, ref offset, (ulong)len); } catch { int offset = 0; UInt64LE.Write(buf, ref offset, ulong.MaxValue); } await strm.WriteAsync(buf, 0, UInt64LE.Size, cancel); await strm.FlushAsync(cancel); }); } catch { _mutex.Dispose(); throw; } }