private void EncodeThread() { for (;;) { Thread.Sleep(1000 * 1); if (this.State == ManagerState.Stop) return; BackgroundUploadItem item = null; try { lock (_thisLock) { if (_settings.UploadItems.Count > 0) { item = _settings.UploadItems .Where(n => n.State == BackgroundUploadState.Encoding) .FirstOrDefault(); } } } catch (Exception) { return; } if (item == null) continue; try { if (item.Groups.Count == 0 && item.Keys.Count == 0) { Stream stream = null; try { if (item.Scheme == "Broadcast") { if (item.Type == "Link") { var value = item.Link; if (value == null) throw new FormatException(); stream = ContentConverter.ToStream(value); } else if (item.Type == "Profile") { var value = item.Profile; if (value == null) throw new FormatException(); stream = ContentConverter.ToStream(value); } else if (item.Type == "Store") { var value = item.Store; if (value == null) throw new FormatException(); stream = ContentConverter.ToStream(value); } } else if (item.Scheme == "Unicast") { if (item.Type == "Message") { var value = item.Message; if (value == null) throw new FormatException(); stream = ContentConverter.ToCryptoStream(value, item.ExchangePublicKey); } } else if (item.Scheme == "Multicast") { if (item.Type == "Message") { var value = item.Message; if (value == null) throw new FormatException(); stream = ContentConverter.ToStream(value); } } else { throw new FormatException(); } if (stream.Length == 0) { lock (_thisLock) { if (item.Scheme == "Broadcast") { _connectionsManager.Upload(new BroadcastMetadata(item.Type, item.CreationTime, null, item.DigitalSignature)); } else if (item.Scheme == "Unicast") { _connectionsManager.Upload(new UnicastMetadata(item.Type, item.Signature, item.CreationTime, null, item.DigitalSignature)); } else if (item.Scheme == "Multicast") { _connectionsManager.Upload(new MulticastMetadata(item.Type, item.Tag, item.CreationTime, null, null, item.DigitalSignature)); } item.State = BackgroundUploadState.Completed; } } else { KeyCollection keys = null; try { using (ProgressStream encodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) => { isStop = (this.State == ManagerState.Stop || !_settings.UploadItems.Contains(item)); }, 1024 * 1024, true)) { if (stream.Length == 0) throw new InvalidOperationException("Stream Length"); encodingProgressStream.Seek(0, SeekOrigin.Begin); item.State = BackgroundUploadState.Encoding; keys = _cacheManager.Encoding(encodingProgressStream, CompressionAlgorithm.None, CryptoAlgorithm.None, null, item.BlockLength, item.HashAlgorithm); } } catch (StopIoException) { continue; } lock (_thisLock) { if (!_settings.UploadItems.Contains(item)) { foreach (var key in keys) { _cacheManager.Unlock(key); } continue; } foreach (var key in keys) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.Keys.AddRange(keys); } } } finally { if (stream != null) stream.Dispose(); } } else if (item.Groups.Count == 0 && item.Keys.Count == 1) { BroadcastMetadata broadcastMetadata = null; UnicastMetadata unicastMetadata = null; MulticastMetadata multicastMetadata = null; { var metadata = new Metadata(item.Depth, item.Keys[0], CompressionAlgorithm.None, CryptoAlgorithm.None, null); if (item.Scheme == "Broadcast") { broadcastMetadata = new BroadcastMetadata(item.Type, item.CreationTime, metadata, item.DigitalSignature); } else if (item.Scheme == "Unicast") { unicastMetadata = new UnicastMetadata(item.Type, item.Signature, item.CreationTime, metadata, item.DigitalSignature); } else if (item.Scheme == "Multicast") { var miner = new Miner(CashAlgorithm.Version1, item.MiningLimit, item.MiningTime); try { var task = Task.Run(() => { return new MulticastMetadata(item.Type, item.Tag, item.CreationTime, metadata, miner, item.DigitalSignature); }); while (!task.IsCompleted) { if (this.State == ManagerState.Stop) miner.Cancel(); lock (_thisLock) { if (!_settings.UploadItems.Contains(item)) { miner.Cancel(); } } Thread.Sleep(1000); } multicastMetadata = task.Result; } catch (Exception) { continue; } } } lock (_thisLock) { if (!_settings.UploadItems.Contains(item)) continue; if (item.Scheme == "Broadcast") { _connectionsManager.Upload(broadcastMetadata); } else if (item.Scheme == "Unicast") { _connectionsManager.Upload(unicastMetadata); } else if (item.Scheme == "Multicast") { _connectionsManager.Upload(multicastMetadata); } item.Keys.Clear(); foreach (var key in item.UploadKeys) { _connectionsManager.Upload(key); } item.State = BackgroundUploadState.Uploading; this.CheckState(item); } } else if (item.Keys.Count > 0) { var length = Math.Min(item.Keys.Count, 128); var keys = new KeyCollection(item.Keys.Take(length)); Group group = null; try { using (var tokenSource = new CancellationTokenSource()) { var task = _cacheManager.ParityEncoding(keys, item.HashAlgorithm, item.BlockLength, item.CorrectionAlgorithm, tokenSource.Token); while (!task.IsCompleted) { if (this.State == ManagerState.Stop || !_settings.UploadItems.Contains(item)) tokenSource.Cancel(); Thread.Sleep(1000); } group = task.Result; } } catch (Exception) { continue; } lock (_thisLock) { if (!_settings.UploadItems.Contains(item)) { foreach (var key in group.Keys.Skip(group.InformationLength)) { _cacheManager.Unlock(key); } continue; } foreach (var key in group.Keys.Skip(group.InformationLength)) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.Groups.Add(group); item.Keys.RemoveRange(0, length); } } else if (item.Groups.Count > 0 && item.Keys.Count == 0) { var index = new Index(); index.Groups.AddRange(item.Groups); KeyCollection keys = null; try { using (var stream = index.Export(_bufferManager)) using (ProgressStream encodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) => { isStop = (this.State == ManagerState.Stop || !_settings.UploadItems.Contains(item)); }, 1024 * 1024, true)) { encodingProgressStream.Seek(0, SeekOrigin.Begin); item.State = BackgroundUploadState.Encoding; keys = _cacheManager.Encoding(encodingProgressStream, CompressionAlgorithm.None, CryptoAlgorithm.None, null, item.BlockLength, item.HashAlgorithm); } } catch (StopIoException) { continue; } lock (_thisLock) { if (!_settings.UploadItems.Contains(item)) { foreach (var key in keys) { _cacheManager.Unlock(key); } continue; } foreach (var key in keys) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.Keys.AddRange(keys); item.Depth++; item.Groups.Clear(); } } } catch (Exception e) { item.State = BackgroundUploadState.Error; Log.Error(e); this.Remove(item); } } }
private void UploadManagerThread() { for (; ; ) { Thread.Sleep(1000 * 1); if (this.State == ManagerState.Stop) return; BackgroundUploadItem item = null; try { lock (this.ThisLock) { if (_settings.BackgroundUploadItems.Count > 0) { item = _settings.BackgroundUploadItems .Where(n => n.State == BackgroundUploadState.Encoding) .FirstOrDefault(); } } } catch (Exception) { return; } if (item == null) continue; try { if (item.Groups.Count == 0 && item.Keys.Count == 0) { Stream stream = null; try { if (item.Type == BackgroundItemType.Link) { var link = item.Value as Link; if (link == null) throw new FormatException(); stream = link.Export(_bufferManager); } else if (item.Type == BackgroundItemType.Store) { var store = item.Value as Store; if (store == null) throw new FormatException(); stream = store.Export(_bufferManager); } else { throw new FormatException(); } if (stream.Length == 0) { lock (this.ThisLock) { item.Seed.Rank = 0; if (item.DigitalSignature != null) { item.Seed.CreateCertificate(item.DigitalSignature); } _connectionsManager.Upload(item.Seed); item.State = BackgroundUploadState.Completed; } } else { KeyCollection keys = null; byte[] cryptoKey = null; try { using (ProgressStream encodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) => { isStop = (this.State == ManagerState.Stop || !_settings.BackgroundUploadItems.Contains(item)); }, 1024 * 1024, true)) { item.Seed.Length = stream.Length; if (item.Seed.Length == 0) throw new InvalidOperationException("Stream Length"); if (item.HashAlgorithm == HashAlgorithm.Sha256) { cryptoKey = Sha256.ComputeHash(encodingProgressStream); } encodingProgressStream.Seek(0, SeekOrigin.Begin); item.State = BackgroundUploadState.Encoding; keys = _cacheManager.Encoding(encodingProgressStream, item.CompressionAlgorithm, item.CryptoAlgorithm, cryptoKey, item.BlockLength, item.HashAlgorithm); } } catch (StopIoException) { continue; } lock (this.ThisLock) { foreach (var key in keys) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.CryptoKey = cryptoKey; item.Keys.AddRange(keys); } } } finally { if (stream != null) stream.Dispose(); } } else if (item.Groups.Count == 0 && item.Keys.Count == 1) { lock (this.ThisLock) { item.Seed.Rank = item.Rank; item.Seed.Key = item.Keys[0]; item.Keys.Clear(); item.Seed.CompressionAlgorithm = item.CompressionAlgorithm; item.Seed.CryptoAlgorithm = item.CryptoAlgorithm; item.Seed.CryptoKey = item.CryptoKey; if (item.DigitalSignature != null) { item.Seed.CreateCertificate(item.DigitalSignature); } item.UploadKeys.Add(item.Seed.Key); foreach (var key in item.UploadKeys) { _connectionsManager.Upload(key); } this.SetKeyCount(item); foreach (var key in item.LockedKeys) { _cacheManager.Unlock(key); } item.LockedKeys.Clear(); item.State = BackgroundUploadState.Uploading; _connectionsManager.Upload(item.Seed); } } else if (item.Keys.Count > 0) { var length = Math.Min(item.Keys.Count, 128); var keys = new KeyCollection(item.Keys.Take(length)); Group group = null; try { group = _cacheManager.ParityEncoding(keys, item.HashAlgorithm, item.BlockLength, item.CorrectionAlgorithm, (object state2) => { return (this.State == ManagerState.Stop || !_settings.BackgroundUploadItems.Contains(item)); }); } catch (StopException) { continue; } lock (this.ThisLock) { foreach (var key in group.Keys.Skip(group.InformationLength)) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.Groups.Add(group); item.Keys.RemoveRange(0, length); } } else if (item.Groups.Count > 0 && item.Keys.Count == 0) { var index = new Index(); index.Groups.AddRange(item.Groups); index.CompressionAlgorithm = item.CompressionAlgorithm; index.CryptoAlgorithm = item.CryptoAlgorithm; index.CryptoKey = item.CryptoKey; byte[] cryptoKey = null; KeyCollection keys = null; try { using (var stream = index.Export(_bufferManager)) using (ProgressStream encodingProgressStream = new ProgressStream(stream, (object sender, long readSize, long writeSize, out bool isStop) => { isStop = (this.State == ManagerState.Stop || !_settings.BackgroundUploadItems.Contains(item)); }, 1024 * 1024, true)) { if (item.HashAlgorithm == HashAlgorithm.Sha256) { cryptoKey = Sha256.ComputeHash(encodingProgressStream); } encodingProgressStream.Seek(0, SeekOrigin.Begin); item.State = BackgroundUploadState.Encoding; keys = _cacheManager.Encoding(encodingProgressStream, item.CompressionAlgorithm, item.CryptoAlgorithm, cryptoKey, item.BlockLength, item.HashAlgorithm); } } catch (StopIoException) { continue; } lock (this.ThisLock) { foreach (var key in keys) { item.UploadKeys.Add(key); item.LockedKeys.Add(key); } item.CryptoKey = cryptoKey; item.Keys.AddRange(keys); item.Rank++; item.Groups.Clear(); } } } catch (Exception e) { item.State = BackgroundUploadState.Error; Log.Error(e); this.Remove(item); } } }