public void Seek_Result(long offset, SeekOrigin origin, long expectedPosition) { MemoryStream stream = new MemoryStream(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); SubStream subStream = new SubStream(stream, 5); long result = subStream.Seek(offset, origin); Assert.Equal(expectedPosition, result); }
public void Seek_FromCurrent() { // Verify that we can seek via the [Seek/current] method. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 0, 10)) { for (int i = 0; i < 5; i++) { substream.Position = 5; Assert.Equal(i + 5, substream.Seek(i, SeekOrigin.Current)); Assert.Equal(i + 5, substream.ReadByte()); } } } // Verify that we can't seek before the beginning of the substream. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 5, 5)) { Assert.Throws <IOException>( () => { substream.Position = 0; substream.Seek(-1, SeekOrigin.Current); }); } } // Verify that we can't seek past the end of the substream. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 5, 5)) { Assert.Throws <IOException>( () => { substream.Seek(6, SeekOrigin.Current); }); } } }
public void Seek_FromEnd() { // Verify that we can seek via the [Seek/end] method. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 0, 10)) { for (int i = 0; i < 10; i++) { Assert.Equal(9 - i, substream.Seek(-(i + 1), SeekOrigin.End)); Assert.Equal(9 - i, substream.ReadByte()); } } } // Verify that we can't seek before the beginning of the substream. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 5, 5)) { Assert.Throws <IOException>( () => { substream.Seek(-6, SeekOrigin.End); }); } } // Verify that we can't seek past the end of the substream. using (var parent = new MemoryStream()) { parent.Write(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); using (var substream = new SubStream(parent, 5, 5)) { Assert.Throws <IOException>( () => { substream.Seek(1, SeekOrigin.End); }); } } }
public void SeekTest() { var encoded = Helpers.GetExampleBytes("31 0D 05 00 06 09 2A 86 48 86 F7 0D 01 01 0B"); using (var ms = new MemoryStream(encoded)) { ms.Seek(3, SeekOrigin.Begin); var sub1 = new SubStream(ms, 3); // ORIGIN BEGIN // zero offset sub1.Seek(0, SeekOrigin.Begin); Assert.True(sub1.Position == 0); // positive offset sub1.Seek(1, SeekOrigin.Begin); Assert.True(sub1.Position == 1); // ORIGIN END // negative offset sub1.Seek(-1, SeekOrigin.End); Assert.True(sub1.Position == sub1.Length - 1); // zero offset sub1.Seek(0, SeekOrigin.End); Assert.True(sub1.Position == sub1.Length); // positive offset sub1.Seek(1, SeekOrigin.End); Assert.True(sub1.Position > sub1.Length); // ORIGIN CURRENT // negative offset sub1.Seek(-2, SeekOrigin.Current); Assert.True(sub1.Position < sub1.Length); // zero offset var lastPosition = sub1.Position; sub1.Seek(0, SeekOrigin.Current); Assert.True(sub1.Position == lastPosition); // positive offset sub1.Seek(sub1.Length * 3, SeekOrigin.Current); Assert.True(sub1.Position > sub1.Length); } }
public void MustSeekCorrectly() { var sut = new SubStream(stream.Object, 100, 200); sut.Seek(10, SeekOrigin.Begin); Assert.AreEqual(10, sut.Position); sut.Seek(15, SeekOrigin.Current); Assert.AreEqual(25, sut.Position); sut.Seek(-5, SeekOrigin.Current); Assert.AreEqual(20, sut.Position); sut.Seek(-50, SeekOrigin.End); Assert.AreEqual(150, sut.Position); sut.Seek(10, SeekOrigin.End); Assert.AreEqual(210, sut.Position); sut.Seek(-10, SeekOrigin.Begin); Assert.AreEqual(-10, sut.Position); }
public async Task <HttpResponseMessage> UploadFileAsync( Int64 containerId, String itemPath, Stream fileStream, byte[] contentId, Int64 fileLength, Boolean isGzipped, Guid scopeIdentifier, CancellationToken cancellationToken = default(CancellationToken), int chunkSize = c_defaultChunkSize, int chunkRetryTimes = c_defaultChunkRetryTimes, bool uploadFirstChunk = false, Object userState = null) { if (containerId < 1) { throw new ArgumentException(WebApiResources.ContainerIdMustBeGreaterThanZero(), "containerId"); } if (chunkSize > c_maxChunkSize) { chunkSize = c_maxChunkSize; } // if a contentId is specified but the chunk size is not a 2mb multiple error if (contentId != null && (chunkSize % c_ContentChunkMultiple) != 0) { throw new ArgumentException(FileContainerResources.ChunksizeWrongWithContentId(c_ContentChunkMultiple), "chunkSize"); } ArgumentUtility.CheckForNull(fileStream, "fileStream"); ApiResourceVersion gzipSupportedVersion = new ApiResourceVersion(new Version(1, 0), 2); ApiResourceVersion requestVersion = await NegotiateRequestVersionAsync(FileContainerResourceIds.FileContainer, s_currentApiVersion, userState, cancellationToken).ConfigureAwait(false); if (isGzipped && (requestVersion.ApiVersion < gzipSupportedVersion.ApiVersion || (requestVersion.ApiVersion == gzipSupportedVersion.ApiVersion && requestVersion.ResourceVersion < gzipSupportedVersion.ResourceVersion))) { throw new ArgumentException(FileContainerResources.GzipNotSupportedOnServer(), "isGzipped"); } if (isGzipped && fileStream.Length >= fileLength) { throw new ArgumentException(FileContainerResources.BadCompression(), "fileLength"); } HttpRequestMessage requestMessage = null; List <KeyValuePair <String, String> > query = AppendItemQueryString(itemPath, scopeIdentifier); if (fileStream.Length == 0) { // zero byte upload FileUploadTrace(itemPath, $"Upload zero byte file '{itemPath}'."); requestMessage = await CreateRequestMessageAsync(HttpMethod.Put, FileContainerResourceIds.FileContainer, routeValues : new { containerId = containerId }, version : s_currentApiVersion, queryParameters : query, userState : userState, cancellationToken : cancellationToken).ConfigureAwait(false); return(await SendAsync(requestMessage, userState, cancellationToken).ConfigureAwait(false)); } bool multiChunk = false; int totalChunks = 1; if (fileStream.Length > chunkSize) { totalChunks = (int)Math.Ceiling(fileStream.Length / (double)chunkSize); FileUploadTrace(itemPath, $"Begin chunking upload file '{itemPath}', chunk size '{chunkSize} Bytes', total chunks '{totalChunks}'."); multiChunk = true; } else { FileUploadTrace(itemPath, $"File '{itemPath}' will be uploaded in one chunk."); chunkSize = (int)fileStream.Length; } StreamParser streamParser = new StreamParser(fileStream, chunkSize); SubStream currentStream = streamParser.GetNextStream(); HttpResponseMessage response = null; Byte[] dataToSend = new Byte[chunkSize]; int currentChunk = 0; Stopwatch uploadTimer = new Stopwatch(); while (currentStream.Length > 0 && !cancellationToken.IsCancellationRequested) { currentChunk++; for (int attempt = 1; attempt <= chunkRetryTimes && !cancellationToken.IsCancellationRequested; attempt++) { if (attempt > 1) { TimeSpan backoff = BackoffTimerHelper.GetRandomBackoff(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)); FileUploadTrace(itemPath, $"Backoff {backoff.TotalSeconds} seconds before attempt '{attempt}' chunk '{currentChunk}' of file '{itemPath}'."); await Task.Delay(backoff, cancellationToken).ConfigureAwait(false); currentStream.Seek(0, SeekOrigin.Begin); } FileUploadTrace(itemPath, $"Attempt '{attempt}' for uploading chunk '{currentChunk}' of file '{itemPath}'."); // inorder for the upload to be retryable, we need the content to be re-readable // to ensure this we copy the chunk into a byte array and send that // chunk size ensures we can convert the length to an int int bytesToCopy = (int)currentStream.Length; using (MemoryStream ms = new MemoryStream(dataToSend)) { await currentStream.CopyToAsync(ms, bytesToCopy, cancellationToken).ConfigureAwait(false); } // set the content and the Content-Range header HttpContent byteArrayContent = new ByteArrayContent(dataToSend, 0, bytesToCopy); byteArrayContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream"); byteArrayContent.Headers.ContentLength = currentStream.Length; byteArrayContent.Headers.ContentRange = new System.Net.Http.Headers.ContentRangeHeaderValue(currentStream.StartingPostionOnOuterStream, currentStream.EndingPostionOnOuterStream, streamParser.Length); FileUploadTrace(itemPath, $"Generate new HttpRequest for uploading file '{itemPath}', chunk '{currentChunk}' of '{totalChunks}'."); try { if (requestMessage != null) { requestMessage.Dispose(); requestMessage = null; } requestMessage = await CreateRequestMessageAsync( HttpMethod.Put, FileContainerResourceIds.FileContainer, routeValues : new { containerId = containerId }, version : s_currentApiVersion, content : byteArrayContent, queryParameters : query, userState : userState, cancellationToken : cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // stop re-try on cancellation. throw; } catch (Exception ex) when(attempt < chunkRetryTimes) // not the last attempt { FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' fail to create HttpRequest. Error: {ex.ToString()}."); continue; } if (isGzipped) { //add gzip header info byteArrayContent.Headers.ContentEncoding.Add("gzip"); byteArrayContent.Headers.Add("x-tfs-filelength", fileLength.ToString(System.Globalization.CultureInfo.InvariantCulture)); } if (contentId != null) { byteArrayContent.Headers.Add("x-vso-contentId", Convert.ToBase64String(contentId)); // Base64FormattingOptions.None is default when not supplied } FileUploadTrace(itemPath, $"Start uploading file '{itemPath}' to server, chunk '{currentChunk}'."); uploadTimer.Restart(); try { if (response != null) { response.Dispose(); response = null; } response = await SendAsync(requestMessage, userState, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { // stop re-try on cancellation. throw; } catch (Exception ex) when(attempt < chunkRetryTimes) // not the last attempt { FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' fail to send request to server. Error: {ex.ToString()}."); continue; } uploadTimer.Stop(); FileUploadTrace(itemPath, $"Finished upload chunk '{currentChunk}' of file '{itemPath}', elapsed {uploadTimer.ElapsedMilliseconds} (ms), response code '{response.StatusCode}'."); if (multiChunk) { FileUploadProgress(itemPath, currentChunk, (int)Math.Ceiling(fileStream.Length / (double)chunkSize)); } if (response.IsSuccessStatusCode) { break; } else if (IsFastFailResponse(response)) { FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' received non-success status code {response.StatusCode} for sending request and cannot continue."); break; } else { FileUploadTrace(itemPath, $"Chunk '{currentChunk}' attempt '{attempt}' of file '{itemPath}' received non-success status code {response.StatusCode} for sending request."); continue; } } // if we don't have success then bail and return the failed response if (!response.IsSuccessStatusCode) { break; } if (contentId != null && response.StatusCode == HttpStatusCode.Created) { // no need to keep uploading since the server said it has all the content FileUploadTrace(itemPath, $"Stop chunking upload the rest of the file '{itemPath}', since server already has all the content."); break; } currentStream = streamParser.GetNextStream(); if (uploadFirstChunk) { break; } } cancellationToken.ThrowIfCancellationRequested(); return(response); }
public void ReadTest() { var encoded = Helpers.GetExampleBytes("31 0D 05 00 06 09 2A 86 48 86 F7 0D 01 01 0B"); using (var ms = new MemoryStream(encoded)) { var sub1 = new SubStream(ms, 3); ms.Seek(3, SeekOrigin.Begin); var sub2 = new SubStream(ms, 5); ms.Seek(5, SeekOrigin.Current); var sub3 = new SubStream(ms, 4); ms.Seek(4, SeekOrigin.Current); var sub4 = new SubStream(ms, 3); ms.Seek(3, SeekOrigin.End); var val1 = new byte[3]; sub1.Read(val1, 0, 3); //ComparisonResult result = compareLogic.Compare(new byte[] { 0x31, 0x0d, 0x05 }, val1); //Assert.True(result.AreEqual, result.DifferencesString); val1.ShouldBeEquivalentTo(new byte[] { 0x31, 0x0d, 0x05 }, options => options.AllowingInfiniteRecursion()); var val2 = new byte[5]; sub2.Read(val2, 0, 5); //result = compareLogic.Compare(new byte[] { 0x00, 0x06, 0x09, 0x2A, 0x86 }, val2); //Assert.True(result.AreEqual, result.DifferencesString); val2.ShouldBeEquivalentTo(new byte[] { 0x00, 0x06, 0x09, 0x2A, 0x86 }, options => options.AllowingInfiniteRecursion()); var val3 = new byte[4]; sub3.Read(val3, 0, 4); //result = compareLogic.Compare(new byte[] { 0x48, 0x86, 0xF7, 0x0D }, val3); //Assert.True(result.AreEqual, result.DifferencesString); val3.ShouldBeEquivalentTo(new byte[] { 0x48, 0x86, 0xF7, 0x0D }, options => options.AllowingInfiniteRecursion()); var val4 = new byte[3]; sub4.Read(val4, 0, 3); //result = compareLogic.Compare(new byte[] { 0x01, 0x01, 0x0B }, val4); //Assert.True(result.AreEqual, result.DifferencesString); val4.ShouldBeEquivalentTo(new byte[] { 0x01, 0x01, 0x0B }, options => options.AllowingInfiniteRecursion()); sub1.Seek(0, SeekOrigin.Begin); val1 = new byte[3]; sub1.Read(val1, 0, 3); //result = compareLogic.Compare(new byte[] { 0x31, 0x0d, 0x05 }, val1); //Assert.True(result.AreEqual, result.DifferencesString); val1.ShouldBeEquivalentTo(new byte[] { 0x31, 0x0d, 0x05 }, options => options.AllowingInfiniteRecursion()); sub1.Seek(-2, SeekOrigin.End); val1 = new byte[2]; sub1.Read(val1, 0, 2); //result = compareLogic.Compare(new byte[] { 0x0d, 0x05 }, val1); //Assert.True(result.AreEqual, result.DifferencesString); val1.ShouldBeEquivalentTo(new byte[] { 0x0d, 0x05 }, options => options.AllowingInfiniteRecursion()); } }
static void Main(string[] args) { if (!File.Exists(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile)) { Settings.Default.Reset(); Settings.Default.Save(); } if (args.Length < 1) { Console.WriteLine(Resources.Description); Console.ReadLine(); return; } #if !DEBUG try { #endif if (args[0].EndsWith(".acb", StringComparison.OrdinalIgnoreCase)) { var extractor = new DataExtractor(); extractor.ProgressChanged += OnProgressChanged; extractor.BufferSize = Settings.Default.BufferSize; extractor.EnableThreading = Settings.Default.EnableThreading; extractor.MaxThreads = Settings.Default.MaxThreads; string baseDirectory = Path.GetDirectoryName(args[0]); string outputDirectoryPath = Path.ChangeExtension(args[0], null); string extAfs2ArchivePath = string.Empty; Directory.CreateDirectory(outputDirectoryPath); using (CriTableReader acbReader = CriTableReader.Create(args[0])) { acbReader.Read(); CriAfs2Archive afs2Archive = new CriAfs2Archive(); CriAfs2Archive extAfs2Archive = new CriAfs2Archive(); CriCpkArchive cpkArchive = new CriCpkArchive(); CriCpkArchive extCpkArchive = null; extAfs2ArchivePath = outputDirectoryPath + ".awb"; bool found = File.Exists(extAfs2ArchivePath); if (!found) { extAfs2ArchivePath = outputDirectoryPath + "_streamfiles.awb"; found = File.Exists(extAfs2ArchivePath); } if (!found) { extAfs2ArchivePath = outputDirectoryPath + "_STR.awb"; found = File.Exists(extAfs2ArchivePath); } bool cpkMode = true; long awbPosition = acbReader.GetPosition("AwbFile"); if (acbReader.GetLength("AwbFile") > 0) { using (SubStream afs2Stream = acbReader.GetSubStream("AwbFile")) { cpkMode = !CheckIfAfs2(afs2Stream); if (cpkMode) { cpkArchive.Read(afs2Stream); } else { afs2Archive.Read(afs2Stream); } } } if (acbReader.GetLength("StreamAwbAfs2Header") > 0) { cpkMode = false; using (SubStream extAfs2Stream = acbReader.GetSubStream("StreamAwbAfs2Header")) { bool utfMode = DataStream.ReadCString(extAfs2Stream, 4) == "@UTF"; extAfs2Stream.Seek(0, SeekOrigin.Begin); if (utfMode) { using (CriTableReader utfAfs2HeaderReader = CriTableReader.Create(extAfs2Stream)) { utfAfs2HeaderReader.Read(); using (SubStream extAfs2HeaderStream = utfAfs2HeaderReader.GetSubStream("Header")) { extAfs2Archive.Read(extAfs2HeaderStream); } } } else { extAfs2Archive.Read(extAfs2Stream); } } if (!found) { throw new FileNotFoundException("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); } } using (SubStream waveformTableStream = acbReader.GetSubStream("WaveformTable")) using (CriTableReader waveformReader = CriTableReader.Create(waveformTableStream)) { while (waveformReader.Read()) { byte encodeType = waveformReader.GetByte("EncodeType"); bool streaming = waveformReader.GetBoolean("Streaming"); ushort id = waveformReader.ContainsField("MemoryAwbId") ? streaming ? waveformReader.GetUInt16("StreamAwbId") : waveformReader.GetUInt16("MemoryAwbId") : waveformReader.GetUInt16("Id"); string outputName = id.ToString("D5"); if (streaming) { outputName += "_streaming"; } outputName += GetExtension(encodeType); outputName = Path.Combine(outputDirectoryPath, outputName); if (streaming) { if (!found) { throw new Exception("Cannot find the external .AWB file for this .ACB file. Please ensure that the external .AWB file is stored in the directory where the .ACB file is."); } else if (extCpkArchive == null && cpkMode) { extCpkArchive = new CriCpkArchive(); extCpkArchive.Load(extAfs2ArchivePath, Settings.Default.BufferSize); } EntryBase afs2Entry = null; if (cpkMode) { afs2Entry = extCpkArchive.GetById(id); } else { afs2Entry = extAfs2Archive.GetById(id); } extractor.Add(extAfs2ArchivePath, outputName, afs2Entry.Position, afs2Entry.Length); } else { EntryBase afs2Entry = null; if (cpkMode) { afs2Entry = cpkArchive.GetById(id); } else { afs2Entry = afs2Archive.GetById(id); } extractor.Add(args[0], outputName, awbPosition + afs2Entry.Position, afs2Entry.Length); } } } } extractor.Run(); } else if (File.GetAttributes(args[0]).HasFlag(FileAttributes.Directory)) { string baseDirectory = Path.GetDirectoryName(args[0]); string acbPath = args[0] + ".acb"; string awbPath = args[0] + "_streamfiles.awb"; bool found = File.Exists(awbPath); if (!found) { awbPath = args[0] + "_STR.awb"; found = File.Exists(awbPath); } if (!found) { awbPath = args[0] + ".awb"; } if (!File.Exists(acbPath)) { throw new FileNotFoundException("Cannot find the .ACB file for this directory. Please ensure that the .ACB file is stored in the directory where this directory is."); } CriTable acbFile = new CriTable(); acbFile.Load(acbPath, Settings.Default.BufferSize); CriAfs2Archive afs2Archive = new CriAfs2Archive(); CriAfs2Archive extAfs2Archive = new CriAfs2Archive(); CriCpkArchive cpkArchive = new CriCpkArchive(); CriCpkArchive extCpkArchive = new CriCpkArchive(); cpkArchive.Mode = extCpkArchive.Mode = CriCpkMode.Id; afs2Archive.ProgressChanged += OnProgressChanged; extAfs2Archive.ProgressChanged += OnProgressChanged; cpkArchive.ProgressChanged += OnProgressChanged; extCpkArchive.ProgressChanged += OnProgressChanged; bool cpkMode = true; byte[] awbFile = (byte[])acbFile.Rows[0]["AwbFile"]; byte[] streamAwbAfs2Header = (byte[])acbFile.Rows[0]["StreamAwbAfs2Header"]; cpkMode = !(awbFile != null && awbFile.Length >= 4 && Encoding.ASCII.GetString(awbFile, 0, 4) == "AFS2") && (streamAwbAfs2Header == null || streamAwbAfs2Header.Length == 0); using (CriTableReader reader = CriTableReader.Create((byte[])acbFile.Rows[0]["WaveformTable"])) { while (reader.Read()) { byte encodeType = reader.GetByte("EncodeType"); bool streaming = reader.GetBoolean("Streaming"); ushort id = reader.ContainsField("MemoryAwbId") ? streaming ? reader.GetUInt16("StreamAwbId") : reader.GetUInt16("MemoryAwbId") : reader.GetUInt16("Id"); string inputName = id.ToString("D5"); if (streaming) { inputName += "_streaming"; } inputName += GetExtension(encodeType); inputName = Path.Combine(args[0], inputName); if (!File.Exists(inputName)) { throw new FileNotFoundException($"Cannot find audio file with id {id} for replacement.\nPath attempt: {inputName}"); } if (cpkMode) { CriCpkEntry entry = new CriCpkEntry(); entry.FilePath = new FileInfo(inputName); entry.Id = id; if (streaming) { extCpkArchive.Add(entry); } else { cpkArchive.Add(entry); } } else { CriAfs2Entry entry = new CriAfs2Entry(); entry.FilePath = new FileInfo(inputName); entry.Id = id; if (streaming) { extAfs2Archive.Add(entry); } else { afs2Archive.Add(entry); } } } } acbFile.Rows[0]["AwbFile"] = null; acbFile.Rows[0]["StreamAwbAfs2Header"] = null; if (afs2Archive.Count > 0 || cpkArchive.Count > 0) { Console.WriteLine("Saving internal AWB..."); acbFile.Rows[0]["AwbFile"] = cpkMode ? cpkArchive.Save() : afs2Archive.Save(); Console.WriteLine(); } if (extAfs2Archive.Count > 0 || extCpkArchive.Count > 0) { Console.WriteLine("Saving external AWB..."); if (cpkMode) { extCpkArchive.Save(awbPath, Settings.Default.BufferSize); } else { extAfs2Archive.Save(awbPath, Settings.Default.BufferSize); if (Encoding.UTF8.GetString(streamAwbAfs2Header, 0, 4) == "@UTF") { CriTable headerTable = new CriTable(); headerTable.Load(streamAwbAfs2Header); headerTable.Rows[0]["Header"] = extAfs2Archive.Header; headerTable.WriterSettings = CriTableWriterSettings.Adx2Settings; acbFile.Rows[0]["StreamAwbAfs2Header"] = headerTable.Save(); } else { acbFile.Rows[0]["StreamAwbAfs2Header"] = extAfs2Archive.Header; } } } acbFile.WriterSettings = CriTableWriterSettings.Adx2Settings; acbFile.Save(acbPath, Settings.Default.BufferSize); } #if !DEBUG } catch (Exception exception) { MessageBox.Show($"{exception.Message}", "ACB Editor", MessageBoxButtons.OK, MessageBoxIcon.Error); } #endif }