locked
Readto char plus 32 other (unknown) chars after it RRS feed

  • Question

  • Hello,

    I am trying to read the call data from a very old serial PABX.

    I (thought I'd) found out that that the End Of Line was 32 blank spaces. However, that is only the case if the call is internal. 

    If the call is external then there some of these spaces are replaced with chars, and there are only 15 blanks.

    Each call does have a char near prior to the spaces which I could use instead as the readto limiter, but I  do not know how to tell it to

    string output = sp.ReadTo("I" + 32);


    I have tried above, but thats didnt work

    At the moment the code I have reads the following as one line, so I can only grab 1/2 the info

    00 127 201001 1151 299        0000 9    123456               a                      0056 m           0 I 710  9    123456               
    00 128 201001 1259 709        0000      299                  A                      0010 A           0 I

    What I am trying to grab is

    00 127 201001 1151 299        0000 9    123456               a                      0056 m           0          
    00 128 201001 1259 709        0000      299                  A                      0010 A           0

    and I can then deal with them (correctly) as separate calls.

    Can someone advise me on how I can readto("I"), but not include the 32chars after it in the next readto/line ? 

    As alwasy, Thank you :-)

    Friday, October 2, 2020 8:19 AM

Answers

  • Hello,

    I am trying to read the call data from a very old serial PABX.

    I (thought I'd) found out that that the End Of Line was 32 blank spaces. However, that is only the case if the call is internal. 

    If the call is external then there some of these spaces are replaced with chars, and there are only 15 blanks.

    Each call does have a char near prior to the spaces which I could use instead as the readto limiter, but I  do not know how to tell it to

    string output = sp.ReadTo("I" + 32);

    You left MSDN users to guess or assume that sp represents a System.IO.SerialPort.  If that isn't correct, then please clarify.

    string outputYouWant = sp.ReadTo(@"I");
    int skipChars = 32;
    for (int i = 0; i < skipChars; i++)
    {
        sp.ReadChar();
    }

    This would only work if there are at least 32 bytes to read following the found value of the character I.  If there always are then skipping those 32 bytes following the I is sure to end up making you lose relevant data at some point.

    Personally I think you've misidentified your lineterm.  Those 32 empty spaces are obviously unused data fields in some cases, not a lineterm.  It's possible that there is no actual lineterm in the data, but that programmers are expected to know some predefined value such as that "each call entry consumes exactly X number of bytes."  You can figure out if that's the case by just reading all the output and writing it to a file, then viewing that file in a hex editor.  Count the number of bytes from the start of a data block to the end of the data block.  Make sure you compare both the count in blocks that end with 32 blank spaces and the count in blocks that end with 15 blank spaces.  If a dozen or so of each type are exactly the same length, then that's the deal.

    If it turns out that every block isn't the same length, then there will surely be some metadata at the front of each entry that indicates the number of bytes for that entry.  Depending on how old your PBX is, you might be looking at a single byte, a word, or a dword.


    Before you can learn anything new you have to learn that there's stuff you don't know.

    Edits:  First I added a suggestion to just jump the sp.BaseStream ahead by 32 bytes, but on reflection I realize that may not work depending on text encoding and I also read more of the SerialPort.BaseStream documentation where it explicitly notes that Length, Position, Seek and SetLength are not supported in the BaseStream instance.

    • Edited by Andrew B. Painter Tuesday, October 6, 2020 3:23 PM
    • Marked as answer by G-Oker Thursday, October 8, 2020 6:07 AM
    Tuesday, October 6, 2020 3:00 PM

All replies

  • Hi G-Oker,

    Thank you for posting here.

    If we can be sure that the letter "I" will not appear in the front, perhaps we can use String.IndexOf Method to find the index of this "I", and then use String.Remove Method to delete the following spaces.

                string[] strs = new string[] {
                   "00 127 201001 1151 299        0000 9    123456               a                      0056 m           0 I 710  9    123456               ",
                   "00 128 201001 1259 709        0000      299                  A                      0010 A           0 I                                "};
                foreach (var item in strs)
                {
                   string re =  item.Remove(item.IndexOf('I'), 33);
                    Console.WriteLine(re);
                }

    Result:

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, October 5, 2020 2:41 AM
  • Hi Timon,

    I I save the Serialport output to a string, and then try your code, I get an exception "Index and count must refer to a location within the string. Parameter name: count".

    I thought you'd got it then :-) (as that made sense to me). Thank you for help though. I assume this i because the string its trying to read is shorter than excepted and the number I have used exceeds the string length?

    Is there anything else I can try ?


    • Edited by G-Oker Tuesday, October 6, 2020 6:22 AM
    Monday, October 5, 2020 11:33 AM
  • Hi G-Oker,

    I assume this i because the string its trying to read is shorter than excepted and the number I have used exceeds the string length

    I tested it again and got the same conclusion as you. It should be the second parameter of the Remove method that caused this problem.

    If you need to delete all characters after "I", no matter how many characters there are, you can use the overloaded method of Remve with only one parameter.

     string re = item.Remove(item.IndexOf('I'));

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, October 6, 2020 7:33 AM
  • Hello,

    I am trying to read the call data from a very old serial PABX.

    I (thought I'd) found out that that the End Of Line was 32 blank spaces. However, that is only the case if the call is internal. 

    If the call is external then there some of these spaces are replaced with chars, and there are only 15 blanks.

    Each call does have a char near prior to the spaces which I could use instead as the readto limiter, but I  do not know how to tell it to

    string output = sp.ReadTo("I" + 32);

    You left MSDN users to guess or assume that sp represents a System.IO.SerialPort.  If that isn't correct, then please clarify.

    string outputYouWant = sp.ReadTo(@"I");
    int skipChars = 32;
    for (int i = 0; i < skipChars; i++)
    {
        sp.ReadChar();
    }

    This would only work if there are at least 32 bytes to read following the found value of the character I.  If there always are then skipping those 32 bytes following the I is sure to end up making you lose relevant data at some point.

    Personally I think you've misidentified your lineterm.  Those 32 empty spaces are obviously unused data fields in some cases, not a lineterm.  It's possible that there is no actual lineterm in the data, but that programmers are expected to know some predefined value such as that "each call entry consumes exactly X number of bytes."  You can figure out if that's the case by just reading all the output and writing it to a file, then viewing that file in a hex editor.  Count the number of bytes from the start of a data block to the end of the data block.  Make sure you compare both the count in blocks that end with 32 blank spaces and the count in blocks that end with 15 blank spaces.  If a dozen or so of each type are exactly the same length, then that's the deal.

    If it turns out that every block isn't the same length, then there will surely be some metadata at the front of each entry that indicates the number of bytes for that entry.  Depending on how old your PBX is, you might be looking at a single byte, a word, or a dword.


    Before you can learn anything new you have to learn that there's stuff you don't know.

    Edits:  First I added a suggestion to just jump the sp.BaseStream ahead by 32 bytes, but on reflection I realize that may not work depending on text encoding and I also read more of the SerialPort.BaseStream documentation where it explicitly notes that Length, Position, Seek and SetLength are not supported in the BaseStream instance.

    • Edited by Andrew B. Painter Tuesday, October 6, 2020 3:23 PM
    • Marked as answer by G-Oker Thursday, October 8, 2020 6:07 AM
    Tuesday, October 6, 2020 3:00 PM
  • Apologies for giving people guess work. it was not my intention.

    I took your lineterm words to heart, and dug around the inital raw data again , and I believe the correct terminator is \r. Ive applied this to the readto, and it seems to be working (why is didnt before when I tried I do not know).

    Thank you all for you help and guidance.


     

    Wednesday, October 7, 2020 2:00 PM
  • Hi,

    Has your issue been resolved?

    If so, please click on the "Mark as answer" option of the reply that solved your question, so that it will help other members to find the solution quickly if they face a similar issue.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, October 8, 2020 1:50 AM