Skip to content

Instantly share code, notes, and snippets.

@Ice3man543
Last active August 19, 2018 00:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ice3man543/e462bec952947910ac2e71dad4956f37 to your computer and use it in GitHub Desktop.
Save Ice3man543/e462bec952947910ac2e71dad4956f37 to your computer and use it in GitHub Desktop.
Workspace format serialize/Deserialize
// Written by ice3man
package main
import (
"bytes"
"compress/gzip"
"encoding/base64"
"encoding/gob"
"fmt"
"io"
"os"
"strings"
)
type NodeType int
const (
NodeTypeHostname NodeType = iota
NodeTypeIP
NodeTypeContent
)
type Database struct {
Root *Node
}
type Node struct {
Type NodeType
Value interface{}
Relations []*Node
}
func (t NodeType) String() string {
switch t {
case NodeTypeHostname:
return "host"
case NodeTypeIP:
return "ip"
case NodeTypeContent:
return "content"
}
return "???"
}
func space(counter int) string { return strings.Repeat("\t", counter) }
func (n *Node) PrintNode(relation bool, counter *int) {
if relation == false {
fmt.Printf("\n%s[ROOT_NODE] %s=>%s Relations: %d", space(*counter), n.Type.String(), n.Value, len(n.Relations))
} else {
fmt.Printf("\n%s[RELATION] %s=>%s Relations: %d", space(*counter), n.Type.String(), n.Value, len(n.Relations))
}
if len(n.Relations) > 0 {
n.PrintRelations((*counter + 1))
}
}
func (n *Node) PrintRelations(counter int) {
for i := 0; i < len(n.Relations); i++ {
n.Relations[i].PrintNode(true, &counter)
}
}
func (n *Node) PrintDatabase() {
counter := 0
n.PrintNode(false, &counter)
}
func main() {
db := Database{Root: &Node{Type: NodeTypeHostname, Value: "google.com"}}
db.Root.Relations = append(db.Root.Relations, &Node{Type: NodeTypeIP, Value: "10.10.10.70"})
db.Root.Relations = append(db.Root.Relations, &Node{Type: NodeTypeIP, Value: "10.10.10.71"})
db.Root.Relations = append(db.Root.Relations, &Node{Type: NodeTypeIP, Value: "10.10.10.72"})
db.Root.Relations[2].Relations = append(db.Root.Relations[2].Relations, &Node{Type: NodeTypeContent, Value: "/.git"})
db.Root.Relations = append(db.Root.Relations, &Node{Type: NodeTypeIP, Value: "10.10.10.73"})
fmt.Printf("[ORIGINAL] %v\n", db)
db.Root.PrintDatabase()
serialized := Base64GobEncode(db)
fmt.Printf("\n\n[SERIALIZED] Len: %d\n%v\n", len(serialized), serialized)
result, _ := gZipData([]byte(serialized))
fmt.Printf("\n\n[SERIALIZED_GZIPPED] Len: %d\n%v\n", len(result), string(result))
de_result, _ := gUnzipData(result)
var p1 = Database{}
_ = Base64GobDecode(string(de_result), &p1)
p1.Root.PrintDatabase()
fmt.Printf("\n[DESERIALIZED] %v\n", p1)
}
func Base64GobEncode(object interface{}) string {
b := bytes.Buffer{}
encoder := gob.NewEncoder(&b)
err := encoder.Encode(object)
if err != nil {
fmt.Printf("\nencode: %v", err)
os.Exit(1)
}
return base64.StdEncoding.EncodeToString(b.Bytes())
}
func Base64GobDecode(data string, object interface{}) error {
by, _ := base64.StdEncoding.DecodeString(data)
b := bytes.Buffer{}
b.Write(by)
decoder := gob.NewDecoder(&b)
err := decoder.Decode(object)
if err != nil {
fmt.Printf("\ndecode: %v", err)
os.Exit(1)
}
return nil
}
func gUnzipData(data []byte) (resData []byte, err error) {
b := bytes.NewBuffer(data)
var r io.Reader
r, err = gzip.NewReader(b)
if err != nil {
return
}
var resB bytes.Buffer
_, err = resB.ReadFrom(r)
if err != nil {
return
}
resData = resB.Bytes()
return
}
func gZipData(data []byte) (compressedData []byte, err error) {
var b bytes.Buffer
gz := gzip.NewWriter(&b)
_, err = gz.Write(data)
if err != nil {
return
}
if err = gz.Flush(); err != nil {
return
}
if err = gz.Close(); err != nil {
return
}
compressedData = b.Bytes()
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment