package model import ( "fmt" "log/slog" ) type DCEvent int const ( // 驱动数据更新 DCE_Drive_Update DCEvent = 1 // 采集数据更新 DCE_Collect_Update DCEvent = 2 ) // 驱动采集数据 type QC interface { // 更新驱动数据,位数组 UpdateQdByBits(start uint32, bits []bool) error // 更新驱动数据,字节数组 UpdateQdByBytes(start uint32, values []byte) error // 更新采集数据,位数组 UpdateCjByBits(start uint32, bits []bool) error // 更新采集数据,字节数组 UpdateCjByBytes(start uint32, values []byte) error // 设置驱动数据 SetQdBytes(bytes []byte) // 获取驱动数据,字节数组 GetQdBytes() []byte // 获取驱动数据,位数组 GetQdBits() []bool // 获取指定驱动数据,位 GetQdBitOf(start uint32) bool // 获取指定驱动数据,位数组 GetQdBitsOf(start uint32, quantity uint32) []bool // 获取指定驱动数据,字节 GetQdByteOf(start uint32) byte // 获取指定驱动数据,字节数组 GetQdBytesOf(start uint32, quantity uint32) []byte // 设置采集数据 SetCjBytes(bytes []byte) // 获取采集数据,字节数组 GetCjBytes() []byte // 获取采集数据,位数组 GetCjBits() []bool // 获取指定采集数据,位 GetCjBitOf(start uint32) bool // 获取指定采集数据,位数组 GetCjBitsOf(start uint32, quantity uint32) []bool // 获取指定采集数据,字节 GetCjByteOf(start uint32) byte // 获取指定采集数据,字节数组 GetCjBytesOf(start uint32, quantity uint32) []byte // // 发布事件 // Emit(event DCEvent) // // 订阅事件 // On(event DCEvent, callback func(dc QC)) // // 取消订阅 // Off(event DCEvent, callback func(dc QC)) } type qc struct { // 驱动数据 qd []byte qdBits []bool // 采集数据 cj []byte cjBits []bool // // 事件 // subscribes map[DCEvent][]func(dc QC) } func (d *qc) SetCjBytes(bytes []byte) { d.cj = bytes d.cjBits = DecodeBools(bytes) } // GetCjBytes implements DC. func (d *qc) GetCjBytes() []byte { return d.cj } func (d *qc) GetCjBits() []bool { return d.cjBits } func (d *qc) GetCjBitOf(start uint32) bool { if start >= uint32(len(d.cjBits)) { panic(fmt.Errorf("GetCollectBit超出范围")) } return d.cjBits[start] } func (d *qc) GetCjBitsOf(start uint32, quantity uint32) []bool { if start+quantity > uint32(len(d.cjBits)) { panic(fmt.Errorf("GetCollectBits超出范围")) } return d.cjBits[start : start+quantity] } func (d *qc) GetCjByteOf(start uint32) byte { if start >= uint32(len(d.cj)) { panic(fmt.Errorf("GetCollectByte超出范围")) } return d.cj[start] } func (d *qc) GetCjBytesOf(start uint32, quantity uint32) []byte { if start+quantity > uint32(len(d.cj)) { panic(fmt.Errorf("GetCollectBytes超出范围")) } return d.cj[start : start+quantity] } func (d *qc) SetQdBytes(bytes []byte) { d.qd = bytes d.qdBits = DecodeBools(bytes) } // GetQdBytes implements DC. func (d *qc) GetQdBytes() []byte { return d.qd } func (d *qc) GetQdBits() []bool { return d.qdBits } func (d *qc) GetQdBitOf(start uint32) bool { if start >= uint32(len(d.qdBits)) { panic(fmt.Errorf("GetDriveBit超出范围")) } return d.qdBits[start] } func (d *qc) GetQdBitsOf(start uint32, quantity uint32) []bool { if start+quantity > uint32(len(d.qdBits)) { panic(fmt.Errorf("GetDriveBits超出范围")) } return d.qdBits[start : start+quantity] } func (d *qc) GetQdByteOf(start uint32) byte { if start >= uint32(len(d.qd)) { panic(fmt.Errorf("GetDriveByte超出范围")) } return d.qd[start] } func (d *qc) GetQdBytesOf(start uint32, quantity uint32) []byte { if start+quantity > uint32(len(d.qd)) { panic(fmt.Errorf("GetDriveBytes超出范围")) } return d.qd[start : start+quantity] } // UpdateCjByBits implements DC. func (d *qc) UpdateCjByBits(start uint32, bits []bool) error { total := len(d.cjBits) if start >= uint32(total) { return fmt.Errorf("UpdateCollectByBits参数start超出范围") } end := start + uint32(len(bits)) if end > uint32(total) { return fmt.Errorf("UpdateCollectByBits参数start+len(bits)超出范围") } for i := start; i < end; i++ { d.cjBits[i] = bits[i-start] } d.cj = EncodeBytes(d.cjBits) slog.Debug("UpdateCollectByBits成功", "collect", fmt.Sprintf("%v", d.cj), "collectBits", d.cjBits) // d.Emit(DCE_Collect_Update) return nil } // UpdateCjByBytes implements DC. func (d *qc) UpdateCjByBytes(start uint32, values []byte) error { total := len(d.cj) if start >= uint32(total) { return fmt.Errorf("UpdateCollectByBytes参数start超出范围") } end := start + uint32(len(values)) if end > uint32(total) { return fmt.Errorf("UpdateCollectByBytes参数start+len(values)超出范围") } copy(d.cj[start:end], values) d.cjBits = DecodeBools(d.cj) slog.Debug("UpdateCollectByBytes成功", "collect", fmt.Sprintf("%v", d.cj), "collectBits", d.cjBits) // d.Emit(DCE_Collect_Update) return nil } // UpdateQdByBits implements DC. func (d *qc) UpdateQdByBits(start uint32, bits []bool) error { total := len(d.qdBits) if start >= uint32(total) { return fmt.Errorf("UpdateDriveByBits参数start超出范围") } end := start + uint32(len(bits)) if end > uint32(total) { return fmt.Errorf("UpdateDriveByBits参数start+len(bits)超出范围") } for i := start; i < end; i++ { d.qdBits[i] = bits[i-start] } d.qd = EncodeBytes(d.qdBits) slog.Debug("UpdateDriveByBits成功", "drive", fmt.Sprintf("%v", d.qd), "driveBits", d.qdBits) // d.Emit(DCE_Drive_Update) return nil } // UpdateQdByBytes implements DC. func (d *qc) UpdateQdByBytes(start uint32, values []byte) error { total := len(d.qd) if start >= uint32(total) { return fmt.Errorf("UpdateDriveByBytes参数start超出范围") } end := start + uint32(len(values)) if end > uint32(total) { return fmt.Errorf("UpdateDriveByBytes参数start+len(values)超出范围") } copy(d.qd[start:end], values) d.qdBits = DecodeBools(d.qd) slog.Debug("UpdateDriveByBytes成功", "drive", fmt.Sprintf("%v", d.qd), "driveBits", d.qdBits) // d.Emit(DCE_Drive_Update) return nil } // // Emit implements DC. // func (d *qc) Emit(event DCEvent) { // listeners := d.subscribes[event] // for _, v := range listeners { // v(d) // } // } // // On implements DC. // func (d *qc) On(event DCEvent, callback func(d QC)) { // d.subscribes[event] = append(d.subscribes[event], callback) // } // // Off implements DC. // func (d *qc) Off(event DCEvent, callback func(d QC)) { // panic("unimplemented") // } func NewDC(qd []byte, cj []byte) QC { return &qc{ qd: qd, qdBits: DecodeBools(qd), cj: cj, cjBits: DecodeBools(cj), // subscribes: make(map[DCEvent][]func(d QC)), } } func DecodeBools(bytes []byte) (out []bool) { len := len(bytes) * 8 var i int for i = 0; i < len; i++ { out = append(out, (((bytes[i/8] >> (i % 8)) & 0x01) == 0x01)) } return out } func EncodeBytes(bits []bool) (out []byte) { len := len(bits) if len%8 != 0 { panic("encodeBytes参数bits长度错误") } var i int out = make([]byte, len/8) for i = 0; i < len; i++ { if bits[i] { out[i/8] = out[i/8] | (1 << (i % 8)) } } return out }