<commit_before>package client

import (
    "fmt"
    "sort"
    "strings"
    "encoding/xml"
)

type Preset struct {
    ID          int     `json:"id" xml:"id,attr"`
    Name        string  `json:"Name"`
    LockMode    int     `json:"LockMode"`
    Sno         float64 `json:"presetSno" xml:"presetSno"`
}

func (preset Preset) ParseOrder() (group int, index int) {
    // one awesome hack
    sno := strings.Trim(fmt.Sprintf("%f", preset.Sno), "0")

    if _, err := fmt.Sscanf(sno, "%d.%d", &group, &index); err != nil {
        // 0.0 is invalid..
        return 0, 0
    }

    return
}

// Filtering
const listPresetsExclude = -2
const listPresetsInclude = -1

type listPresets struct {
    ScreenDest  int     `json:"ScreenDest"`
    AuxDest     int     `json:"AuxDest"`
}

// Default is to return all presets
func (client *Client) ListPresets() (presetList []Preset, err error) {
    request := Request{
        Method:     "listPresets",
        Params:     struct{}{},
    }

    if err := client.doResult(&request, &presetList); err != nil {
        return nil, err
    } else {
        return presetList, nil
    }
}

func (client *Client) ListPresetsX(screenID int, auxID int) (presetList []Preset, err error) {
    request := Request{
        Method:     "listPresets",
        Params:     listPresets{
            ScreenDest:     screenID,
            AuxDest:        auxID,
        },
    }

    if err := client.doResult(&request, &presetList); err != nil {
        return nil, err
    } else {
        return presetList, nil
    }
}

// Preset Destinations
type PresetAuxDest struct {
    ID      int     `json:"id"`
}
type PresetScreenDest struct {
    ID      int     `json:"id"`
}

type PresetDestinations struct {
    Preset

    AuxDest     []PresetAuxDest     `json:"AuxDest"`
    ScreenDest  []PresetScreenDest  `json:"ScreenDest"`
}

type listDestinationsForPreset struct {
    ID      int     `json:"id"`
}

func (client *Client) ListDestinationsForPreset(presetID int) (result PresetDestinations, err error) {
    if presetID < 0 {
        return result, fmt.Errorf("Invalid Preset ID: %v", presetID)
    }

    request := Request{
        Method:     "listDestinationsForPreset",
        Params:     listDestinationsForPreset{
            ID:     presetID,
        },
    }

    if err := client.doResult(&request, &result); err != nil {
        return result, err
    } else {
        return result, nil
    }
}

// XML
type PresetCol map[int]Preset

// unmarshal each <Preset> separately
// TODO: this is not as efficient, since we COW the PresetCol map on every Preset...
func (col *PresetCol) UnmarshalXML(d *xml.Decoder, e xml.StartElement) error {
    return unmarshalXMLItem(col, d, e)
}

func (col PresetCol) MarshalJSON() ([]byte, error) {
    return marshalJSONMap(col)
}

func (col PresetCol) List() (items []Preset) {
    var keys []int

    for key, _ := range col {
        keys = append(keys, key)
    }

    sort.Ints(keys)

    for _, key := range keys {
        items = append(items, col[key])
    }

    return items
}

type PresetMgr struct {
    ID          int             `xml:"id,attr"`

    LastRecall  int             `xml:"LastRecall"`

    Preset      PresetCol       `xml:"Preset"`
}<commit_msg>client: fix PresetMgr <Add> <Remove> XML unmarshalling<commit_after>package client

import (
    "fmt"
    "sort"
    "strings"
    "encoding/xml"
)

type Preset struct {
    ID          int     `json:"id" xml:"id,attr"`
    Name        string  `json:"Name"`
    LockMode    int     `json:"LockMode"`
    Sno         float64 `json:"presetSno" xml:"presetSno"`
}

func (preset Preset) ParseOrder() (group int, index int) {
    // one awesome hack
    sno := strings.Trim(fmt.Sprintf("%f", preset.Sno), "0")

    if _, err := fmt.Sscanf(sno, "%d.%d", &group, &index); err != nil {
        // 0.0 is invalid..
        return 0, 0
    }

    return
}

// Filtering
const listPresetsExclude = -2
const listPresetsInclude = -1

type listPresets struct {
    ScreenDest  int     `json:"ScreenDest"`
    AuxDest     int     `json:"AuxDest"`
}

// Default is to return all presets
func (client *Client) ListPresets() (presetList []Preset, err error) {
    request := Request{
        Method:     "listPresets",
        Params:     struct{}{},
    }

    if err := client.doResult(&request, &presetList); err != nil {
        return nil, err
    } else {
        return presetList, nil
    }
}

func (client *Client) ListPresetsX(screenID int, auxID int) (presetList []Preset, err error) {
    request := Request{
        Method:     "listPresets",
        Params:     listPresets{
            ScreenDest:     screenID,
            AuxDest:        auxID,
        },
    }

    if err := client.doResult(&request, &presetList); err != nil {
        return nil, err
    } else {
        return presetList, nil
    }
}

// Preset Destinations
type PresetAuxDest struct {
    ID      int     `json:"id"`
}
type PresetScreenDest struct {
    ID      int     `json:"id"`
}

type PresetDestinations struct {
    Preset

    AuxDest     []PresetAuxDest     `json:"AuxDest"`
    ScreenDest  []PresetScreenDest  `json:"ScreenDest"`
}

type listDestinationsForPreset struct {
    ID      int     `json:"id"`
}

func (client *Client) ListDestinationsForPreset(presetID int) (result PresetDestinations, err error) {
    if presetID < 0 {
        return result, fmt.Errorf("Invalid Preset ID: %v", presetID)
    }

    request := Request{
        Method:     "listDestinationsForPreset",
        Params:     listDestinationsForPreset{
            ID:     presetID,
        },
    }

    if err := client.doResult(&request, &result); err != nil {
        return result, err
    } else {
        return result, nil
    }
}

// XML
type PresetCol map[int]Preset

// unmarshal each <Preset> separately
// TODO: this is not as efficient, since we COW the PresetCol map on every Preset...
func (col *PresetCol) UnmarshalXML(d *xml.Decoder, e xml.StartElement) error {
    return unmarshalXMLItem(col, d, e)
}

func (col PresetCol) MarshalJSON() ([]byte, error) {
    return marshalJSONMap(col)
}

func (col PresetCol) List() (items []Preset) {
    var keys []int

    for key, _ := range col {
        keys = append(keys, key)
    }

    sort.Ints(keys)

    for _, key := range keys {
        items = append(items, col[key])
    }

    return items
}

type PresetMgr struct {
    ID          int             `xml:"id,attr"`

    LastRecall  int             `xml:"LastRecall"`

    Preset      PresetCol       `xml:",any"`    // <Preset> or <Add><Preset> or <Remove><Preset>
}
{'fraction_non_alphanumeric': 0.12210271171034692, 'fraction_numerical': 0.0030298439630359036, 'mean_word_length': 2.2845771144278606, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 12, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5349400', 'n_tokens_mistral': 2184, 'n_tokens_neox': 2128, 'n_words': 587}