Exemplo n.º 1
0
        /// <summary>
        /// Determines whether the data in the buffer can be represented as ASCII values.
        /// Using ".DD1 'A'" for 0x41 is obvious, but we also allow ".DD2 'A'" for
        /// 0x41 0x00.  16-bit character constants are more likely as intermediate
        /// operands, but could be found in data areas.
        ///
        /// High and low ASCII are allowed, and may be freely mixed.
        ///
        /// Testing explicitly is probably excessive, and possibly counter-productive if
        /// the user is trying to flag an area that is a mix of ASCII and non-ASCII and
        /// just wants hex for the rest, but we'll give it a try.
        /// </summary>
        /// <param name="wordWidth">Number of bytes per character.</param>
        /// <param name="isBigEndian">Word endian-ness.</param>
        /// <returns>True if data in all regions can be represented as high or low ASCII.</returns>
        private bool IsRawAsciiCompatible(int wordWidth, bool isBigEndian)
        {
            IEnumerator <TypedRangeSet.TypedRange> iter = Selection.RangeListIterator;

            while (iter.MoveNext())
            {
                TypedRangeSet.TypedRange rng = iter.Current;
                Debug.Assert(((rng.High - rng.Low + 1) / wordWidth) * wordWidth ==
                             rng.High - rng.Low + 1);
                for (int i = rng.Low; i <= rng.High; i += wordWidth)
                {
                    int val = RawData.GetWord(mFileData, rng.Low, wordWidth, isBigEndian);
                    if (val < 0x20 || (val >= 0x7f && val < 0xa0) || val >= 0xff)
                    {
                        // bad value, fail
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a list of FormatDescriptors, based on the current control configuration.
        ///
        /// The entries in the list are guaranteed to be sorted by start address and not
        /// overlap.
        ///
        /// We assume that whatever the control gives us is correct, e.g. it's not going
        /// to tell us to put a buffer full of zeroes into a DCI string.
        /// </summary>
        /// <returns>Result list.</returns>
        private void CreateDescriptorListFromControls()
        {
            FormatDescriptor.Type    type      = FormatDescriptor.Type.Default;
            FormatDescriptor.SubType subType   = FormatDescriptor.SubType.None;
            WeakSymbolRef            symbolRef = null;
            int chunkLength = -1;

            // Decode the "display as" panel, if it's relevant.
            if (radioSimpleDataHex.Enabled)
            {
                if (radioSimpleDataHex.Checked)
                {
                    subType = FormatDescriptor.SubType.Hex;
                }
                else if (radioSimpleDataDecimal.Checked)
                {
                    subType = FormatDescriptor.SubType.Decimal;
                }
                else if (radioSimpleDataBinary.Checked)
                {
                    subType = FormatDescriptor.SubType.Binary;
                }
                else if (radioSimpleDataAscii.Checked)
                {
                    subType = FormatDescriptor.SubType.Ascii;
                }
                else if (radioSimpleDataAddress.Checked)
                {
                    subType = FormatDescriptor.SubType.Address;
                }
                else if (radioSimpleDataSymbolic.Checked)
                {
                    WeakSymbolRef.Part part;
                    if (radioSymbolPartLow.Checked)
                    {
                        part = WeakSymbolRef.Part.Low;
                    }
                    else if (radioSymbolPartHigh.Checked)
                    {
                        part = WeakSymbolRef.Part.High;
                    }
                    else if (radioSymbolPartBank.Checked)
                    {
                        part = WeakSymbolRef.Part.Bank;
                    }
                    else
                    {
                        Debug.Assert(false);
                        part = WeakSymbolRef.Part.Low;
                    }
                    subType   = FormatDescriptor.SubType.Symbol;
                    symbolRef = new WeakSymbolRef(symbolEntryTextBox.Text, part);
                }
                else
                {
                    Debug.Assert(false);
                }
            }
            else
            {
                subType = 0;        // set later, or doesn't matter
            }

            // Decode the main format.
            if (radioDefaultFormat.Checked)
            {
                // Default/None; note this would create a multi-byte Default format, which isn't
                // really allowed.  What we actually want to do is remove the explicit formatting
                // from all spanned offsets, so we use a dedicated type for that.
                type = FormatDescriptor.Type.REMOVE;
            }
            else if (radioSingleBytes.Checked)
            {
                type        = FormatDescriptor.Type.NumericLE;
                chunkLength = 1;
            }
            else if (radio16BitLittle.Checked)
            {
                type        = FormatDescriptor.Type.NumericLE;
                chunkLength = 2;
            }
            else if (radio16BitBig.Checked)
            {
                type        = FormatDescriptor.Type.NumericBE;
                chunkLength = 2;
            }
            else if (radio24BitLittle.Checked)
            {
                type        = FormatDescriptor.Type.NumericLE;
                chunkLength = 3;
            }
            else if (radio32BitLittle.Checked)
            {
                type        = FormatDescriptor.Type.NumericLE;
                chunkLength = 4;
            }
            else if (radioDenseHex.Checked)
            {
                type = FormatDescriptor.Type.Dense;
            }
            else if (radioFill.Checked)
            {
                type = FormatDescriptor.Type.Fill;
            }
            else if (radioStringMixed.Checked)
            {
                type = FormatDescriptor.Type.String;
            }
            else if (radioStringMixedReverse.Checked)
            {
                type    = FormatDescriptor.Type.String;
                subType = FormatDescriptor.SubType.Reverse;
            }
            else if (radioStringNullTerm.Checked)
            {
                type    = FormatDescriptor.Type.String;
                subType = FormatDescriptor.SubType.CString;
            }
            else if (radioStringLen8.Checked)
            {
                type    = FormatDescriptor.Type.String;
                subType = FormatDescriptor.SubType.L8String;
            }
            else if (radioStringLen16.Checked)
            {
                type    = FormatDescriptor.Type.String;
                subType = FormatDescriptor.SubType.L16String;
            }
            else if (radioStringDci.Checked)
            {
                type    = FormatDescriptor.Type.String;
                subType = FormatDescriptor.SubType.Dci;
                //} else if (radioStringDciReverse.Checked) {
                //    type = FormatDescriptor.Type.String;
                //    subType = FormatDescriptor.SubType.DciReverse;
            }
            else
            {
                Debug.Assert(false);
                // default/none
            }


            Results = new SortedList <int, FormatDescriptor>();

            IEnumerator <TypedRangeSet.TypedRange> iter = Selection.RangeListIterator;

            while (iter.MoveNext())
            {
                TypedRangeSet.TypedRange rng = iter.Current;

                if (type == FormatDescriptor.Type.String)
                {
                    // We want to create one FormatDescriptor object per string.  That way
                    // each string gets its own line.
                    if ((subType == FormatDescriptor.SubType.None ||
                         subType == FormatDescriptor.SubType.Reverse))
                    {
                        CreateMixedStringEntries(rng.Low, rng.High, subType);
                    }
                    else if (subType == FormatDescriptor.SubType.CString)
                    {
                        CreateCStringEntries(rng.Low, rng.High, subType);
                    }
                    else if (subType == FormatDescriptor.SubType.L8String ||
                             subType == FormatDescriptor.SubType.L16String)
                    {
                        CreateLengthStringEntries(rng.Low, rng.High, subType);
                    }
                    else if (subType == FormatDescriptor.SubType.Dci ||
                             subType == FormatDescriptor.SubType.DciReverse)
                    {
                        CreateDciStringEntries(rng.Low, rng.High, subType);
                    }
                    else
                    {
                        Debug.Assert(false);
                        CreateMixedStringEntries(rng.Low, rng.High, subType);   // shrug
                    }
                }
                else
                {
                    CreateSimpleEntries(type, subType, chunkLength, symbolRef, rng.Low, rng.High);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Analyzes the selection to see which data formatting options are suitable.
        /// Disables radio buttons and updates labels.
        ///
        /// Call this once, when the dialog is first loaded.
        /// </summary>
        private void AnalyzeRanges()
        {
            Debug.Assert(Selection.Count != 0);

            string fmt = (Selection.RangeCount == 1) ?
                         Properties.Resources.FMT_FORMAT_SINGLE_GROUP :
                         Properties.Resources.FMT_FORMAT_MULTIPLE_GROUPS;

            selectFormatLabel.Text = string.Format(fmt, Selection.Count, Selection.RangeCount);

            IEnumerator <TypedRangeSet.TypedRange> iter = Selection.RangeListIterator;

            int mixedAsciiOkCount   = 0;
            int mixedAsciiNotCount  = 0;
            int nullTermStringCount = 0;
            int len8StringCount     = 0;
            int len16StringCount    = 0;
            int dciStringCount      = 0;

            //int revDciStringCount = 0;

            // For each range, check to see if the data within qualifies for the various
            // options.  If any of them fail to meet the criteria, the option is disabled
            // for all ranges.
            while (iter.MoveNext())
            {
                TypedRangeSet.TypedRange rng = iter.Current;
                Debug.WriteLine("Testing [" + rng.Low + ", " + rng.High + "]");

                // Start with the easy ones.  Single-byte and dense are always enabled.

                int count = rng.High - rng.Low + 1;
                Debug.Assert(count > 0);
                if ((count & 0x01) != 0)
                {
                    // not divisible by 2, disallow 16-bit entries
                    radio16BitLittle.Enabled = false;
                    radio16BitBig.Enabled    = false;
                }
                if ((count & 0x03) != 0)
                {
                    // not divisible by 4, disallow 32-bit entries
                    radio32BitLittle.Enabled = false;
                }
                if ((count / 3) * 3 != count)
                {
                    // not divisible by 3, disallow 24-bit entries
                    radio24BitLittle.Enabled = false;
                }


                // Check for run of bytes (2 or more of the same thing).  Remember that
                // we check this one region at a time, and each region could have different
                // bytes, but so long as the bytes are all the same within a region we're good.
                if (radioFill.Enabled && count > 1 &&
                    DataAnalysis.RecognizeRun(mFileData, rng.Low, rng.High) == count)
                {
                    // LGTM
                }
                else
                {
                    radioFill.Enabled = false;
                }

                // See if there's enough string data to make it worthwhile.  We use an
                // arbitrary threshold of 2+ ASCII characters, and require twice as many
                // ASCII as non-ASCII.  We arbitrarily require the strings to be either
                // high or low ASCII, and treat the other as non-ASCII.  (We could relax
                // this -- we generate separate items for each string and non-ASCII chunk --
                // but I'm trying to hide the option when the buffer doesn't really seem
                // to be holding strings.  Could replace with some sort of minimum string
                // length requirement?)
                if (radioStringMixed.Enabled)
                {
                    int asciiCount;
                    DataAnalysis.CountAsciiBytes(mFileData, rng.Low, rng.High,
                                                 out int lowAscii, out int highAscii, out int nonAscii);
                    if (highAscii > lowAscii)
                    {
                        asciiCount = highAscii;
                        nonAscii  += lowAscii;
                    }
                    else
                    {
                        asciiCount = lowAscii;
                        nonAscii  += highAscii;
                    }

                    if (asciiCount >= 2 && asciiCount >= nonAscii * 2)
                    {
                        // Looks good
                        mixedAsciiOkCount  += asciiCount;
                        mixedAsciiNotCount += nonAscii;
                    }
                    else
                    {
                        // Fail
                        radioStringMixed.Enabled        = false;
                        radioStringMixedReverse.Enabled = false;
                        mixedAsciiOkCount = mixedAsciiNotCount = -1;
                    }
                }

                // Check for null-terminated strings.  Zero-length strings are allowed, but
                // not counted -- we want to have some actual character data.  Individual
                // strings need to be entirely high-ASCII or low-ASCII, but not all strings
                // in a region have to be the same.
                if (radioStringNullTerm.Enabled)
                {
                    int strCount = DataAnalysis.RecognizeNullTerminatedStrings(mFileData,
                                                                               rng.Low, rng.High);
                    if (strCount > 0)
                    {
                        nullTermStringCount += strCount;
                    }
                    else
                    {
                        radioStringNullTerm.Enabled = false;
                        nullTermStringCount         = -1;
                    }
                }

                // Check for strings prefixed with an 8-bit length.
                if (radioStringLen8.Enabled)
                {
                    int strCount = DataAnalysis.RecognizeLen8Strings(mFileData, rng.Low, rng.High);
                    if (strCount > 0)
                    {
                        len8StringCount += strCount;
                    }
                    else
                    {
                        radioStringLen8.Enabled = false;
                        len8StringCount         = -1;
                    }
                }

                // Check for strings prefixed with a 16-bit length.
                if (radioStringLen16.Enabled)
                {
                    int strCount = DataAnalysis.RecognizeLen16Strings(mFileData, rng.Low, rng.High);
                    if (strCount > 0)
                    {
                        len16StringCount += strCount;
                    }
                    else
                    {
                        radioStringLen16.Enabled = false;
                        len16StringCount         = -1;
                    }
                }

                // Check for DCI strings.  All strings within a single range must have the
                // same "polarity", e.g. low ASCII terminated by high ASCII.
                if (radioStringDci.Enabled)
                {
                    int strCount = DataAnalysis.RecognizeDciStrings(mFileData, rng.Low, rng.High);
                    if (strCount > 0)
                    {
                        dciStringCount += strCount;
                    }
                    else
                    {
                        radioStringDci.Enabled = false;
                        dciStringCount         = -1;
                    }
                }

                //// Check for reverse DCI strings.  All strings within a single range must have the
                //// same "polarity", e.g. low ASCII terminated by high ASCII.
                //if (radioStringDciReverse.Enabled) {
                //    int strCount = DataAnalysis.RecognizeReverseDciStrings(mFileData,
                //            rng.Low, rng.High);
                //    if (strCount > 0) {
                //        revDciStringCount += strCount;
                //    } else {
                //        radioStringDciReverse.Enabled = false;
                //        revDciStringCount = -1;
                //    }
                //}
            }

            // Update the dialog with string and character counts, summed across all regions.

            if (mixedAsciiOkCount > 0)
            {
                Debug.Assert(radioStringMixed.Enabled);
                radioStringMixed.Text = string.Format(radioStringMixed.Text,
                                                      mixedAsciiOkCount, mixedAsciiNotCount);
                radioStringMixedReverse.Text = string.Format(radioStringMixedReverse.Text,
                                                             mixedAsciiOkCount, mixedAsciiNotCount);
            }
            else
            {
                Debug.Assert(!radioStringMixed.Enabled);
                radioStringMixed.Text        = string.Format(radioStringMixed.Text, "xx", "xx");
                radioStringMixedReverse.Text = string.Format(radioStringMixedReverse.Text,
                                                             "xx", "xx");
            }

            if (nullTermStringCount > 0)
            {
                Debug.Assert(radioStringNullTerm.Enabled);
                radioStringNullTerm.Text = string.Format(radioStringNullTerm.Text, nullTermStringCount);
            }
            else
            {
                Debug.Assert(!radioStringNullTerm.Enabled);
                radioStringNullTerm.Text = string.Format(radioStringNullTerm.Text, "xx");
            }

            if (len8StringCount > 0)
            {
                Debug.Assert(radioStringLen8.Enabled);
                radioStringLen8.Text = string.Format(radioStringLen8.Text, len8StringCount);
            }
            else
            {
                Debug.Assert(!radioStringLen8.Enabled);
                radioStringLen8.Text = string.Format(radioStringLen8.Text, "xx");
            }

            if (len16StringCount > 0)
            {
                Debug.Assert(radioStringLen16.Enabled);
                radioStringLen16.Text = string.Format(radioStringLen16.Text, len16StringCount);
            }
            else
            {
                Debug.Assert(!radioStringLen16.Enabled);
                radioStringLen16.Text = string.Format(radioStringLen16.Text, "xx");
            }

            if (dciStringCount > 0)
            {
                Debug.Assert(radioStringDci.Enabled);
                radioStringDci.Text = string.Format(radioStringDci.Text, dciStringCount);
            }
            else
            {
                Debug.Assert(!radioStringDci.Enabled);
                radioStringDci.Text = string.Format(radioStringDci.Text, "xx");
            }

            //if (revDciStringCount > 0) {
            //    Debug.Assert(radioStringDciReverse.Enabled);
            //    radioStringDciReverse.Text =
            //        string.Format(radioStringDciReverse.Text, revDciStringCount);
            //} else {
            //    Debug.Assert(!radioStringDciReverse.Enabled);
            //    radioStringDciReverse.Text = string.Format(radioStringDciReverse.Text, "xx");
            //}
        }