// Copyright 2013-2014 Fuzamei tech Ltd. All rights reserved. package client // 本文件为简化客户端的实现, 对Server服务调用进行封装 import ( "bytes" "encoding/binary" "errors" "io" "log" ) var ErrNoFile = errors.New("no file") type decoder interface { Decode(v interface{}) error } type encoder interface { Encode(v interface{}) error } type DlInfo struct { Fname string Reply *HistoryReply } func unzip(b []byte) ([]Candle, error) { r := bytes.NewBuffer(b) return UnzipC(r) } func unzipTicks(b []byte) ([]Tick, error) { r := bytes.NewBuffer(b) return UnzipT(r) } type HistoryResponse struct { clientsimple *ClientSimple timelist []string insId string period int n int ts int64 db bool buf *bytes.Buffer fileIndex int readN int } func (hresp *HistoryResponse) Read(p []byte) (n int, err error) { n, err = hresp.buf.Read(p) if err == io.EOF { if (hresp.n < 0 && hresp.readN >= (-hresp.n)) || (hresp.n > 0 && hresp.readN >= hresp.n) { return n, err //数据读完结束., } fname, err := hresp.nextFile() if err == ErrNoFile { return 0, io.EOF } if err != nil { return 0, err } //log.Println("debug", fname, err) if hresp.period == TK { ticks, err := ReadTickFile(fname) if err != nil { return 0, err } if len(ticks) > 0 { if hresp.n < 0 && ticks[0].Timestamp > hresp.ts { return 0, nil //没有符合要求的数据,跳过这个文件 } if hresp.n > 0 && ticks[len(ticks)-1].Timestamp < hresp.ts { return 0, nil //没有符合要求的数据,跳过这个文件 } } if hresp.n > 0 { for _, tick := range ticks { if tick.Timestamp >= hresp.ts { if hresp.readN >= hresp.n { break } binary.Write(hresp.buf, binary.LittleEndian, &tick) hresp.readN++ } } } if hresp.n < 0 { for j := len(ticks) - 1; j >= 0; j-- { if ticks[j].Timestamp <= hresp.ts { if hresp.readN >= (-hresp.n) { break } binary.Write(hresp.buf, binary.LittleEndian, &ticks[j]) hresp.readN++ } } } } else { candles, err := ReadCandleFile(fname) if err != nil { return 0, err } if len(candles) > 0 { if hresp.n < 0 && candles[0].Timestamp > hresp.ts { log.Println("debug no data", fname) return 0, nil //没有符合要求的数据,跳过这个文件 } if hresp.n > 0 && candles[len(candles)-1].Timestamp < hresp.ts { log.Println("debug no data", fname) return 0, nil //没有符合要求的数据,跳过这个文件 } } if hresp.n > 0 { for _, candle := range candles { if candle.Timestamp >= hresp.ts { if hresp.readN >= hresp.n { break } binary.Write(hresp.buf, binary.LittleEndian, &candle) hresp.readN++ } } } if hresp.n < 0 { for j := len(candles) - 1; j >= 0; j-- { if candles[j].Timestamp <= hresp.ts { if hresp.readN >= (-hresp.n) { break } binary.Write(hresp.buf, binary.LittleEndian, &candles[j]) hresp.readN++ } } } } return hresp.buf.Read(p) } return n, err } func (hresp *HistoryResponse) nextFile() (string, error) { if hresp.n == 0 { return "", ErrNoFile } if hresp.n < 0 { for i := hresp.fileIndex; i >= 0; i-- { var fname string var err error fname, err = hresp.clientsimple.downloadOne(hresp.insId, hresp.timelist[i], hresp.period) if err == nil { hresp.fileIndex = i - 1 return fname, nil } else { return "", err } } } if hresp.n > 0 { for i := hresp.fileIndex; i < len(hresp.timelist); i++ { var fname string var err error fname, err = hresp.clientsimple.downloadOne(hresp.insId, hresp.timelist[i], hresp.period) if err == nil { hresp.fileIndex = i + 1 return fname, nil } else { return "", err } } } return "", ErrNoFile } func (hresp *HistoryResponse) Close() error { return nil } type HistoryResponseEx struct { clientsimple *ClientSimple timelist []string insId string period int st int64 et int64 db bool fileIndex int readTime int64 buf *bytes.Buffer } func (hresp *HistoryResponseEx) Read(p []byte) (n int, err error) { n, err = hresp.buf.Read(p) if err == io.EOF { if hresp.readTime >= hresp.et { return n, err //数据读完结束., } fname, err := hresp.nextFile() if err == ErrNoFile { return 0, io.EOF } if err != nil { log.Println("debug", err) return 0, err } log.Println("debug", fname) if hresp.period == TK { ticks, err := ReadTickFile(fname) if err != nil { return 0, err } if len(ticks) > 0 { if ticks[len(ticks)-1].Timestamp < hresp.st { return 0, nil //没有符合要求的数据,跳过这个文件 } } for _, tick := range ticks { if tick.Timestamp >= hresp.st { if tick.Timestamp <= hresp.et { binary.Write(hresp.buf, binary.LittleEndian, &tick) hresp.readTime = tick.Timestamp } else { break } } } } else { candles, err := ReadCandleFile(fname) if err != nil { return 0, err } if len(candles) > 0 { if candles[len(candles)-1].Timestamp < hresp.st { log.Println("debug no data", fname) return 0, nil //没有符合要求的数据,跳过这个文件 } } for _, candle := range candles { if candle.Timestamp >= hresp.st { if candle.Timestamp <= hresp.et { binary.Write(hresp.buf, binary.LittleEndian, &candle) hresp.readTime = candle.Timestamp } else { break } } } } return hresp.buf.Read(p) } return n, err } func (hresp *HistoryResponseEx) nextFile() (string, error) { for i := hresp.fileIndex; i < len(hresp.timelist); i++ { var fname string var err error fname, err = hresp.clientsimple.downloadOne(hresp.insId, hresp.timelist[i], hresp.period) if err == nil { hresp.fileIndex = i + 1 return fname, nil } else { return "", err } } return "", ErrNoFile } func (hresp *HistoryResponseEx) Close() error { return nil }