Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a string containing hex values, I will parse them and convert to a tagged string. Suppose here I have tags L and A, followed by the number of elements specified to determine the sequence that will need to be converted. The problem here is that I have retrieved the elements, converted them to display values, but I have the problem of not displaying the correct tags and the number of elements per tag. I think my code looks pretty ugly and unstable. Therefore, I would like to ask if you have a way to display them properly with tags according to the number elements. This is my snipped code

C#
string _str = "01 04 41 03 78 79 7A 01 04 01 00 41 07 34 35 36 20 37 38 39 01 01 41 03 31 32 33 01 00 41 03 61 62 63 01 00";
            //var _result_expect = "<L\r\n  <A \"xyz\">\r\n  <L\r\n    <L\r\n    >\r\n    <A \"456 789\">\r\n    <L\r\n      <A \"123\">\r\n    >\r\n    <L\r\n    >\r\n  >\r\n  <A \"abc\">\r\n  <L\r\n  >\r\n>.";
            bool _first_list = false, _match = false;
            string _result = "", _space = " ", _current_space = "";
            int _list_num = 0, _space_num = 0;
            while (_str.Length > 0)
            {
                if (_str.Substring(0, 2) == "41") //Is A, check if start is 41
                {
                    string _ascii_str = "", _ascii_temp = "";
                    int _ascii_len = 0;
                    _ascii_len = Convert.ToInt32(_str.Substring(3, 2), 16); //get total element number follow this tag
                    if (_ascii_len == 0)
                    {
                        _result = _result + _current_space + "<A>";
                        _str = _str.Substring(6, _str.Length - 6).Trim();
                    }
                    else
                    {
                        _ascii_temp = _str.Substring(6, (_ascii_len * 3) - 1).Trim();
                        for (int x = 0; x <= _ascii_temp.Length - 1; x = x + 3)
                        {
                            string k = _ascii_temp.Substring(x, 2).Trim();
                            _ascii_str = _ascii_str + Convert.ToChar(Convert.ToInt32(k, 16)).ToString();
                        }
                        _str = _str.Substring(6 + (_ascii_len * 3) - 1, _str.Length - 6 - ((_ascii_len * 3) - 1)).Trim();
                        _result = _result + _current_space + "<A " + "\"" + _ascii_str + "\"" + ">";
                    }
                    _match = true;
                    _list_num = _list_num - 1;
                    if (_str.Trim() == "")
                        goto skipwhile;
                    else
                        _result = _result + "\r\n";
                }
                if (_list_num <= 0 && _result != "") //define if end of tag
                {
                    _space_num = _space_num - 1;
                    _current_space = _current_space.Substring(0, _current_space.Length - 2);
                    _result = _result + _current_space + ">" + "\r\n";
                }
                if (_str.Substring(0, 2) == "01") //Is L, check if start is 01
                {
                    _list_num = Convert.ToInt32(_str.Substring(3, 2), 16); //get total element number follow this tag
                    if (_list_num == 0)
                    {
                        _result = _result + _current_space + "<L\r\n" + _current_space + ">";
                        _list_num += 1;
                        _first_list = false;
                    }
                    else
                    {
                        _result = _result + _current_space + "<L";
                        _first_list = true;
                    }
                    _str = _str.Substring(5, _str.Length - 5).Trim();
                    _match = true;                 
                    if (_str.Trim() == "")
                    {
                        _result = _result + "\r\n" + _current_space + ">";
                        goto skipwhile;
                    }
                    else
                        _result = _result + "\r\n";
                }
                if (_match == false) //exit while if not match
                {
                    goto exitwhile;
                }
                if (_list_num <= 0 || _first_list == true) //define number of space
                {
                    _first_list = false;
                    _space_num = _space_num + 1;
                    _current_space = _current_space  + _space + _space;
                }
            }
        skipwhile:
            for (int i = 1; i <= _space_num; i++)
            {
                if (i == _space_num)
                {
                    _current_space = "";
                }
                if (_current_space.Length > 0)
                {
                    _current_space = _current_space.Substring(0, _current_space.Length - 2);
                }
                _result = _result + "\r\n" + _current_space + ">";
            }
        exitwhile:
            _result = _result + ".";

According to the code, the result should be like _result_expect value, which I have commented. As more detail in this case, look at the str with tags and the hex encode in below, they show clarify and you can look at them, which I tried to convert.

HTML
<L
  <A "xyz">
  <L
    <L
    >
    <A "456 789">
    <L
      <A "123">
    >
    <L
    >
  >
  <A "abc">
  <L
  >
>.

01 04 => L with 4 elements
41 03 78 79 7A => A with 3 character is xyz
01 04 => L with 4 elements
01 00 => L with 0 element
41 07 34 35 36 20 37 38 39 => A with 7 character is 456 789
01 01 => L with 1 elements
41 03 31 32 33 => A with 3 character is 123
01 00 => L with 0 element
41 03 61 62 63 => A with 3 character is abc
01 00 => L with 0 element


What I have tried:

Tried to debug and see the result not expected
Posted
Updated 11-Jul-23 9:59am
Comments
Richard MacCutchan 10-Jul-23 12:03pm    
The obvious thing wrong with this code is the use of goto statements.
headshot9x 10-Jul-23 12:10pm    
Hi, probably you have some corrections on my code =(
Richard MacCutchan 10-Jul-23 12:47pm    
In your string you have the following at the beginning:
01 04 41 03 78 79 7A

You then say that the value after the 01 is the number of following elements (4). But in this case there are 5 items following. Later sequences also look incorrect, or perhaps your explanation is incorrect.
headshot9x 10-Jul-23 20:55pm    
Hi, look at my example, the number following as element tags number. After 01, we have 4 elements (include tags).
Richard MacCutchan 11-Jul-23 3:43am    
You and I seem to have different ways of counting. After 01 you have 04, and after 04 you have 41 03 78 79 7A, which is definitely 5 items.

1 solution

If i understand you well, you want to create custom "TagBuilder".
I'd suggest to create a class with Parse method.
Parse method should do:
- split string into parts based on space,
- loop through the collection od parts to find "L" and "A" and its items,
- create and output string.

For example:

C#
internal class TagBuilder
{
	private string sIn = string.Empty;
	private string sOut = string.Empty;
	
	public TagBuilder(string _input)
	{
		sIn = _input;
	}
	
	public string Parse()
	{
		var parts = sIn.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)
		.Select((x,id) => new { Index = id, Item = x})
		.ToList();
	
		int i = 0;
		int j = 0;
		int c = parts.Count();
		int il = 0;
		int lc = 0;
		StringBuilder sb = new StringBuilder();
		do
		{
			var P = parts[i];
			if(P.Item.Equals("01"))
			{
				//get its index
				il = P.Index;
				//count of parts 
				lc = Convert.ToInt32(parts[il+1].Item);
				sb.AppendLine($"Count of L items: {lc}");
				j = 2;
			}
			if(P.Item.Equals("41"))
			{
				//get its index
				il = P.Index;
				//count of parts 
				lc = Convert.ToInt32(parts[il+1].Item);
				//get A subitems
				var aa = string.Join(",", parts.Skip(il+2).Take(lc).Select(o => o.Item));
				sb.AppendLine($"\tCount of A items: {lc}: {{{aa}}}");
				j = lc + 2;
			}
			i += j;
		}
		while(i<c);
		sOut = sb.ToString();
		return sOut;
	}
	
	public override string ToString()
	{
		sOut = Parse();
		return sOut;
	}
}


Usage:
C#
string s = "01 04 41 03 78 79 7A 01 04 01 00 41 07 34 35 36 20 37 38 39 01 01 41 03 31 32 33 01 00 41 03 61 62 63 01 00";
TagBuilder tb = new TagBuilder(s);
tb.ToString().Dump(); //LinqPad method to dump result


Result:
Count of L items: 4
  Count of A items: 3: {78,79,7A}
Count of L items: 4
Count of L items: 0
  Count of A items: 7: {34,35,36,20,37,38,39}
Count of L items: 1
  Count of A items: 3: {31,32,33}
Count of L items: 0
  Count of A items: 3: {61,62,63}
Count of L items: 0


This is just an idea, not a complete solution. You have to change the code to your needs!
 
Share this answer
 
Comments
headshot9x 11-Jul-23 21:58pm    
Oh great, based on this, I need enhancement something. Thanks a lot.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900