/********************************************************************
 * @author:      Kaven
 * @email:       kaven@wuwenkai.com
 * @website:     http://kavenblog.com
 * @file:        [basic] /src/libs/KavenUInt64.ts
 * @create:      2019-04-11 13:01:36.287
 * @modify:      2019-04-13 01:29:04.829
 * @version:     1.1.20
 * @times:       41
 * @lines:       193
 * @copyright:   Copyright © 2019 Kaven. All Rights Reserved.
 * @description: [description]
 * @license:
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 ********************************************************************/
export class KavenUInt64 {
    constructor(value, radix = 16) {
        this.high = 0;
        this.low = 0;
        if (value === undefined) {
            return;
        }
        if (typeof value === "number") {
            this.low = value;
        }
        else {
            const hl = value.SplitByN(8);
            if (hl.length === 2) {
                this.high = parseInt(hl[0], radix);
                this.low = parseInt(hl[1], radix);
            }
            else {
                this.low = parseInt(hl[0], radix);
            }
        }
    }
    get HEX() {
        // this.ToUnit();
        return this.high.ToHEX() + this.low.ToHEX();
    }
    // tslint:disable:no-bitwise
    static FromBytes(...bytes) {
        let [h, l] = [0, 0];
        const hl = bytes.Split(4);
        if (hl.length === 2) {
            for (let i = 0; i < hl[0].length; i++) {
                l += (hl[0][i] << 8 * i);
            }
            for (let i = 0; i < hl[1].length; i++) {
                h += (hl[1][i] << 8 * i);
            }
        }
        else {
            for (let i = 0; i < hl[0].length; i++) {
                l += (hl[0][i] << 8 * i);
            }
        }
        return KavenUInt64.FromHighLow(h, l);
    }
    static FromHighLow(high, low) {
        const result = new KavenUInt64();
        result.high = high >>> 0;
        result.low = low >>> 0;
        return result;
    }
    static Initialize2d(x, y) {
        return new Array(x).fill(new KavenUInt64()).map(() => new Array(y).fill(new KavenUInt64()));
    }
    Swap() {
        return KavenUInt64.FromHighLow(this.low.Swap32(), this.high.Swap32());
    }
    AND(val) {
        let [h, l] = [0, 0];
        if (typeof val === "number") {
            l = this.low & val;
            h = 0;
        }
        else {
            l = this.low & val.low;
            h = this.high & val.high;
        }
        return KavenUInt64.FromHighLow(h, l);
    }
    XOR(val) {
        let [h, l] = [0, 0];
        if (typeof val === "number") {
            l = this.low ^ val;
        }
        else {
            l = this.low ^ val.low;
            h = this.high ^ val.high;
        }
        return KavenUInt64.FromHighLow(h, l);
    }
    NOT() {
        return KavenUInt64.FromHighLow(~this.high, ~this.low);
    }
    LeftRotate(n) {
        if (n === 0) {
            return this.Clone();
        }
        let [h, l] = [this.low, this.high];
        if (n < 32) {
            const m = 32 - n;
            l = this.low << n | this.high >>> m;
            h = this.high << n | this.low >>> m;
        }
        else if (n > 32) {
            n -= 32;
            const m = 32 - n;
            l = this.high << n | this.low >>> m;
            h = this.low << n | this.high >>> m;
        }
        return KavenUInt64.FromHighLow(h, l);
    }
    RightRotate(n) {
        if (n === 0) {
            return this.Clone();
        }
        let [h, l] = [this.low, this.low];
        if (n < 32) {
            const m = 32 - n;
            l = this.low >>> n | this.high << m;
            h = this.high >>> n | this.low << m;
        }
        else if (n > 32) {
            n -= 32;
            const m = 32 - n;
            l = this.high >>> n | this.low << m;
            h = this.low >>> n | this.high << m;
        }
        return KavenUInt64.FromHighLow(h, l);
    }
    Clone() {
        return KavenUInt64.FromHighLow(this.high, this.low);
    }
}
//# sourceMappingURL=KavenUInt64.js.map