// Copyright (C) 2014 The Syncthing Authors. // // 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 https://mozilla.org/MPL/2.0/. package config import ( "encoding/json" "encoding/xml" "sort" "github.com/syncthing/syncthing/lib/fs" "github.com/syncthing/syncthing/lib/structutil" ) // internalVersioningConfiguration is used in XML serialization type internalVersioningConfiguration struct { Type string `xml:"type,attr,omitempty"` Params []internalParam `xml:"param"` CleanupIntervalS int `xml:"cleanupIntervalS" default:"3600"` FSPath string `xml:"fsPath"` FSType fs.FilesystemType `xml:"fsType"` } type internalParam struct { Key string `xml:"key,attr"` Val string `xml:"val,attr"` } func (c VersioningConfiguration) Copy() VersioningConfiguration { cp := c cp.Params = make(map[string]string, len(c.Params)) for k, v := range c.Params { cp.Params[k] = v } return cp } func (c *VersioningConfiguration) UnmarshalJSON(data []byte) error { structutil.SetDefaults(c) type noCustomUnmarshal VersioningConfiguration ptr := (*noCustomUnmarshal)(c) return json.Unmarshal(data, ptr) } func (c *VersioningConfiguration) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { var intCfg internalVersioningConfiguration structutil.SetDefaults(&intCfg) if err := d.DecodeElement(&intCfg, &start); err != nil { return err } c.fromInternal(intCfg) return nil } func (c VersioningConfiguration) MarshalXML(e *xml.Encoder, start xml.StartElement) error { // Using EncodeElement instead of plain Encode ensures that we use the // outer tag name from the VersioningConfiguration (i.e., // ``) rather than whatever the internal representation // would otherwise be. return e.EncodeElement(c.toInternal(), start) } func (c *VersioningConfiguration) toInternal() internalVersioningConfiguration { var tmp internalVersioningConfiguration tmp.Type = c.Type tmp.CleanupIntervalS = c.CleanupIntervalS tmp.FSPath = c.FSPath tmp.FSType = c.FSType for k, v := range c.Params { tmp.Params = append(tmp.Params, internalParam{k, v}) } sort.Slice(tmp.Params, func(a, b int) bool { return tmp.Params[a].Key < tmp.Params[b].Key }) return tmp } func (c *VersioningConfiguration) fromInternal(intCfg internalVersioningConfiguration) { c.Type = intCfg.Type c.CleanupIntervalS = intCfg.CleanupIntervalS c.FSPath = intCfg.FSPath c.FSType = intCfg.FSType c.Params = make(map[string]string, len(intCfg.Params)) for _, p := range intCfg.Params { c.Params[p.Key] = p.Val } }