Handle delimiter in read message

15 views
Skip to first unread message

mike

unread,
May 23, 2022, 2:09:48 AMMay 23
to
Hi,

We receive a message called "chunked message" in NETCONF.
Example:

final String MSG_REPLY = "#877\r\n"
+
"<rpc-reply message-id=\"1\" xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><data xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\"><listen><endpoint><name>default-ssh</name><ssh><tcp-server-parameters><local-address>0.0.0.0</local-address><keepalives><idle-time>1</idle-time><max-probes>10</max-probes><probe-interval>5</probe-interval></keepalives></tcp-server-parameters><ssh-server-parameters><server-identity><host-key><name>default-key</name><public-key><keystore-reference>genkey</keystore-reference></public-key></host-key></server-identity><client-authentication><supported-authentication-methods><publickey/><passsword/><other>interactive</other></supported-authentication-methods><users/></client-authentication></ssh-server-parameters></ssh></endpoint></listen></netconf-server></data></rpc-reply>\r\n"
+
"##\r\n";

I tried:

String newline = System.getProperty("line.separator");//make sure I get newline for platform.
return sb.toString().contains(newline + "##" + newline);

But it fails. Is it possible to check if the string ends with a regex pattern?

//mike

mike

unread,
May 23, 2022, 5:32:07 AMMay 23
to
I even checked the ASCII in my buffer.

ASCII numbers is:

10 LF
35 #
35 #
10 LF

I changed my regexp:

sb.toString().matches("(?s).*\\r\\n|\\n##\\r\\n|\\n$")

but it still evaluates to false. I suspect it is DOT ALL that gives me the headache.

//mike

mike

unread,
May 23, 2022, 6:00:06 AMMay 23
to
Even tried this to make sure I have only four last characters of my string.

String endofMsg = sb.toString().substring(sb.toString().length() - 4);

return endofMsg.matches("^\\r\\n|[\\n]##\\r\\n|[\\n]$");

mike

unread,
May 23, 2022, 7:34:50 AMMay 23
to
I found out I can do:

String endofMsg = sb.toString().substring(sb.toString().length() - 6);
return endofMsg.matches("\\r\\n##\\r\\n|.*\\n##\\n$");

I had to use the last 6 characters since newline is different for each platform.

//mike

e.d.pro...@gmail.com

unread,
May 23, 2022, 9:31:21 AMMay 23
to
> I found out I can do:
>
> String endofMsg = sb.toString().substring(sb.toString().length() - 6);
> return endofMsg.matches("\\r\\n##\\r\\n|.*\\n##\\n$");
>
> I had to use the last 6 characters since newline is different for each platform.
>
> //mike

I'm not clear what is the problem you're trying to solve, but System.getProperty("line.separator") is system dependent, so if you're running that on one system to get a value to use on a different system, your value will be wrong if the systems are different. *nix uses \n for linefeed, Windows uses \r\n , so you're checking for the presence of \n if you want to check for a linefeed.

Eric Sosman

unread,
May 23, 2022, 10:34:00 AMMay 23
to
Also (if I recall correctly), various Internet RFC's require CR-LF
line terminators, regardless of the system sending the lines. I don't
know whether mike's messages follow such a protocol, but many do.

His best bet may be to recognize all of CR, LF, and CR-LF as line
terminators, and maybe even LF-CR as well.

--
eso...@comcast-dot-net.invalid
Look on my code, ye Hackers, and guffaw!

--
This email has been checked for viruses by AVG.
https://www.avg.com

Arne Vajhøj

unread,
May 23, 2022, 11:21:28 AMMay 23
to
>> Even tried this to make sure I have only four last characters of my string.
>>
>> String endofMsg = sb.toString().substring(sb.toString().length() - 4);
>>
>> return endofMsg.matches("^\\r\\n|[\\n]##\\r\\n|[\\n]$");
>
> I found out I can do:
>
> String endofMsg = sb.toString().substring(sb.toString().length() - 6);
> return endofMsg.matches("\\r\\n##\\r\\n|.*\\n##\\n$");
>
> I had to use the last 6 characters since newline is different for each platform.

This seems to work:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class EndTest {
private static final Pattern re =
Pattern.compile("^#\\d+\\v+(.*)##\\v+$", Pattern.MULTILINE +
Pattern.DOTALL);
public static void test(String s) {
System.out.println(s);
Matcher m = re.matcher(s);
if(m.find()) {
System.out.println("Match: " + m.group(1));
} else {
System.out.println("No match");
}
}
public static void main(String[] args) {
test("ABC");
String msg = "#877\r\n"
+
"<rpc-reply message-id=\"1\"
xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><data
xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><netconf-server
xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\"><listen><endpoint><name>default-ssh</name><ssh><tcp-server-parameters><local-address>0.0.0.0</local-address><keepalives><idle-time>1</idle-time><max-probes>10</max-probes><probe-interval>5</probe-interval></keepalives></tcp-server-parameters><ssh-server-parameters><server-identity><host-key><name>default-key</name><public-key><keystore-reference>genkey</keystore-reference></public-key></host-key></server-identity><client-authentication><supported-authentication-methods><publickey/><passsword/><other>interactive</other></supported-authentication-methods><users/></client-authentication></ssh-server-parameters></ssh></endpoint></listen></netconf-server></data></rpc-reply>\r\n"

+
"##\r\n";
test(msg);
}
}

Arne

Stanimir Stamenkov

unread,
Jun 7, 2022, 4:19:31 PMJun 7
to
Mon, 23 May 2022 02:31:59 -0700 (PDT), /mike/:

> I changed my regexp:
>
> sb.toString().matches("(?s).*\\r\\n|\\n##\\r\\n|\\n$")
>
> but it still evaluates to false. I suspect it is DOT ALL that gives me the headache.

Maybe you really mean (note the grouping):

sb.toString().matches("(?s).*(\\r\\n|\\n##\\r\\n|\\n)$")

or even:

sb.toString().matches("(?s).*\\r?\\n(##\\r?\\n?)?$")

--
Stanimir
Reply all
Reply to author
Forward
0 new messages