Merge pull request #217 from alixander/encoding

compress + decompress
This commit is contained in:
Alexander Wang 2022-11-25 19:29:25 -08:00 committed by GitHub
commit b13629fe8f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 94 additions and 0 deletions

67
lib/compress/compress.go Normal file
View file

@ -0,0 +1,67 @@
package compress
import (
"bytes"
"compress/flate"
"encoding/base64"
"io"
"strings"
"oss.terrastruct.com/d2/d2graph"
)
var compressionDict = "->" +
"<-" +
"--" +
"<->"
var compressionDictBytes []byte
// Compress takes a D2 script and compresses it to a URL-encoded string
func Compress(raw string) (string, error) {
var b bytes.Buffer
zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(compressionDict))
if err != nil {
return "", err
}
if _, err := io.Copy(zw, strings.NewReader(raw)); err != nil {
return "", err
}
if err := zw.Close(); err != nil {
return "", err
}
encoded := base64.URLEncoding.EncodeToString(b.Bytes())
return encoded, nil
}
// Decompress takes a compressed, URL-encoded string and returns the decompressed D2 script
func Decompress(encoded string) (string, error) {
b64Decoded, err := base64.URLEncoding.DecodeString(encoded)
if err != nil {
return "", err
}
zr := flate.NewReaderDict(bytes.NewReader(b64Decoded), []byte(compressionDict))
var b bytes.Buffer
if _, err := io.Copy(&b, zr); err != nil {
return "", err
}
if err := zr.Close(); err != nil {
return "", nil
}
return b.String(), nil
}
func init() {
for k := range d2graph.StyleKeywords {
compressionDict += k
}
for k := range d2graph.ReservedKeywords {
compressionDict += k
}
for k := range d2graph.ReservedKeywordHolders {
compressionDict += k
}
}

View file

@ -0,0 +1,27 @@
package compress
import (
"testing"
"oss.terrastruct.com/diff"
)
func TestCompression(t *testing.T) {
script := `x -> y
I just forgot my whole philosophy of life!!!: {
s: TV is chewing gum for the eyes
}
`
encoded, err := Compress(script)
if err != nil {
t.Fatal(err)
}
decoded, err := Decompress(encoded)
if err != nil {
t.Fatal(err)
}
diff.AssertStringEq(t, script, decoded)
}