buffer

package
v1.1.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 12, 2023 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Example (Mixed_writes)
testCases := []struct {
	startMode, endMode OutputMode
}{
	{UnsafeEscaped, SafeEscaped},
	{SafeEscaped, UnsafeEscaped},
	{UnsafeEscaped, SafeRaw},
	{SafeRaw, UnsafeEscaped},
	{SafeEscaped, SafeRaw},
	{SafeRaw, SafeEscaped},
}

doWritesFn := []func(*Buffer){
	// Noop
	func(b *Buffer) {},
	func(b *Buffer) { b.WriteByte('a') },
	func(b *Buffer) { b.WriteRune('a') },
	func(b *Buffer) { b.WriteString("bc") },
	func(b *Buffer) { b.Write([]byte("bc")) },
	func(b *Buffer) { b.WriteString("safe‹unsafe›") },
	func(b *Buffer) { b.WriteByte('\n') },
	func(b *Buffer) { b.WriteRune('\n') },
	func(b *Buffer) { b.WriteString("\nx\ny\n") },
	func(b *Buffer) { b.Write([]byte("\nx\ny\n")) },
}

for i, tc := range testCases {
	if i > 0 {
		fmt.Println()
	}
	fmt.Println(tc.startMode, " -> ", tc.endMode)
	for j, doWrites := range doWritesFn {
		var b Buffer
		b.SetMode(tc.startMode)
		doWrites(&b)
		for k, doWrites2 := range doWritesFn {
			copy := b.clone()
			copy.SetMode(tc.endMode)
			doWrites2(copy)
			var b2 Buffer
			b2.SetMode(tc.endMode)
			doWrites2(&b2)
			fmt.Printf("fn%d+fn%d: %q   (%q + %q)\n", j, k, copy.RedactableString(), b.RedactableString(), b2.RedactableString())
		}
	}
}
Output:

0  ->  1
fn0+fn0: ""   ("" + "")
fn0+fn1: "a"   ("" + "a")
fn0+fn2: "a"   ("" + "a")
fn0+fn3: "bc"   ("" + "bc")
fn0+fn4: "bc"   ("" + "bc")
fn0+fn5: "safe?unsafe?"   ("" + "safe?unsafe?")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\nx\ny\n"   ("" + "\nx\ny\n")
fn0+fn9: "\nx\ny\n"   ("" + "\nx\ny\n")
fn1+fn0: "‹a›"   ("‹a›" + "")
fn1+fn1: "‹a›a"   ("‹a›" + "a")
fn1+fn2: "‹a›a"   ("‹a›" + "a")
fn1+fn3: "‹a›bc"   ("‹a›" + "bc")
fn1+fn4: "‹a›bc"   ("‹a›" + "bc")
fn1+fn5: "‹a›safe?unsafe?"   ("‹a›" + "safe?unsafe?")
fn1+fn6: "‹a›\n"   ("‹a›" + "\n")
fn1+fn7: "‹a›\n"   ("‹a›" + "\n")
fn1+fn8: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn1+fn9: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn2+fn0: "‹a›"   ("‹a›" + "")
fn2+fn1: "‹a›a"   ("‹a›" + "a")
fn2+fn2: "‹a›a"   ("‹a›" + "a")
fn2+fn3: "‹a›bc"   ("‹a›" + "bc")
fn2+fn4: "‹a›bc"   ("‹a›" + "bc")
fn2+fn5: "‹a›safe?unsafe?"   ("‹a›" + "safe?unsafe?")
fn2+fn6: "‹a›\n"   ("‹a›" + "\n")
fn2+fn7: "‹a›\n"   ("‹a›" + "\n")
fn2+fn8: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn2+fn9: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn3+fn0: "‹bc›"   ("‹bc›" + "")
fn3+fn1: "‹bc›a"   ("‹bc›" + "a")
fn3+fn2: "‹bc›a"   ("‹bc›" + "a")
fn3+fn3: "‹bc›bc"   ("‹bc›" + "bc")
fn3+fn4: "‹bc›bc"   ("‹bc›" + "bc")
fn3+fn5: "‹bc›safe?unsafe?"   ("‹bc›" + "safe?unsafe?")
fn3+fn6: "‹bc›\n"   ("‹bc›" + "\n")
fn3+fn7: "‹bc›\n"   ("‹bc›" + "\n")
fn3+fn8: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn3+fn9: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn4+fn0: "‹bc›"   ("‹bc›" + "")
fn4+fn1: "‹bc›a"   ("‹bc›" + "a")
fn4+fn2: "‹bc›a"   ("‹bc›" + "a")
fn4+fn3: "‹bc›bc"   ("‹bc›" + "bc")
fn4+fn4: "‹bc›bc"   ("‹bc›" + "bc")
fn4+fn5: "‹bc›safe?unsafe?"   ("‹bc›" + "safe?unsafe?")
fn4+fn6: "‹bc›\n"   ("‹bc›" + "\n")
fn4+fn7: "‹bc›\n"   ("‹bc›" + "\n")
fn4+fn8: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn4+fn9: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn5+fn0: "‹safe?unsafe?›"   ("‹safe?unsafe?›" + "")
fn5+fn1: "‹safe?unsafe?›a"   ("‹safe?unsafe?›" + "a")
fn5+fn2: "‹safe?unsafe?›a"   ("‹safe?unsafe?›" + "a")
fn5+fn3: "‹safe?unsafe?›bc"   ("‹safe?unsafe?›" + "bc")
fn5+fn4: "‹safe?unsafe?›bc"   ("‹safe?unsafe?›" + "bc")
fn5+fn5: "‹safe?unsafe?›safe?unsafe?"   ("‹safe?unsafe?›" + "safe?unsafe?")
fn5+fn6: "‹safe?unsafe?›\n"   ("‹safe?unsafe?›" + "\n")
fn5+fn7: "‹safe?unsafe?›\n"   ("‹safe?unsafe?›" + "\n")
fn5+fn8: "‹safe?unsafe?›\nx\ny\n"   ("‹safe?unsafe?›" + "\nx\ny\n")
fn5+fn9: "‹safe?unsafe?›\nx\ny\n"   ("‹safe?unsafe?›" + "\nx\ny\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\na"   ("\n" + "a")
fn6+fn2: "\na"   ("\n" + "a")
fn6+fn3: "\nbc"   ("\n" + "bc")
fn6+fn4: "\nbc"   ("\n" + "bc")
fn6+fn5: "\nsafe?unsafe?"   ("\n" + "safe?unsafe?")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn6+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\na"   ("\n" + "a")
fn7+fn2: "\na"   ("\n" + "a")
fn7+fn3: "\nbc"   ("\n" + "bc")
fn7+fn4: "\nbc"   ("\n" + "bc")
fn7+fn5: "\nsafe?unsafe?"   ("\n" + "safe?unsafe?")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn8+fn0: "\n‹x›\n‹y›\n"   ("\n‹x›\n‹y›\n" + "")
fn8+fn1: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn8+fn2: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn8+fn3: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn8+fn4: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn8+fn5: "\n‹x›\n‹y›\nsafe?unsafe?"   ("\n‹x›\n‹y›\n" + "safe?unsafe?")
fn8+fn6: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn8+fn7: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn8+fn8: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn8+fn9: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn9+fn0: "\n‹x›\n‹y›\n"   ("\n‹x›\n‹y›\n" + "")
fn9+fn1: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn9+fn2: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn9+fn3: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn9+fn4: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn9+fn5: "\n‹x›\n‹y›\nsafe?unsafe?"   ("\n‹x›\n‹y›\n" + "safe?unsafe?")
fn9+fn6: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn9+fn7: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn9+fn8: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn9+fn9: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")

1  ->  0
fn0+fn0: ""   ("" + "")
fn0+fn1: "‹a›"   ("" + "‹a›")
fn0+fn2: "‹a›"   ("" + "‹a›")
fn0+fn3: "‹bc›"   ("" + "‹bc›")
fn0+fn4: "‹bc›"   ("" + "‹bc›")
fn0+fn5: "‹safe?unsafe?›"   ("" + "‹safe?unsafe?›")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\n‹x›\n‹y›\n"   ("" + "\n‹x›\n‹y›\n")
fn0+fn9: "\n‹x›\n‹y›\n"   ("" + "\n‹x›\n‹y›\n")
fn1+fn0: "a"   ("a" + "")
fn1+fn1: "a‹a›"   ("a" + "‹a›")
fn1+fn2: "a‹a›"   ("a" + "‹a›")
fn1+fn3: "a‹bc›"   ("a" + "‹bc›")
fn1+fn4: "a‹bc›"   ("a" + "‹bc›")
fn1+fn5: "a‹safe?unsafe?›"   ("a" + "‹safe?unsafe?›")
fn1+fn6: "a\n"   ("a" + "\n")
fn1+fn7: "a\n"   ("a" + "\n")
fn1+fn8: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn1+fn9: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn2+fn0: "a"   ("a" + "")
fn2+fn1: "a‹a›"   ("a" + "‹a›")
fn2+fn2: "a‹a›"   ("a" + "‹a›")
fn2+fn3: "a‹bc›"   ("a" + "‹bc›")
fn2+fn4: "a‹bc›"   ("a" + "‹bc›")
fn2+fn5: "a‹safe?unsafe?›"   ("a" + "‹safe?unsafe?›")
fn2+fn6: "a\n"   ("a" + "\n")
fn2+fn7: "a\n"   ("a" + "\n")
fn2+fn8: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn2+fn9: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn3+fn0: "bc"   ("bc" + "")
fn3+fn1: "bc‹a›"   ("bc" + "‹a›")
fn3+fn2: "bc‹a›"   ("bc" + "‹a›")
fn3+fn3: "bc‹bc›"   ("bc" + "‹bc›")
fn3+fn4: "bc‹bc›"   ("bc" + "‹bc›")
fn3+fn5: "bc‹safe?unsafe?›"   ("bc" + "‹safe?unsafe?›")
fn3+fn6: "bc\n"   ("bc" + "\n")
fn3+fn7: "bc\n"   ("bc" + "\n")
fn3+fn8: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn3+fn9: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn4+fn0: "bc"   ("bc" + "")
fn4+fn1: "bc‹a›"   ("bc" + "‹a›")
fn4+fn2: "bc‹a›"   ("bc" + "‹a›")
fn4+fn3: "bc‹bc›"   ("bc" + "‹bc›")
fn4+fn4: "bc‹bc›"   ("bc" + "‹bc›")
fn4+fn5: "bc‹safe?unsafe?›"   ("bc" + "‹safe?unsafe?›")
fn4+fn6: "bc\n"   ("bc" + "\n")
fn4+fn7: "bc\n"   ("bc" + "\n")
fn4+fn8: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn4+fn9: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn5+fn0: "safe?unsafe?"   ("safe?unsafe?" + "")
fn5+fn1: "safe?unsafe?‹a›"   ("safe?unsafe?" + "‹a›")
fn5+fn2: "safe?unsafe?‹a›"   ("safe?unsafe?" + "‹a›")
fn5+fn3: "safe?unsafe?‹bc›"   ("safe?unsafe?" + "‹bc›")
fn5+fn4: "safe?unsafe?‹bc›"   ("safe?unsafe?" + "‹bc›")
fn5+fn5: "safe?unsafe?‹safe?unsafe?›"   ("safe?unsafe?" + "‹safe?unsafe?›")
fn5+fn6: "safe?unsafe?\n"   ("safe?unsafe?" + "\n")
fn5+fn7: "safe?unsafe?\n"   ("safe?unsafe?" + "\n")
fn5+fn8: "safe?unsafe?\n‹x›\n‹y›\n"   ("safe?unsafe?" + "\n‹x›\n‹y›\n")
fn5+fn9: "safe?unsafe?\n‹x›\n‹y›\n"   ("safe?unsafe?" + "\n‹x›\n‹y›\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\n‹a›"   ("\n" + "‹a›")
fn6+fn2: "\n‹a›"   ("\n" + "‹a›")
fn6+fn3: "\n‹bc›"   ("\n" + "‹bc›")
fn6+fn4: "\n‹bc›"   ("\n" + "‹bc›")
fn6+fn5: "\n‹safe?unsafe?›"   ("\n" + "‹safe?unsafe?›")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn6+fn9: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\n‹a›"   ("\n" + "‹a›")
fn7+fn2: "\n‹a›"   ("\n" + "‹a›")
fn7+fn3: "\n‹bc›"   ("\n" + "‹bc›")
fn7+fn4: "\n‹bc›"   ("\n" + "‹bc›")
fn7+fn5: "\n‹safe?unsafe?›"   ("\n" + "‹safe?unsafe?›")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn7+fn9: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn8+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn8+fn1: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn8+fn2: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn8+fn3: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn8+fn4: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn8+fn5: "\nx\ny\n‹safe?unsafe?›"   ("\nx\ny\n" + "‹safe?unsafe?›")
fn8+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn8: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn8+fn9: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn9+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn9+fn1: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn9+fn2: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn9+fn3: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn9+fn4: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn9+fn5: "\nx\ny\n‹safe?unsafe?›"   ("\nx\ny\n" + "‹safe?unsafe?›")
fn9+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn8: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn9+fn9: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")

0  ->  2
fn0+fn0: ""   ("" + "")
fn0+fn1: "a"   ("" + "a")
fn0+fn2: "a"   ("" + "a")
fn0+fn3: "bc"   ("" + "bc")
fn0+fn4: "bc"   ("" + "bc")
fn0+fn5: "safe‹unsafe›"   ("" + "safe‹unsafe›")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\nx\ny\n"   ("" + "\nx\ny\n")
fn0+fn9: "\nx\ny\n"   ("" + "\nx\ny\n")
fn1+fn0: "‹a›"   ("‹a›" + "")
fn1+fn1: "‹a›a"   ("‹a›" + "a")
fn1+fn2: "‹a›a"   ("‹a›" + "a")
fn1+fn3: "‹a›bc"   ("‹a›" + "bc")
fn1+fn4: "‹a›bc"   ("‹a›" + "bc")
fn1+fn5: "‹a›safe‹unsafe›"   ("‹a›" + "safe‹unsafe›")
fn1+fn6: "‹a›\n"   ("‹a›" + "\n")
fn1+fn7: "‹a›\n"   ("‹a›" + "\n")
fn1+fn8: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn1+fn9: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn2+fn0: "‹a›"   ("‹a›" + "")
fn2+fn1: "‹a›a"   ("‹a›" + "a")
fn2+fn2: "‹a›a"   ("‹a›" + "a")
fn2+fn3: "‹a›bc"   ("‹a›" + "bc")
fn2+fn4: "‹a›bc"   ("‹a›" + "bc")
fn2+fn5: "‹a›safe‹unsafe›"   ("‹a›" + "safe‹unsafe›")
fn2+fn6: "‹a›\n"   ("‹a›" + "\n")
fn2+fn7: "‹a›\n"   ("‹a›" + "\n")
fn2+fn8: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn2+fn9: "‹a›\nx\ny\n"   ("‹a›" + "\nx\ny\n")
fn3+fn0: "‹bc›"   ("‹bc›" + "")
fn3+fn1: "‹bc›a"   ("‹bc›" + "a")
fn3+fn2: "‹bc›a"   ("‹bc›" + "a")
fn3+fn3: "‹bc›bc"   ("‹bc›" + "bc")
fn3+fn4: "‹bc›bc"   ("‹bc›" + "bc")
fn3+fn5: "‹bc›safe‹unsafe›"   ("‹bc›" + "safe‹unsafe›")
fn3+fn6: "‹bc›\n"   ("‹bc›" + "\n")
fn3+fn7: "‹bc›\n"   ("‹bc›" + "\n")
fn3+fn8: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn3+fn9: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn4+fn0: "‹bc›"   ("‹bc›" + "")
fn4+fn1: "‹bc›a"   ("‹bc›" + "a")
fn4+fn2: "‹bc›a"   ("‹bc›" + "a")
fn4+fn3: "‹bc›bc"   ("‹bc›" + "bc")
fn4+fn4: "‹bc›bc"   ("‹bc›" + "bc")
fn4+fn5: "‹bc›safe‹unsafe›"   ("‹bc›" + "safe‹unsafe›")
fn4+fn6: "‹bc›\n"   ("‹bc›" + "\n")
fn4+fn7: "‹bc›\n"   ("‹bc›" + "\n")
fn4+fn8: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn4+fn9: "‹bc›\nx\ny\n"   ("‹bc›" + "\nx\ny\n")
fn5+fn0: "‹safe?unsafe?›"   ("‹safe?unsafe?›" + "")
fn5+fn1: "‹safe?unsafe?›a"   ("‹safe?unsafe?›" + "a")
fn5+fn2: "‹safe?unsafe?›a"   ("‹safe?unsafe?›" + "a")
fn5+fn3: "‹safe?unsafe?›bc"   ("‹safe?unsafe?›" + "bc")
fn5+fn4: "‹safe?unsafe?›bc"   ("‹safe?unsafe?›" + "bc")
fn5+fn5: "‹safe?unsafe?›safe‹unsafe›"   ("‹safe?unsafe?›" + "safe‹unsafe›")
fn5+fn6: "‹safe?unsafe?›\n"   ("‹safe?unsafe?›" + "\n")
fn5+fn7: "‹safe?unsafe?›\n"   ("‹safe?unsafe?›" + "\n")
fn5+fn8: "‹safe?unsafe?›\nx\ny\n"   ("‹safe?unsafe?›" + "\nx\ny\n")
fn5+fn9: "‹safe?unsafe?›\nx\ny\n"   ("‹safe?unsafe?›" + "\nx\ny\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\na"   ("\n" + "a")
fn6+fn2: "\na"   ("\n" + "a")
fn6+fn3: "\nbc"   ("\n" + "bc")
fn6+fn4: "\nbc"   ("\n" + "bc")
fn6+fn5: "\nsafe‹unsafe›"   ("\n" + "safe‹unsafe›")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn6+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\na"   ("\n" + "a")
fn7+fn2: "\na"   ("\n" + "a")
fn7+fn3: "\nbc"   ("\n" + "bc")
fn7+fn4: "\nbc"   ("\n" + "bc")
fn7+fn5: "\nsafe‹unsafe›"   ("\n" + "safe‹unsafe›")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn8+fn0: "\n‹x›\n‹y›\n"   ("\n‹x›\n‹y›\n" + "")
fn8+fn1: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn8+fn2: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn8+fn3: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn8+fn4: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn8+fn5: "\n‹x›\n‹y›\nsafe‹unsafe›"   ("\n‹x›\n‹y›\n" + "safe‹unsafe›")
fn8+fn6: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn8+fn7: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn8+fn8: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn8+fn9: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn9+fn0: "\n‹x›\n‹y›\n"   ("\n‹x›\n‹y›\n" + "")
fn9+fn1: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn9+fn2: "\n‹x›\n‹y›\na"   ("\n‹x›\n‹y›\n" + "a")
fn9+fn3: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn9+fn4: "\n‹x›\n‹y›\nbc"   ("\n‹x›\n‹y›\n" + "bc")
fn9+fn5: "\n‹x›\n‹y›\nsafe‹unsafe›"   ("\n‹x›\n‹y›\n" + "safe‹unsafe›")
fn9+fn6: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn9+fn7: "\n‹x›\n‹y›\n\n"   ("\n‹x›\n‹y›\n" + "\n")
fn9+fn8: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")
fn9+fn9: "\n‹x›\n‹y›\n\nx\ny\n"   ("\n‹x›\n‹y›\n" + "\nx\ny\n")

2  ->  0
fn0+fn0: ""   ("" + "")
fn0+fn1: "‹a›"   ("" + "‹a›")
fn0+fn2: "‹a›"   ("" + "‹a›")
fn0+fn3: "‹bc›"   ("" + "‹bc›")
fn0+fn4: "‹bc›"   ("" + "‹bc›")
fn0+fn5: "‹safe?unsafe?›"   ("" + "‹safe?unsafe?›")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\n‹x›\n‹y›\n"   ("" + "\n‹x›\n‹y›\n")
fn0+fn9: "\n‹x›\n‹y›\n"   ("" + "\n‹x›\n‹y›\n")
fn1+fn0: "a"   ("a" + "")
fn1+fn1: "a‹a›"   ("a" + "‹a›")
fn1+fn2: "a‹a›"   ("a" + "‹a›")
fn1+fn3: "a‹bc›"   ("a" + "‹bc›")
fn1+fn4: "a‹bc›"   ("a" + "‹bc›")
fn1+fn5: "a‹safe?unsafe?›"   ("a" + "‹safe?unsafe?›")
fn1+fn6: "a\n"   ("a" + "\n")
fn1+fn7: "a\n"   ("a" + "\n")
fn1+fn8: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn1+fn9: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn2+fn0: "a"   ("a" + "")
fn2+fn1: "a‹a›"   ("a" + "‹a›")
fn2+fn2: "a‹a›"   ("a" + "‹a›")
fn2+fn3: "a‹bc›"   ("a" + "‹bc›")
fn2+fn4: "a‹bc›"   ("a" + "‹bc›")
fn2+fn5: "a‹safe?unsafe?›"   ("a" + "‹safe?unsafe?›")
fn2+fn6: "a\n"   ("a" + "\n")
fn2+fn7: "a\n"   ("a" + "\n")
fn2+fn8: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn2+fn9: "a\n‹x›\n‹y›\n"   ("a" + "\n‹x›\n‹y›\n")
fn3+fn0: "bc"   ("bc" + "")
fn3+fn1: "bc‹a›"   ("bc" + "‹a›")
fn3+fn2: "bc‹a›"   ("bc" + "‹a›")
fn3+fn3: "bc‹bc›"   ("bc" + "‹bc›")
fn3+fn4: "bc‹bc›"   ("bc" + "‹bc›")
fn3+fn5: "bc‹safe?unsafe?›"   ("bc" + "‹safe?unsafe?›")
fn3+fn6: "bc\n"   ("bc" + "\n")
fn3+fn7: "bc\n"   ("bc" + "\n")
fn3+fn8: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn3+fn9: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn4+fn0: "bc"   ("bc" + "")
fn4+fn1: "bc‹a›"   ("bc" + "‹a›")
fn4+fn2: "bc‹a›"   ("bc" + "‹a›")
fn4+fn3: "bc‹bc›"   ("bc" + "‹bc›")
fn4+fn4: "bc‹bc›"   ("bc" + "‹bc›")
fn4+fn5: "bc‹safe?unsafe?›"   ("bc" + "‹safe?unsafe?›")
fn4+fn6: "bc\n"   ("bc" + "\n")
fn4+fn7: "bc\n"   ("bc" + "\n")
fn4+fn8: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn4+fn9: "bc\n‹x›\n‹y›\n"   ("bc" + "\n‹x›\n‹y›\n")
fn5+fn0: "safe‹unsafe›"   ("safe‹unsafe›" + "")
fn5+fn1: "safe‹unsafea›"   ("safe‹unsafe›" + "‹a›")
fn5+fn2: "safe‹unsafea›"   ("safe‹unsafe›" + "‹a›")
fn5+fn3: "safe‹unsafebc›"   ("safe‹unsafe›" + "‹bc›")
fn5+fn4: "safe‹unsafebc›"   ("safe‹unsafe›" + "‹bc›")
fn5+fn5: "safe‹unsafesafe?unsafe?›"   ("safe‹unsafe›" + "‹safe?unsafe?›")
fn5+fn6: "safe‹unsafe›\n"   ("safe‹unsafe›" + "\n")
fn5+fn7: "safe‹unsafe›\n"   ("safe‹unsafe›" + "\n")
fn5+fn8: "safe‹unsafe›\n‹x›\n‹y›\n"   ("safe‹unsafe›" + "\n‹x›\n‹y›\n")
fn5+fn9: "safe‹unsafe›\n‹x›\n‹y›\n"   ("safe‹unsafe›" + "\n‹x›\n‹y›\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\n‹a›"   ("\n" + "‹a›")
fn6+fn2: "\n‹a›"   ("\n" + "‹a›")
fn6+fn3: "\n‹bc›"   ("\n" + "‹bc›")
fn6+fn4: "\n‹bc›"   ("\n" + "‹bc›")
fn6+fn5: "\n‹safe?unsafe?›"   ("\n" + "‹safe?unsafe?›")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn6+fn9: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\n‹a›"   ("\n" + "‹a›")
fn7+fn2: "\n‹a›"   ("\n" + "‹a›")
fn7+fn3: "\n‹bc›"   ("\n" + "‹bc›")
fn7+fn4: "\n‹bc›"   ("\n" + "‹bc›")
fn7+fn5: "\n‹safe?unsafe?›"   ("\n" + "‹safe?unsafe?›")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn7+fn9: "\n\n‹x›\n‹y›\n"   ("\n" + "\n‹x›\n‹y›\n")
fn8+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn8+fn1: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn8+fn2: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn8+fn3: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn8+fn4: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn8+fn5: "\nx\ny\n‹safe?unsafe?›"   ("\nx\ny\n" + "‹safe?unsafe?›")
fn8+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn8: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn8+fn9: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn9+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn9+fn1: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn9+fn2: "\nx\ny\n‹a›"   ("\nx\ny\n" + "‹a›")
fn9+fn3: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn9+fn4: "\nx\ny\n‹bc›"   ("\nx\ny\n" + "‹bc›")
fn9+fn5: "\nx\ny\n‹safe?unsafe?›"   ("\nx\ny\n" + "‹safe?unsafe?›")
fn9+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn8: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")
fn9+fn9: "\nx\ny\n\n‹x›\n‹y›\n"   ("\nx\ny\n" + "\n‹x›\n‹y›\n")

1  ->  2
fn0+fn0: ""   ("" + "")
fn0+fn1: "a"   ("" + "a")
fn0+fn2: "a"   ("" + "a")
fn0+fn3: "bc"   ("" + "bc")
fn0+fn4: "bc"   ("" + "bc")
fn0+fn5: "safe‹unsafe›"   ("" + "safe‹unsafe›")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\nx\ny\n"   ("" + "\nx\ny\n")
fn0+fn9: "\nx\ny\n"   ("" + "\nx\ny\n")
fn1+fn0: "a"   ("a" + "")
fn1+fn1: "aa"   ("a" + "a")
fn1+fn2: "aa"   ("a" + "a")
fn1+fn3: "abc"   ("a" + "bc")
fn1+fn4: "abc"   ("a" + "bc")
fn1+fn5: "asafe‹unsafe›"   ("a" + "safe‹unsafe›")
fn1+fn6: "a\n"   ("a" + "\n")
fn1+fn7: "a\n"   ("a" + "\n")
fn1+fn8: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn1+fn9: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn2+fn0: "a"   ("a" + "")
fn2+fn1: "aa"   ("a" + "a")
fn2+fn2: "aa"   ("a" + "a")
fn2+fn3: "abc"   ("a" + "bc")
fn2+fn4: "abc"   ("a" + "bc")
fn2+fn5: "asafe‹unsafe›"   ("a" + "safe‹unsafe›")
fn2+fn6: "a\n"   ("a" + "\n")
fn2+fn7: "a\n"   ("a" + "\n")
fn2+fn8: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn2+fn9: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn3+fn0: "bc"   ("bc" + "")
fn3+fn1: "bca"   ("bc" + "a")
fn3+fn2: "bca"   ("bc" + "a")
fn3+fn3: "bcbc"   ("bc" + "bc")
fn3+fn4: "bcbc"   ("bc" + "bc")
fn3+fn5: "bcsafe‹unsafe›"   ("bc" + "safe‹unsafe›")
fn3+fn6: "bc\n"   ("bc" + "\n")
fn3+fn7: "bc\n"   ("bc" + "\n")
fn3+fn8: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn3+fn9: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn4+fn0: "bc"   ("bc" + "")
fn4+fn1: "bca"   ("bc" + "a")
fn4+fn2: "bca"   ("bc" + "a")
fn4+fn3: "bcbc"   ("bc" + "bc")
fn4+fn4: "bcbc"   ("bc" + "bc")
fn4+fn5: "bcsafe‹unsafe›"   ("bc" + "safe‹unsafe›")
fn4+fn6: "bc\n"   ("bc" + "\n")
fn4+fn7: "bc\n"   ("bc" + "\n")
fn4+fn8: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn4+fn9: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn5+fn0: "safe?unsafe?"   ("safe?unsafe?" + "")
fn5+fn1: "safe?unsafe?a"   ("safe?unsafe?" + "a")
fn5+fn2: "safe?unsafe?a"   ("safe?unsafe?" + "a")
fn5+fn3: "safe?unsafe?bc"   ("safe?unsafe?" + "bc")
fn5+fn4: "safe?unsafe?bc"   ("safe?unsafe?" + "bc")
fn5+fn5: "safe?unsafe?safe‹unsafe›"   ("safe?unsafe?" + "safe‹unsafe›")
fn5+fn6: "safe?unsafe?\n"   ("safe?unsafe?" + "\n")
fn5+fn7: "safe?unsafe?\n"   ("safe?unsafe?" + "\n")
fn5+fn8: "safe?unsafe?\nx\ny\n"   ("safe?unsafe?" + "\nx\ny\n")
fn5+fn9: "safe?unsafe?\nx\ny\n"   ("safe?unsafe?" + "\nx\ny\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\na"   ("\n" + "a")
fn6+fn2: "\na"   ("\n" + "a")
fn6+fn3: "\nbc"   ("\n" + "bc")
fn6+fn4: "\nbc"   ("\n" + "bc")
fn6+fn5: "\nsafe‹unsafe›"   ("\n" + "safe‹unsafe›")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn6+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\na"   ("\n" + "a")
fn7+fn2: "\na"   ("\n" + "a")
fn7+fn3: "\nbc"   ("\n" + "bc")
fn7+fn4: "\nbc"   ("\n" + "bc")
fn7+fn5: "\nsafe‹unsafe›"   ("\n" + "safe‹unsafe›")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn8+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn8+fn1: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn8+fn2: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn8+fn3: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn8+fn4: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn8+fn5: "\nx\ny\nsafe‹unsafe›"   ("\nx\ny\n" + "safe‹unsafe›")
fn8+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn8: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn8+fn9: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn9+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn9+fn1: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn9+fn2: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn9+fn3: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn9+fn4: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn9+fn5: "\nx\ny\nsafe‹unsafe›"   ("\nx\ny\n" + "safe‹unsafe›")
fn9+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn8: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn9+fn9: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")

2  ->  1
fn0+fn0: ""   ("" + "")
fn0+fn1: "a"   ("" + "a")
fn0+fn2: "a"   ("" + "a")
fn0+fn3: "bc"   ("" + "bc")
fn0+fn4: "bc"   ("" + "bc")
fn0+fn5: "safe?unsafe?"   ("" + "safe?unsafe?")
fn0+fn6: "\n"   ("" + "\n")
fn0+fn7: "\n"   ("" + "\n")
fn0+fn8: "\nx\ny\n"   ("" + "\nx\ny\n")
fn0+fn9: "\nx\ny\n"   ("" + "\nx\ny\n")
fn1+fn0: "a"   ("a" + "")
fn1+fn1: "aa"   ("a" + "a")
fn1+fn2: "aa"   ("a" + "a")
fn1+fn3: "abc"   ("a" + "bc")
fn1+fn4: "abc"   ("a" + "bc")
fn1+fn5: "asafe?unsafe?"   ("a" + "safe?unsafe?")
fn1+fn6: "a\n"   ("a" + "\n")
fn1+fn7: "a\n"   ("a" + "\n")
fn1+fn8: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn1+fn9: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn2+fn0: "a"   ("a" + "")
fn2+fn1: "aa"   ("a" + "a")
fn2+fn2: "aa"   ("a" + "a")
fn2+fn3: "abc"   ("a" + "bc")
fn2+fn4: "abc"   ("a" + "bc")
fn2+fn5: "asafe?unsafe?"   ("a" + "safe?unsafe?")
fn2+fn6: "a\n"   ("a" + "\n")
fn2+fn7: "a\n"   ("a" + "\n")
fn2+fn8: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn2+fn9: "a\nx\ny\n"   ("a" + "\nx\ny\n")
fn3+fn0: "bc"   ("bc" + "")
fn3+fn1: "bca"   ("bc" + "a")
fn3+fn2: "bca"   ("bc" + "a")
fn3+fn3: "bcbc"   ("bc" + "bc")
fn3+fn4: "bcbc"   ("bc" + "bc")
fn3+fn5: "bcsafe?unsafe?"   ("bc" + "safe?unsafe?")
fn3+fn6: "bc\n"   ("bc" + "\n")
fn3+fn7: "bc\n"   ("bc" + "\n")
fn3+fn8: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn3+fn9: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn4+fn0: "bc"   ("bc" + "")
fn4+fn1: "bca"   ("bc" + "a")
fn4+fn2: "bca"   ("bc" + "a")
fn4+fn3: "bcbc"   ("bc" + "bc")
fn4+fn4: "bcbc"   ("bc" + "bc")
fn4+fn5: "bcsafe?unsafe?"   ("bc" + "safe?unsafe?")
fn4+fn6: "bc\n"   ("bc" + "\n")
fn4+fn7: "bc\n"   ("bc" + "\n")
fn4+fn8: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn4+fn9: "bc\nx\ny\n"   ("bc" + "\nx\ny\n")
fn5+fn0: "safe‹unsafe›"   ("safe‹unsafe›" + "")
fn5+fn1: "safe‹unsafe›a"   ("safe‹unsafe›" + "a")
fn5+fn2: "safe‹unsafe›a"   ("safe‹unsafe›" + "a")
fn5+fn3: "safe‹unsafe›bc"   ("safe‹unsafe›" + "bc")
fn5+fn4: "safe‹unsafe›bc"   ("safe‹unsafe›" + "bc")
fn5+fn5: "safe‹unsafe›safe?unsafe?"   ("safe‹unsafe›" + "safe?unsafe?")
fn5+fn6: "safe‹unsafe›\n"   ("safe‹unsafe›" + "\n")
fn5+fn7: "safe‹unsafe›\n"   ("safe‹unsafe›" + "\n")
fn5+fn8: "safe‹unsafe›\nx\ny\n"   ("safe‹unsafe›" + "\nx\ny\n")
fn5+fn9: "safe‹unsafe›\nx\ny\n"   ("safe‹unsafe›" + "\nx\ny\n")
fn6+fn0: "\n"   ("\n" + "")
fn6+fn1: "\na"   ("\n" + "a")
fn6+fn2: "\na"   ("\n" + "a")
fn6+fn3: "\nbc"   ("\n" + "bc")
fn6+fn4: "\nbc"   ("\n" + "bc")
fn6+fn5: "\nsafe?unsafe?"   ("\n" + "safe?unsafe?")
fn6+fn6: "\n\n"   ("\n" + "\n")
fn6+fn7: "\n\n"   ("\n" + "\n")
fn6+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn6+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn0: "\n"   ("\n" + "")
fn7+fn1: "\na"   ("\n" + "a")
fn7+fn2: "\na"   ("\n" + "a")
fn7+fn3: "\nbc"   ("\n" + "bc")
fn7+fn4: "\nbc"   ("\n" + "bc")
fn7+fn5: "\nsafe?unsafe?"   ("\n" + "safe?unsafe?")
fn7+fn6: "\n\n"   ("\n" + "\n")
fn7+fn7: "\n\n"   ("\n" + "\n")
fn7+fn8: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn7+fn9: "\n\nx\ny\n"   ("\n" + "\nx\ny\n")
fn8+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn8+fn1: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn8+fn2: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn8+fn3: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn8+fn4: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn8+fn5: "\nx\ny\nsafe?unsafe?"   ("\nx\ny\n" + "safe?unsafe?")
fn8+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn8+fn8: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn8+fn9: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn9+fn0: "\nx\ny\n"   ("\nx\ny\n" + "")
fn9+fn1: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn9+fn2: "\nx\ny\na"   ("\nx\ny\n" + "a")
fn9+fn3: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn9+fn4: "\nx\ny\nbc"   ("\nx\ny\n" + "bc")
fn9+fn5: "\nx\ny\nsafe?unsafe?"   ("\nx\ny\n" + "safe?unsafe?")
fn9+fn6: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn7: "\nx\ny\n\n"   ("\nx\ny\n" + "\n")
fn9+fn8: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
fn9+fn9: "\nx\ny\n\nx\ny\n"   ("\nx\ny\n" + "\nx\ny\n")
Example (Newlines)
var b Buffer
b.SetMode(UnsafeEscaped)
b.WriteString("a\n")
fmt.Printf("%q\n", b.RedactableBytes())
Output:

"‹a›\n"

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrTooLarge = origFmt.Errorf("redact.Buffer: too large")

ErrTooLarge is passed to panic if memory cannot be allocated to store data in a buffer.

Functions

This section is empty.

Types

type Buffer

type Buffer struct {
	// contains filtered or unexported fields
}

Buffer is a variable-sized buffer of bytes with a Write method. Writes are escaped in different ways depending on the output mode.

func (*Buffer) Cap

func (b *Buffer) Cap() int

Cap returns the capacity of the buffer's underlying byte slice, that is, the total space allocated for the buffer's data.

func (*Buffer) GetMode

func (b *Buffer) GetMode() OutputMode

GetMode retrieves the output mode.

func (*Buffer) Grow

func (b *Buffer) Grow(n int)

Grow grows the buffer's capacity, if necessary, to guarantee space for another n bytes. After Grow(n), at least n bytes can be written to the buffer without another allocation. If n is negative, Grow will panic. If the buffer can't grow it will panic with ErrTooLarge.

func (*Buffer) Len

func (b *Buffer) Len() int

Len returns the number of bytes in the buffer.

func (Buffer) RedactableBytes

func (b Buffer) RedactableBytes() m.RedactableBytes

RedactableBytes returns the bytes in the buffer.

func (Buffer) RedactableString

func (b Buffer) RedactableString() m.RedactableString

RedactableString returns the bytes in the buffer.

func (*Buffer) Reset

func (b *Buffer) Reset()

Reset resets the buffer to be empty, but it retains the underlying storage for use by future writes. It also resets the output mode to UnsafeEscaped.

func (*Buffer) SetMode

func (b *Buffer) SetMode(newMode OutputMode)

SetMode changes the output mode.

func (Buffer) String

func (b Buffer) String() string

String implemens fmt.Stringer.

func (*Buffer) TakeRedactableBytes

func (b *Buffer) TakeRedactableBytes() m.RedactableBytes

TakeRedactableBytes returns the buffer contents and reinitializes the buffer. This saves a memory allocation compared to RedactableBytes().

func (*Buffer) TakeRedactableString

func (b *Buffer) TakeRedactableString() m.RedactableString

TakeRedactableString returns the buffer contents and reinitializes the buffer. This saves a memory allocation compared to RedactableString().

func (*Buffer) Write

func (b *Buffer) Write(p []byte) (n int, err error)

Write appends the contents of p to the buffer, growing the buffer as needed. The return value n is the length of p; err is always nil. If the buffer becomes too large, Write will panic with ErrTooLarge.

func (*Buffer) WriteByte

func (b *Buffer) WriteByte(s byte) error

WriteByte emits a single byte.

func (*Buffer) WriteRune

func (b *Buffer) WriteRune(s rune) error

WriteRune emits a single rune.

func (*Buffer) WriteString

func (b *Buffer) WriteString(s string) (n int, err error)

WriteString appends the contents of s to the buffer, growing the buffer as needed. The return value n is the length of s; err is always nil. If the buffer becomes too large, WriteString will panic with ErrTooLarge.

type OutputMode

type OutputMode int

OutputMode determines how writes are processed in the Buffer.

const (
	// UnsafeEscaped says that written data is unsafe for reporting,
	// so it should be enclosed in redaction markers,
	// and may contain redaction markers itself, and so it should be escaped.
	UnsafeEscaped OutputMode = iota
	// SafeEscaped says that written data is safe for reporting
	// (should not be enclosed in redaction markers) but may itself
	// contain redaction markers, and so it should be escaped.
	SafeEscaped
	// SafeRaw says that written data is safe for reporting
	// (should not be enclosed in redaction markers) and is
	// guaranteed not to contain redaction markers, so it
	// needs not be escaped.
	SafeRaw
	// PreRedactable says that written data already contains a mixed
	// of safe and unsafe information with suitably placed redaction markers,
	// and so should be inlined.
	PreRedactable = SafeRaw
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL