Пример #1
0
        public static void TestGZip()
        {
            string filename = @"D:\Toney\Personal\Git\toneyisnow\HeroesIII\MapLoader\maps\HoMM3 Map Pack by HoMMdb\Shadow of Death & HoMM3 Complete\Andrews Exploits.h3m";

            using (FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read))
            {
                using (FileStream output = new FileStream(filename + ".out", FileMode.Create, FileAccess.Write))
                {
                    using (CompressedStreamReader compressedStream = new CompressedStreamReader(input, true))
                    {
                        ulong  bucketSize = 1024;
                        byte[] buffer     = new byte[bucketSize];
                        ulong  readSize   = 0;

                        do
                        {
                            readSize = compressedStream.Read(buffer, bucketSize);
                            if (readSize > 0)
                            {
                                output.Write(buffer, 0, (int)readSize);
                            }
                        }while (readSize > 0);
                    }
                }
            }
        }
Пример #2
0
        static void TestZStream()
        {
            ////string filename = @"C:\Users\charl\source\repos\ConsoleApp3\bin\Debug\output\AdvEvent.txt.zip";
            string filename = @"C:\Users\charl\source\repos\ConsoleApp3\bin\Debug\output\Dwelling.txt.zip";

            using (FileStream output = new FileStream(@"D:\Temp\Dwelling.txt", FileMode.Create, FileAccess.Write))
                using (BinaryFileReader reader = new BinaryFileReader(filename))
                {
                    using (CompressedStreamReader compressedStream = new CompressedStreamReader(reader, false, 500000))
                    {
                        ulong  bucketSize = 1024;
                        byte[] buffer     = new byte[bucketSize];
                        ulong  readSize   = 0;

                        do
                        {
                            readSize = compressedStream.Read(buffer, bucketSize);
                            if (readSize > 0)
                            {
                                output.Write(buffer, 0, (int)readSize);
                                output.Flush();
                            }
                        }while (readSize > 0);
                    }
                }
        }
Пример #3
0
        static void TestCompressedStream()
        {
            string pathSource = @"D:\Toney\Personal\Git\toneyisnow\HeroesIII\MapLoader\maps\HoMM3 Map Pack by HoMMdb\Shadow of Death & HoMM3 Complete\Andrews Exploits\Andrews Exploits";

            using (FileStream sw = new FileStream(@"D:\Temp\compressedout.out", FileMode.Create, FileAccess.Write))
            {
                using (BinaryFileReader fileReader = new BinaryFileReader(pathSource))
                {
                    using (CompressedStreamReader reader = new CompressedStreamReader(fileReader, false, 100000))
                    {
                        int    batchSize = 300;
                        byte[] tempData  = new byte[batchSize];
                        ulong  readSize  = 0;
                        int    count     = 0;
                        do
                        {
                            readSize = reader.Read(tempData, (ulong)batchSize);
                            sw.Write(tempData, 0, (int)readSize);
                        }while (readSize > 0 && count++ < 100);
                    }
                }
            }
        }
Пример #4
0
        /// <summary>Handle the POST verb.</summary>
        /// <param name="httpContext">Information about the HTTP Request.</param>
        private void ProcessPost(HttpContext httpContext)
        {
            // The data from the client needs to be extracted from the incoming HTTP Stream, uncomrpessed and deserialized.  A
            // Binary Formatter is needed to serialize the Batch structure when the results are sent back to the client.
            WebTransaction.binaryFormatter = new BinaryFormatter();
            binaryFormatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
            binaryFormatter.FilterLevel    = TypeFilterLevel.Low;
            binaryFormatter.TypeFormat     = FormatterTypeStyle.TypesWhenNeeded;

            // Read the data out of the buffer that belongs to the incoming request.
            HttpRequest httpRequest = httpContext.Request;

            byte[] requestBuffer = httpContext.Request.BinaryRead(httpContext.Request.TotalBytes);
            httpRequest.InputStream.Close();

            // This will uncompress the data from the client.
            DeflateStream deflateStreamRequest = new DeflateStream(new MemoryStream(requestBuffer), CompressionMode.Decompress);

            byte[] uncompressedBuffer = CompressedStreamReader.ReadBytes(deflateStreamRequest);
            deflateStreamRequest.Close();

            // Now that the data has been read and decompressed, the original data structure can be reconstituted from the
            // serialized data.
            Batch batch = (Batch)binaryFormatter.Deserialize(new MemoryStream(uncompressedBuffer));

            // Execute the transactions contained in the batch.  Each transaction is committed or rejected as a unit.  The batch
            // contains the 'plan' of the transaction.  The task of this service is to execute the plan.
            foreach (TransactionPlan transactionPlan in batch.Transactions)
            {
                // The 'Transaction' is used to commit or reject the methods contained in the 'TransactionPlan' as a unit.  If an
                // exception is taken during the execution of any of the methods contained in the 'TransactionPlan', then the
                // transaction will be rejected and all changes will be rolled back to the beginning of this transaction.  If there
                // are no exceptions taken, then all the changes are committed to their respective data stores.
                using (Transaction transaction = new Transaction())
                {
                    // Every transaction has one or more data repositories that can be read or modified.  This will create a Resource
                    // Manager for every one of the data stores that can be referenced by this server during the processing of a
                    // transaction.  A transaction can include one or more of these databases and the internal framework will escelate
                    // from a single phase transaction to a two-phase transaction when there is more than one durable resource.
                    foreach (ResourceDescription resourceDescription in WebTransaction.resourceDescriptionList)
                    {
                        // This will create a resource manager for an ADO data resource based on the configuration settings.
                        if (resourceDescription is AdoResourceDescription)
                        {
                            transaction.Add(new AdoResourceManager(resourceDescription.Name));
                        }

                        // This will create a resource manager for SQL databases based on the configuration settings.
                        if (resourceDescription is SqlResourceDescription)
                        {
                            transaction.Add(new SqlResourceManager(resourceDescription.Name));
                        }
                    }

                    // This insures that any exceptions in the batch are reported back to the client as part of the return batch.
                    try
                    {
                        // The batch specifies one or more methods that make up a transaction.  This part of the transaction handler
                        // will attempt to collect the ADO locks for each method.  The locks are consolidated as they are collected and
                        // alphabetized.  The consolidation prevents redudant locks from being called, and the alphabetization of the
                        // table locks insures that the locks are always obtained in the same order.  Locking in the same order is
                        // critical for preventing deadlocking.
                        foreach (MethodPlan methodPlan in transactionPlan.Methods)
                        {
                            // Any exception that occurs while processing the method will be associted with the 'MethodPlan' and
                            // returned to the caller in the return batch.
                            try
                            {
                                // Load the assembly from the specification in the 'MethodData' object.  Note that if the assembly is
                                // already in memory, this operation returns quickly with a reference to the existing assembly.
                                Assembly assembly = Assembly.Load(methodPlan.TypePlan.AssemblyPlan.Name);

                                // Find and store the class (Type) of which this method is a member.  Obviously, if the type doesn't
                                // exist, this transaction won't be able to complete successfully.
                                Type type = assembly.GetType(methodPlan.TypePlan.Name);
                                if (type == null)
                                {
                                    throw new Exception(String.Format("Unable to create an object of type {0}",
                                                                      methodPlan.TypePlan.Name));
                                }

                                // The batch contains the plan for executing the method.  In order to pipeline the execution of all the
                                // methods in the transaction, the resource locks required for the method are collected first.  Once
                                // the collection is complete, the locks are acquired, then all the methods are executed.  The first
                                // part of this transaction processing involves collecting all the locks.  The method plan contains the
                                // name of the method to be executed.  Every method that wants to participate in an ADO transaction
                                // needs to provide a method that can accept a 'LockRequestList'.  This list is populated with the
                                // table locks required for the execution of the method.
                                MethodInfo methodInfo = type.GetMethod(methodPlan.Name,
                                                                       new Type[] { typeof(ParameterList) });
                                if (methodInfo == null)
                                {
                                    throw new Exception(String.Format("The method {0}.{1} can't be located in assembly {2}.",
                                                                      methodPlan.TypePlan.Name, methodPlan.Name, methodPlan.TypePlan.AssemblyPlan.Name));
                                }

                                // ADO Transactions require tables to be locked before the method is executed.  If a method needs these
                                // table locks, it will provide a 'prequel' method with the same name, but an 'AdoTransaction'
                                // parameter.  If a method is declared with this calling convension, then execute it to get the table
                                // locks.
                                if (methodInfo != null)
                                {
                                    // If any of the parameters is a reference type, that is, it references another parameter, then
                                    // resolve the reference before calling the method.
                                    foreach (Parameter parameter in methodPlan.Parameters)
                                    {
                                        if (parameter.Value is Parameter)
                                        {
                                            parameter.Value = ((Parameter)parameter.Value).Value;
                                        }
                                    }

                                    // Call the method to retrieve the table locks.  These locks will be consolodated into a single
                                    // lock when dulicate table locks are requested.  They are also alphabetized to insure the locks
                                    // are always called in the same order.
                                    TransactionCallback transactionCallback = Delegate.CreateDelegate(typeof(TransactionCallback),
                                                                                                      methodInfo) as TransactionCallback;
                                    transaction.Add(new TransactionElement(transactionCallback, methodPlan.Parameters));
                                }
                            }
                            catch (Exception exception)
                            {
                                // Any exceptions taken while trying to assembly the execution plan for the transaction will be logged
                                // agains the method plan where the problem occurred.
                                methodPlan.Exceptions.Add(exception is System.Reflection.TargetInvocationException ?
                                                          exception.InnerException : exception);

                                throw new Exception("Fatal error during batch processing.  Couldn't obtain locks for the resources.");
                            }
                        }

                        transaction.AcquireLocks();

                        // Each method that is executed in the batch has the potential to cause an exception.  However, a single
                        // exception will not stop the batch.  The batch will run to completion attempting to find other methods that
                        // may cause trouble as each method has an individual return code.  If any of the methods caused an exception,
                        // the entire batch is rolled back.  Conversely, if everything executes without any trouble the entire
                        // transaction is committed as a unit.  This basically keeps track of any error since the exceptions are caught
                        // for each method executed.
                        bool hasExceptions = false;

                        int methodIndex = 0;

                        // Once all the locks are in place, execute each of the methods prepared in the above code and register any
                        // exceptions with the MethodPlan that originated the operation.  When the batch is returned to the caller, the
                        // exceptions will correlate with the MethodPlan that caused the trouble.
                        foreach (TransactionElement transactionItem in transaction.TransactionElements)
                        {
                            try
                            {
                                // This will insure that any exceptions are passed back to the caller and associated with the
                                // 'MethodPlan' that originated the error.
                                transactionItem.TransactionCallback(transactionItem.Parameters);
                            }
                            catch (Exception exception)
                            {
                                // This indicates that there was some problem with the transaction and the results should be rejected,
                                // but only after the remaining items in the transaction have been attempted.  This maximizes the
                                // information that the caller has so the next time the batch is sent, all the errors can be fixed.  If
                                // the transaction were to stop after the first exception was discovered, there could be a sequence of
                                // many back-and-forth attempts to run the batch before all the errors were discovered and corrected.
                                hasExceptions = true;

                                // This mechanism will pass the exception back to the caller and correlate it with the MethodPlan that
                                // caused the problem.
                                transactionPlan.Methods[methodIndex].Exceptions.Add(
                                    exception is System.Reflection.TargetInvocationException ? exception.InnerException : exception);
                            }

                            // This will keep the MethodPlan items in the batch synchronized with the TransactionItems as the the
                            // transaction items are invoked.  The index is used to pass exceptions back to the calling process in a
                            // way where it matches up with the method that caused the exception.
                            methodIndex++;
                        }

                        // If any exceptions were taken while processing the batch, reject the changes to the data model.  Otherwise,
                        // the results can be committed as a unit.
                        if (hasExceptions)
                        {
                            transaction.Rollback();
                        }
                        else
                        {
                            transaction.Commit();
                        }
                    }
                    catch (Exception exception)
                    {
                        // This mechanism will pass back the exceptions to the client as part of the 'TransactionPlan' structure.
                        transactionPlan.Exceptions.Add(exception);
                    }
                }
            }

            // Pack up the output parameters and the exceptions into a special purpose 'BatchResult' structure and pass them back
            // to the client.  The client will integrate the return parameters and the exceptions with the original batch.  To the
            // user of the Web Transaction, it will look like the batch went to the server and returned as a single structure.
            // Returning just the changes is an optimization designed to reduce network traffic.
            MemoryStream memoryStreamResponse = new MemoryStream();

            binaryFormatter.Serialize(memoryStreamResponse, new BatchResult(batch));

            // This will compress the binary stream and write it to the response output stream.  Compressing the data is designed
            // to take up more CPU time, but provide better performance over the networks.
            Stream        responseStream        = httpContext.Response.OutputStream;
            DeflateStream responseDeflateStream = new DeflateStream(responseStream, CompressionMode.Compress, true);

            responseDeflateStream.Write(memoryStreamResponse.GetBuffer(), 0, (int)memoryStreamResponse.Length);
            responseDeflateStream.Close();
        }