Documentation
¶
Overview ¶
Data Encoding and Decoding entails the protection of data characters from corruption after being rendered as a PSV table, and restoring the original data from a PSV table.
Encoding
- leading and trailing spaces need to be escaped
- '|' needs to be escaped
- '\' needs to be escaped
- <tab> needs to be replaced with '\t'
- fields need to be encoded separately, in order to calculate the correct column widths
- encoding is only done on raw data (i.e. individual fields)
- field padding (column alignment) only takes place on encoded fields
- after encoding and padding, rows need to be joined as an extra step
Decoding
- un-escaped '|' starts a new field
- leading and trailing _escaped spaces_ need to be preserved
- leading and trailing _unescaped spaces_ need to be trimmed
- (don't use strings.TrimSpace)
- '\t' needs to be replaced with <tab>
- '\|' needs to be replaced with '|'
- '\\' needs to be replaced with '\'
- decoding always implies splitting and trimming
Example (Encode_decode) ¶
package main import ( "bytes" "fmt" "strings" "codeberg.org/japh/psv/encoding/row" "codeberg.org/japh/psv/model" ) func main() { testRows := [][]string{ []string{"plain text", "foo", "bar"}, []string{"pipes", "|", "a|1", "|foo", "bar|"}, []string{"tabs", "\tfoo|\t|bar\t"}, // with real tabs []string{"esc tabs", "\t", "\\t", "\\\t", "\\\\t"}, []string{`esc pipes`, `|`, `\|`, `\\|`, `\\\|`}, } // helper rowString := func(row []string) string { line := `[` + strings.Join(row, `] [`) + `]` return strings.Replace(line, "\t", "<tab>", -1) } enc := &row.Encoder{} dec := &row.Decoder{} for _, testRow := range testRows { fmt.Println("---") fmt.Printf("Input: %s\n", rowString(testRow)) encRow := row.EncodeData(testRow) fmt.Printf("Encoded: %s\n", rowString(encRow)) cws := make([]model.ColumnWidth, len(testRow)) // no padding cfs := make([]model.ColumnFlags, len(testRow)) // default column alignment joinedRow := &bytes.Buffer{} enc.Join(joinedRow, encRow, cws, cfs) fmt.Printf("Joined: [%s]\n", joinedRow.String()) decRow := dec.SplitAndDecode(joinedRow.String()) fmt.Printf("Decoded: %s\n", rowString(decRow)) } // Note: tabs are displayed as "<tab>" in the output below }
Output: --- Input: [plain text] [foo] [bar] Encoded: [plain text] [foo] [bar] Joined: [| plain text | foo | bar |] Decoded: [plain text] [foo] [bar] --- Input: [pipes] [|] [a|1] [|foo] [bar|] Encoded: [pipes] [\|] [a\|1] [\|foo] [bar\|] Joined: [| pipes | \| | a\|1 | \|foo | bar\| |] Decoded: [pipes] [|] [a|1] [|foo] [bar|] --- Input: [tabs] [<tab>foo|<tab>|bar<tab>] Encoded: [tabs] [\tfoo\|\t\|bar\t] Joined: [| tabs | \tfoo\|\t\|bar\t |] Decoded: [tabs] [<tab>foo|<tab>|bar<tab>] --- Input: [esc tabs] [<tab>] [\t] [\<tab>] [\\t] Encoded: [esc tabs] [\t] [\\t] [\\\t] [\\\\t] Joined: [| esc tabs | \t | \\t | \\\t | \\\\t |] Decoded: [esc tabs] [<tab>] [\t] [\<tab>] [\\t] --- Input: [esc pipes] [|] [\|] [\\|] [\\\|] Encoded: [esc pipes] [\|] [\\\|] [\\\\\|] [\\\\\\\|] Joined: [| esc pipes | \| | \\\| | \\\\\| | \\\\\\\| |] Decoded: [esc pipes] [|] [\|] [\\|] [\\\|]
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EncodeData ¶
EncodeData escapes all '|' characters in a row's fields.
func Pad ¶
func Pad(field string, cw model.ColumnWidth, cf model.ColumnFlags) string
Types ¶
type Decoder ¶
type Decoder struct{}
func (*Decoder) SplitAndDecode ¶
SplitAndDecode splits an input line into a row of fields IF the row begins with a '|' character.
All of the data returned will have had any escape characters removed
type Encoder ¶
type Encoder struct{}
func (*Encoder) Join ¶
func (enc *Encoder) Join( buf *bytes.Buffer, row []string, cws []model.ColumnWidth, cfs []model.ColumnFlags, )
Join appends a data row to the provided bytes.Buffer
- a []model.ColumnAligner slice is required to ensure that all rows have the same dimensions
- the []string slice should have been encoded via EncodeData prior to preparation of the ColumnAligner slice
- if no ColumnAligner slice is provided, a single empty column will be added with a width of 1, enough for rulers to define their horizontal line character
Click to show internal directories.
Click to hide internal directories.