コード例 #1
0
ファイル: UnitMan.cs プロジェクト: mbeloshapkin/UnitMan
        /// <summary>
        /// Compose UOM from signature which is not defined in source definition file. Find master UOMs, calculate scale, generate label. The signature could be of any complexity.
        /// </summary>
        /// <param name="ANewSignature">A new signature</param>
        /// <returns>Newly composed UOM. Please, note, the new UOM signature could differ on source signature.</returns>
        protected UOM Compose(string ANewSignature)
        {
#if DEBUG
            CheckSignature(ANewSignature);
#endif
            Atom[] atoms = Atomize(ANewSignature);

            // Search for master UOMs
            UOM[] masters = new UOM[atoms.Length];
            UOM   newUOM  = new UOM(); newUOM.Scale = 1.0; newUOM.Signature = ANewSignature;
            for (int ct = 0; ct < atoms.Length; ct++)
            {
                Atom atom = atoms[ct];
                if (!UOMs.ContainsKey(atom.AtomicUOM + "1"))
                {
                    throw new Exception("UnitMan failed to compose new UOM for signature " +
                                        ANewSignature + ". Atomic UOM " + atom.AtomicUOM + " not found.");
                }
                // Atomic UOM found in list. Check if it is master and update scale of new UOM if not.
                UOM src = UOMs[atom.AtomicUOM + "1"].Clone();
                if (src.IsMaster)
                {
                    masters[ct] = src;
                }
                else
                {
                    UOM master = src.Master;
                    // Update scale of new UOM
                    for (int cte = 0; cte < Atom.Abs(atom.Exponent); cte++)
                    {
                        newUOM.Scale *= atom.Exponent > 0 ? src.Scale : 1.0 / src.Scale;
                    }
                    masters[ct] = master.Clone();
                }
            }

            // Masters are of positive exponents here. The exponents could be large than 1.

            for (int ct = 0; ct < masters.Length; ct++)
            {
                masters[ct].Signature = masters[ct].Signature.Replace("1", Atom.Abs(atoms[ct].Exponent).ToString());                                         // That's why I need clone master UOM's
            }
            // Create the master signature
            string masterSignature = masters[0].Signature;
            for (int ct = 1; ct < masters.Length; ct++)
            {
                masterSignature += masters[ct].Signature;
            }
            Atom[] masterAtoms = Atomize(masterSignature);

            for (int ct = 0; ct < masterAtoms.Length; ct++)
            {
                if (atoms[ct].Exponent < 0)
                {
                    masterAtoms[ct].Neg();                                                                     // Restore signs
                }
            }
            Array.Sort(masterAtoms);
            masterSignature = Recombine(masterAtoms);

            // Check the master and domain exists
            if (!UOMs.ContainsKey(masterSignature))
            {
                throw new Exception("Domain for UOM " + ANewSignature + " not found");
            }
            UOM masterUOM = UOMs[masterSignature];

            // Generate label
            bool slash = false; newUOM.Label = "";
            for (int ct = 0; ct < atoms.Length; ct++)
            {
                // check the slash shall be inserted
                if (!slash && atoms[ct].Exponent < 0)
                {
                    if (ct == 0)
                    {
                        newUOM.Label = "1/";
                    }
                    else
                    {
                        newUOM.Label += "/";
                    }
                    slash = true;
                }
                newUOM.Label += atoms[ct].AtomicUOM;
                if (Math.Abs(atoms[ct].Exponent) > 1)
                {
                    newUOM.Label += (int)Math.Abs(atoms[ct].Exponent);
                }
            }

            newUOM.Name   = newUOM.Label;
            newUOM.Plural = newUOM.Label;
            newUOM.Master = masterUOM;
            UOMs.Add(newUOM.Signature, newUOM);
            return(newUOM);
        }