| package engine |
| |
| import ( |
| "bytes" |
| "encoding/json" |
| "io" |
| "sort" |
| "strconv" |
| ) |
| |
| type Table struct { |
| Data []*Env |
| sortKey string |
| Chan chan *Env |
| } |
| |
| func NewTable(sortKey string, sizeHint int) *Table { |
| return &Table{ |
| make([]*Env, 0, sizeHint), |
| sortKey, |
| make(chan *Env), |
| } |
| } |
| |
| func (t *Table) SetKey(sortKey string) { |
| t.sortKey = sortKey |
| } |
| |
| func (t *Table) Add(env *Env) { |
| t.Data = append(t.Data, env) |
| } |
| |
| func (t *Table) Len() int { |
| return len(t.Data) |
| } |
| |
| func (t *Table) Less(a, b int) bool { |
| return t.lessBy(a, b, t.sortKey) |
| } |
| |
| func (t *Table) lessBy(a, b int, by string) bool { |
| keyA := t.Data[a].Get(by) |
| keyB := t.Data[b].Get(by) |
| intA, errA := strconv.ParseInt(keyA, 10, 64) |
| intB, errB := strconv.ParseInt(keyB, 10, 64) |
| if errA == nil && errB == nil { |
| return intA < intB |
| } |
| return keyA < keyB |
| } |
| |
| func (t *Table) Swap(a, b int) { |
| tmp := t.Data[a] |
| t.Data[a] = t.Data[b] |
| t.Data[b] = tmp |
| } |
| |
| func (t *Table) Sort() { |
| sort.Sort(t) |
| } |
| |
| func (t *Table) ReverseSort() { |
| sort.Sort(sort.Reverse(t)) |
| } |
| |
| func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) { |
| if _, err := dst.Write([]byte{'['}); err != nil { |
| return -1, err |
| } |
| n = 1 |
| for i, env := range t.Data { |
| bytes, err := env.WriteTo(dst) |
| if err != nil { |
| return -1, err |
| } |
| n += bytes |
| if i != len(t.Data)-1 { |
| if _, err := dst.Write([]byte{','}); err != nil { |
| return -1, err |
| } |
| n++ |
| } |
| } |
| if _, err := dst.Write([]byte{']'}); err != nil { |
| return -1, err |
| } |
| return n + 1, nil |
| } |
| |
| func (t *Table) ToListString() (string, error) { |
| buffer := bytes.NewBuffer(nil) |
| if _, err := t.WriteListTo(buffer); err != nil { |
| return "", err |
| } |
| return buffer.String(), nil |
| } |
| |
| func (t *Table) WriteTo(dst io.Writer) (n int64, err error) { |
| for _, env := range t.Data { |
| bytes, err := env.WriteTo(dst) |
| if err != nil { |
| return -1, err |
| } |
| n += bytes |
| } |
| return n, nil |
| } |
| |
| func (t *Table) ReadListFrom(src []byte) (n int64, err error) { |
| var array []interface{} |
| |
| if err := json.Unmarshal(src, &array); err != nil { |
| return -1, err |
| } |
| |
| for _, item := range array { |
| if m, ok := item.(map[string]interface{}); ok { |
| env := &Env{} |
| for key, value := range m { |
| env.SetAuto(key, value) |
| } |
| t.Add(env) |
| } |
| } |
| |
| return int64(len(src)), nil |
| } |
| |
| func (t *Table) ReadFrom(src io.Reader) (n int64, err error) { |
| decoder := NewDecoder(src) |
| for { |
| env, err := decoder.Decode() |
| if err == io.EOF { |
| return 0, nil |
| } else if err != nil { |
| return -1, err |
| } |
| t.Add(env) |
| } |
| } |