1
0
mirror of https://github.com/sjwhitworth/golearn.git synced 2025-04-25 13:48:49 +08:00
golearn/base/serialize_attributes.go
2017-09-10 20:35:34 +01:00

137 lines
3.3 KiB
Go

package base
import (
"archive/tar"
"encoding/json"
"fmt"
)
func writeAttributesToFilePart(attrs []Attribute, f *tar.Writer, name string) error {
// Get the marshaled Attribute array
body, err := json.Marshal(attrs)
if err != nil {
return err
}
// Write a header
hdr := &tar.Header{
Name: name,
Size: int64(len(body)),
}
if err := f.WriteHeader(hdr); err != nil {
return err
}
// Write the marshaled data
if _, err := f.Write([]byte(body)); err != nil {
return err
}
return nil
}
// MarshalAttribute converts an Attribute to a JSON map.
func MarshalAttribute(a Attribute) (map[string]interface{}, error) {
ret := make(map[string]interface{})
marshaledAttrRaw, err := a.MarshalJSON()
if err != nil {
return nil, err
}
err = json.Unmarshal(marshaledAttrRaw, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
func SerializeAttribute(attr Attribute) ([]byte, error) {
// Get the marshaled Attribute array
body, err := json.Marshal(attr)
if err != nil {
return nil, err
}
return []byte(body), nil
}
func DeserializeAttribute(data []byte) (Attribute, error) {
type JSONAttribute struct {
Type string `json:"type"`
Name string `json:"name"`
Attr json.RawMessage `json:"attr"`
}
var rawAttr JSONAttribute
err := json.Unmarshal(data, &rawAttr)
if err != nil {
return nil, err
}
var attr Attribute
switch rawAttr.Type {
case "binary":
attr = new(BinaryAttribute)
break
case "float":
attr = new(FloatAttribute)
break
case "categorical":
attr = new(CategoricalAttribute)
break
default:
return nil, fmt.Errorf("Unrecognised Attribute format: %s", rawAttr.Type)
}
err = attr.UnmarshalJSON(rawAttr.Attr)
if err != nil {
return nil, fmt.Errorf("Can't deserialize: %s (error: %s)", rawAttr, err)
}
attr.SetName(rawAttr.Name)
return attr, nil
}
// DeserializeAttributes constructs a ve
func DeserializeAttributes(data []byte) ([]Attribute, error) {
// Define a JSON shim Attribute
var attrs []json.RawMessage
err := json.Unmarshal(data, &attrs)
if err != nil {
return nil, fmt.Errorf("Failed to deserialize attributes: %v", err)
}
ret := make([]Attribute, len(attrs))
for i, v := range attrs {
ret[i], err = DeserializeAttribute(v)
if err != nil {
return nil, err
}
}
return ret, nil
}
// ReplaceDeserializedAttributeWithVersionFromInstances takes an independently deserialized Attribute and matches it
// if possible with one from a candidate FixedDataGrid.
func ReplaceDeserializedAttributeWithVersionFromInstances(deserialized Attribute, matchingWith FixedDataGrid) (Attribute, error) {
for _, a := range matchingWith.AllAttributes() {
if a.Equals(deserialized) {
return a, nil
}
}
return nil, WrapError(fmt.Errorf("Unable to match %v in %v", deserialized, matchingWith))
}
// ReplaceDeserializedAttributesWithVersionsFromInstances takes some independently loaded Attributes and
// matches them up with a candidate FixedDataGrid.
func ReplaceDeserializedAttributesWithVersionsFromInstances(deserialized []Attribute, matchingWith FixedDataGrid) ([]Attribute, error) {
ret := make([]Attribute, len(deserialized))
for i, a := range deserialized {
match, err := ReplaceDeserializedAttributeWithVersionFromInstances(a, matchingWith)
if err != nil {
return nil, WrapError(err)
}
ret[i] = match
}
return ret, nil
}