@@ -456,6 +456,11 @@ func isNumeric(s string) (bool, int) {
456
456
return true , p
457
457
}
458
458
459
+ var (
460
+ bstrExp = regexp .MustCompile (`_x[a-zA-Z\d]{4}_` )
461
+ bstrEscapeExp = regexp .MustCompile (`x[a-zA-Z\d]{4}_` )
462
+ )
463
+
459
464
// bstrUnmarshal parses the binary basic string, this will trim escaped string
460
465
// literal which not permitted in an XML 1.0 document. The basic string
461
466
// variant type can store any valid Unicode character. Unicode characters
@@ -468,15 +473,13 @@ func isNumeric(s string) (bool, int) {
468
473
// initial underscore shall itself be escaped (i.e. stored as _x005F_). For
469
474
// example: The string literal _x0008_ would be stored as _x005F_x0008_.
470
475
func bstrUnmarshal (s string ) (result string ) {
471
- bstrExp := regexp .MustCompile (`_x[a-zA-Z0-9]{4}_` )
472
- escapeExp := regexp .MustCompile (`x[a-zA-Z0-9]{4}_` )
473
476
matches , l , cursor := bstrExp .FindAllStringSubmatchIndex (s , - 1 ), len (s ), 0
474
477
for _ , match := range matches {
475
478
result += s [cursor :match [0 ]]
476
479
subStr := s [match [0 ]:match [1 ]]
477
480
if subStr == "_x005F_" {
478
481
cursor = match [1 ]
479
- if l > match [1 ]+ 6 && ! escapeExp .MatchString (s [match [1 ]:match [1 ]+ 6 ]) {
482
+ if l > match [1 ]+ 6 && ! bstrEscapeExp .MatchString (s [match [1 ]:match [1 ]+ 6 ]) {
480
483
result += subStr
481
484
continue
482
485
}
@@ -487,7 +490,7 @@ func bstrUnmarshal(s string) (result string) {
487
490
cursor = match [1 ]
488
491
v , err := strconv .Unquote (`"\u` + s [match [0 ]+ 2 :match [1 ]- 1 ] + `"` )
489
492
if err != nil {
490
- if l > match [1 ]+ 6 && escapeExp .MatchString (s [match [1 ]:match [1 ]+ 6 ]) {
493
+ if l > match [1 ]+ 6 && bstrEscapeExp .MatchString (s [match [1 ]:match [1 ]+ 6 ]) {
491
494
result += subStr [:6 ]
492
495
cursor = match [1 ] + 6
493
496
continue
@@ -512,6 +515,41 @@ func bstrUnmarshal(s string) (result string) {
512
515
return result
513
516
}
514
517
518
+ // bstrMarshal encode the escaped string literal which not permitted in an XML
519
+ // 1.0 document.
520
+ func bstrMarshal (s string ) (result string ) {
521
+ matches , l , cursor := bstrExp .FindAllStringSubmatchIndex (s , - 1 ), len (s ), 0
522
+ for _ , match := range matches {
523
+ result += s [cursor :match [0 ]]
524
+ subStr := s [match [0 ]:match [1 ]]
525
+ if subStr == "_x005F_" {
526
+ cursor = match [1 ]
527
+ if match [1 ]+ 6 <= l && bstrEscapeExp .MatchString (s [match [1 ]:match [1 ]+ 6 ]) {
528
+ _ , err := strconv .Unquote (`"\u` + s [match [1 ]+ 1 :match [1 ]+ 5 ] + `"` )
529
+ if err == nil {
530
+ result += subStr + "x005F" + subStr
531
+ continue
532
+ }
533
+ }
534
+ result += subStr + "x005F_"
535
+ continue
536
+ }
537
+ if bstrExp .MatchString (subStr ) {
538
+ cursor = match [1 ]
539
+ _ , err := strconv .Unquote (`"\u` + s [match [0 ]+ 2 :match [1 ]- 1 ] + `"` )
540
+ if err == nil {
541
+ result += "_x005F" + subStr
542
+ continue
543
+ }
544
+ result += subStr
545
+ }
546
+ }
547
+ if cursor < l {
548
+ result += s [cursor :]
549
+ }
550
+ return result
551
+ }
552
+
515
553
// Stack defined an abstract data type that serves as a collection of elements.
516
554
type Stack struct {
517
555
list * list.List
0 commit comments