diff options
Diffstat (limited to 'vendor/go.mau.fi/whatsmeow/binary/xml.go')
-rw-r--r-- | vendor/go.mau.fi/whatsmeow/binary/xml.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/whatsmeow/binary/xml.go b/vendor/go.mau.fi/whatsmeow/binary/xml.go new file mode 100644 index 00000000..0f411890 --- /dev/null +++ b/vendor/go.mau.fi/whatsmeow/binary/xml.go @@ -0,0 +1,108 @@ +// Copyright (c) 2021 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package binary + +import ( + "encoding/hex" + "fmt" + "sort" + "strings" + "unicode" + "unicode/utf8" +) + +// Options to control how Node.XMLString behaves. +var ( + IndentXML = false + MaxBytesToPrintAsHex = 128 +) + +// XMLString converts the Node to its XML representation +func (n *Node) XMLString() string { + content := n.contentString() + if len(content) == 0 { + return fmt.Sprintf("<%[1]s%[2]s/>", n.Tag, n.attributeString()) + } + newline := "\n" + if len(content) == 1 || !IndentXML { + newline = "" + } + return fmt.Sprintf("<%[1]s%[2]s>%[4]s%[3]s%[4]s</%[1]s>", n.Tag, n.attributeString(), strings.Join(content, newline), newline) +} + +func (n *Node) attributeString() string { + if len(n.Attrs) == 0 { + return "" + } + stringAttrs := make([]string, len(n.Attrs)+1) + i := 1 + for key, value := range n.Attrs { + stringAttrs[i] = fmt.Sprintf(`%s="%v"`, key, value) + i++ + } + sort.Strings(stringAttrs) + return strings.Join(stringAttrs, " ") +} + +func printable(data []byte) string { + if !utf8.Valid(data) { + return "" + } + str := string(data) + for _, c := range str { + if !unicode.IsPrint(c) { + return "" + } + } + return str +} + +func (n *Node) contentString() []string { + split := make([]string, 0) + switch content := n.Content.(type) { + case []Node: + for _, item := range content { + split = append(split, strings.Split(item.XMLString(), "\n")...) + } + case []byte: + if strContent := printable(content); len(strContent) > 0 { + if IndentXML { + split = append(split, strings.Split(string(content), "\n")...) + } else { + split = append(split, strings.ReplaceAll(string(content), "\n", "\\n")) + } + } else if len(content) > MaxBytesToPrintAsHex { + split = append(split, fmt.Sprintf("<!-- %d bytes -->", len(content))) + } else if !IndentXML { + split = append(split, hex.EncodeToString(content)) + } else { + hexData := hex.EncodeToString(content) + for i := 0; i < len(hexData); i += 80 { + if len(hexData) < i+80 { + split = append(split, hexData[i:]) + } else { + split = append(split, hexData[i:i+80]) + } + } + } + case nil: + // don't append anything + default: + strContent := fmt.Sprintf("%s", content) + if IndentXML { + split = append(split, strings.Split(strContent, "\n")...) + } else { + split = append(split, strings.ReplaceAll(strContent, "\n", "\\n")) + } + } + if len(split) > 1 && IndentXML { + for i, line := range split { + split[i] = " " + line + } + } + return split +} |