diff --git a/sds/text.go b/sds/text.go index 8b135c9..23153d8 100644 --- a/sds/text.go +++ b/sds/text.go @@ -2,6 +2,7 @@ package sds import ( "fmt" + "regexp" "time" "golang.org/x/text/encoding" @@ -190,3 +191,36 @@ func AppendEncodedPayloadText(bytes []byte, bits int, text string, textEncoding bits += encodedBits return bytes, bits } + +var leadingOPTA = regexp.MustCompile(`^[A-Za-z ]+#[0-9]{16}`) + +func SplitLeadingOPTA(s string) (string, string) { + opta := leadingOPTA.FindString(s) + return opta, s[len(opta):] +} + +func RemoveLeadingOPTA(s string) string { + _, result := SplitLeadingOPTA(s) + return result +} + +var trailingITSI = regexp.MustCompile(`((\x1a\x00)|(\x0d\x0d))([0-9]{16})$`) + +func SplitTrailingITSI(s string) (string, string) { + groups := trailingITSI.FindStringSubmatch(s) + var itsi string + var matchLen int + if len(groups) == 0 { + itsi = "" + matchLen = 0 + } else { + itsi = groups[len(groups)-1] + matchLen = len(groups[0]) + } + return s[0 : len(s)-matchLen], itsi +} + +func RemoveTrailingITSI(s string) string { + result, _ := SplitTrailingITSI(s) + return result +} diff --git a/sds/text_test.go b/sds/text_test.go new file mode 100644 index 0000000..ba12ae8 --- /dev/null +++ b/sds/text_test.go @@ -0,0 +1,77 @@ +package sds + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestSplitLeadingOPTA(t *testing.T) { + tt := []struct { + desc string + value string + expectedOPTA string + expectedTail string + }{ + { + desc: "no OPTA", + value: "testmessage", + expectedOPTA: "", + expectedTail: "testmessage", + }, + { + desc: "only OPTA", + value: "ABCD FG#1234567890123456", + expectedOPTA: "ABCD FG#1234567890123456", + expectedTail: "", + }, + { + desc: "OPTA and tail", + value: "ABCD FG#1234567890123456testmessage", + expectedOPTA: "ABCD FG#1234567890123456", + expectedTail: "testmessage", + }, + } + for _, tc := range tt { + t.Run(tc.desc, func(t *testing.T) { + actualOPTA, actualTail := SplitLeadingOPTA(tc.value) + assert.Equal(t, tc.expectedOPTA, actualOPTA) + assert.Equal(t, tc.expectedTail, actualTail) + }) + } +} + +func TestSplitTrailingITSI(t *testing.T) { + tt := []struct { + desc string + value string + expectedHead string + expectedITSI string + }{ + { + desc: "no ITSI", + value: "testmessage", + expectedHead: "testmessage", + expectedITSI: "", + }, + { + desc: "cr cr", + value: "testmessage\r\r1234567890123456", + expectedHead: "testmessage", + expectedITSI: "1234567890123456", + }, + { + desc: "ctrl-z nul", + value: "testmessage\x1a\x001234567890123456", + expectedHead: "testmessage", + expectedITSI: "1234567890123456", + }, + } + for _, tc := range tt { + t.Run(tc.desc, func(t *testing.T) { + actualHead, actualITSI := SplitTrailingITSI(tc.value) + assert.Equal(t, tc.expectedHead, actualHead) + assert.Equal(t, tc.expectedITSI, actualITSI) + }) + } +}