【仓颉】二、一个仓颉的Modbus库-3. 扩展方法:extend Array<T>

在看到支持扩展方法的时候,先感觉是C#里,用一个静态类加this参数的方式,如:public static string Add(this string stringName)。看了手册发现,仓颉是将扩展独立了一个模块!可以更好的支持this指针,属性扩展,protect权限等,比C#的扩展防范更为强大!

如:

extend Array<T> <: IHexConvert where T <: Byte{
    public func setUInt8(bufferIndex:Int64, value : Byte) : Bool{
        @LenCheckThrow(this.size <= bufferIndex)
        this[bufferIndex] = B2T(value)
        return true
    }   

    public func getUInt8(bufferIndex:Int64) : Byte{
        @LenCheckThrow(this.size <= bufferIndex)
        return this[bufferIndex]
    }

    public func setUInt16AB(bufferIndex:Int64, value : UInt16) : Bool{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        this[bufferIndex + 1] = B2T((UInt8(value & 0x00ff)))
        this[bufferIndex] = B2T(UInt8((value & 0x00ff) >> 8))
        return true
    }

    public func getUInt16AB(bufferIndex:Int64) : UInt16{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        return ((UInt16(T2B(this[bufferIndex + 1]))) & 0x00ff) | ((UInt16(T2B(this[bufferIndex])) << 8) & 0xff00)
    }
}

好了,我的代码里出现了一些奇怪的东西:T2B与B2T。这是怎么回事呢?

在写扩展方法的时候,我希望扩展方法仅对泛型Array<Byte>生效。然而—不行,编印不通过。我无法写成extend Array<Byte>的形式(此时会把Byte当作泛型T来看待,而不是一个实例Byte。如果extend Array<UInt8>则会直接报错)。所以,我只能指定T为Byte的派生类型来曲线救国进行限定。

但这带来一个问题:Byte与泛型T毕竟属于派生关系,需要互相转换。于是我写了两个静态方法区转换Byte与T类型:

    private static func T2B(val : T) : Byte{
        val
    }

    private static func B2T(val : Byte) : T{
        if(val is T){
            (val as T).getOrThrow()
        } else{
            throw IllegalArgumentException("类型转换失败")
        }
    }

这里我也尝试对UInt8进行扩展,也无法实现。

然后又出现一个问题:扩展防范无法在包的外部进行访问。我为扩展方法添加一个接口之后就可以访问了,不知道是不是当前版本问题。

好了,数组的扩展类做完了,后面就是添加更多的数据类型转换了。

注意,Modbus会出现数据大小端的问题,因此UInt16AB与UInt16BA就是分别对应了大端与小端。

参考代码(src/hex_bufferconvert/bytesarray_extern.cj):

package hex_bufferconvert

import hex_bufferconvert.macros.*
public interface IHexConvert{
}

extend Array<T> <: IHexConvert where T <: Byte{
    public func copy(start:Int64,end:Int64) : Array<T>{
        @LenCheckThrow(this.size <= end)
        var temp = Array<T>(end - start, item:(0 as T).getOrThrow())
        this.copyTo(temp, start, 0, end - start)
        return temp
    }
    public func setUInt8(bufferIndex:Int64, value : Byte) : Bool{
        @LenCheckThrow(this.size <= bufferIndex)
        this[bufferIndex] = B2T(value)
        return true
    }
    
    public func getUInt8(bufferIndex:Int64) : Byte{
        @LenCheckThrow(this.size <= bufferIndex)
        return this[bufferIndex]
    }

    public func setUInt16AB(bufferIndex:Int64, value : UInt16) : Bool{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        this[bufferIndex + 1] = B2T((UInt8(value & 0x00ff)))
        this[bufferIndex] = B2T(UInt8((value & 0x00ff) >> 8))
        return true
    }

    public func getUInt16AB(bufferIndex:Int64) : UInt16{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        return ((UInt16(T2B(this[bufferIndex + 1]))) & 0x00ff) | ((UInt16(T2B(this[bufferIndex])) << 8) & 0xff00)
    }
    public func setUInt16BA(bufferIndex:Int64, value : UInt16) : Bool{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        this[bufferIndex] = B2T((UInt8(value & 0x00ff)))
        this[bufferIndex + 1] = B2T(UInt8((value & 0x00ff) >> 8))
        return true
    }
    public func getUInt16BA(bufferIndex:Int64) : UInt16{
        @LenCheckThrow(this.size <= (bufferIndex + 1))
        return (UInt16(T2B(this[bufferIndex])) & 0x00ff) | ((UInt16(T2B(this[bufferIndex + 1])) << 8) & 0xff00)
    }
    private func getUInt32ABCD(bufferIndex:Int64) : UInt32{
        @LenCheckThrow(this.size <= (bufferIndex + 3))
        return ((UInt32(T2B(this[bufferIndex+3])) << 24) & 0xff000000) | 
        ((UInt32(T2B(this[bufferIndex+2])) << 16) & 0x00ff0000)| 
        ((UInt32(T2B(this[bufferIndex+1])) << 8) & 0x0000ff00)| 
        ((UInt32(T2B(this[bufferIndex])) ) & 0x000000ff)
    }
    private func getUInt32BADC(bufferIndex:Int64) : UInt32{
        @LenCheckThrow(this.size <= (bufferIndex + 3))
        return ((UInt32(T2B(this[bufferIndex+2])) << 24) & 0xff000000) | 
        ((UInt32(T2B(this[bufferIndex+3])) << 16) & 0x00ff0000)| 
        ((UInt32(T2B(this[bufferIndex])) << 8) & 0x0000ff00)| 
        ((UInt32(T2B(this[bufferIndex+1])) ) & 0x000000ff)
    }
    private func getUInt32CDAB(bufferIndex:Int64) : UInt32{
        @LenCheckThrow(this.size <= (bufferIndex + 3))
        return ((UInt32(T2B(this[bufferIndex+1])) << 24) & 0xff000000) | 
        ((UInt32(T2B(this[bufferIndex])) << 16) & 0x00ff0000)| 
        ((UInt32(T2B(this[bufferIndex+3])) << 8) & 0x0000ff00)| 
        ((UInt32(T2B(this[bufferIndex+2])) ) & 0x000000ff)
    }
    private func getUInt32DCBA(bufferIndex:Int64) : UInt32{
        @LenCheckThrow(this.size <= (bufferIndex + 3))
        return ((UInt32(T2B(this[bufferIndex])) << 24) & 0xff000000) | 
        ((UInt32(T2B(this[bufferIndex+1])) << 16) & 0x00ff0000)| 
        ((UInt32(T2B(this[bufferIndex+2])) << 8) & 0x0000ff00)| 
        ((UInt32(T2B(this[bufferIndex+3])) ) & 0x000000ff)
    }
    private func getUInt64ABCDEFGH(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+7])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+6])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+5])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+4])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+3])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+2])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+1])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex])) ) & 0xff)
    }
    private func getUInt64EFGHABCD(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+3])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+2])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+1])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+7])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+6])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+5])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+4])) ) & 0xff)
    }
    private func getUInt64CDABGHEF(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex+7))
        return ((UInt64(T2B(this[bufferIndex+5])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+4])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+7])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+6])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+1])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+3])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+2])) ) & 0xff)
    }
    private func getUInt64GHEFCDAB(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+1])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+3])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+2])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+5])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+4])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+7])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+6])) ) & 0xff)
    }
    private func getUInt64BADCFEHG(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+6])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+7])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+4])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+5])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+2])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+3])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+1])) ) & 0xff)
    }
    private func getUInt64FEHGBADC(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+2])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+3])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+1])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+6])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+7])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+4])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+5])) ) & 0xff)
    }
    private func getUInt64DCBAHGFE(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex+4])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+5])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+6])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+7])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+1])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+2])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+3])) ) & 0xff)
    }
    private func getUInt64HGFEDCBA(bufferIndex:Int64) : UInt64{
        @LenCheckThrow(this.size <= (bufferIndex + 7))
        return ((UInt64(T2B(this[bufferIndex])) << 56) & (0xff << 56)) | 
        ((UInt64(T2B(this[bufferIndex+1])) << 48) & (0xff << 48))| 
        ((UInt64(T2B(this[bufferIndex+2])) << 40) & (0xff << 40))| 
        ((UInt64(T2B(this[bufferIndex+3])) <<32) & (0xff << 32))|
        ((UInt64(T2B(this[bufferIndex+4])) << 24) & (0xff << 24)) | 
        ((UInt64(T2B(this[bufferIndex+5])) << 16) & (0xff << 16))| 
        ((UInt64(T2B(this[bufferIndex+6])) << 8) & (0xff << 8))| 
        ((UInt64(T2B(this[bufferIndex+7])) ) & 0xff)
    }
    private static func T2B(val : T) : Byte{
        val
    }
    private static func B2T(val : Byte) : T{
        if(val is T){
            (val as T).getOrThrow()
        } else{
            throw IllegalArgumentException("类型转换失败")
        }
    }
}

@LenCheckThrow(this.size <= (bufferIndex + 1))这个宏我们下一节介绍。

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值