# matrix-appservice-kakaotalk - A Matrix-KakaoTalk puppeting bridge. # Copyright (C) 2022 Tulir Asokan, Andrew Ferrazzutti # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . from typing import ClassVar, Optional from attr import dataclass, asdict import bson from mautrix.types import SerializableAttrs, JSON @dataclass(frozen=True) class Long(SerializableAttrs): high: int low: int unsigned: bool @classmethod def from_bytes(cls, raw: bytes) -> "Long": return cls(**bson.loads(raw)) @classmethod def from_optional_bytes(cls, raw: Optional[bytes]) -> Optional["Long"]: return cls(**bson.loads(raw)) if raw is not None else None @classmethod def to_optional_bytes(cls, value: Optional["Long"]) -> Optional[bytes]: return bytes(value) if value is not None else None def serialize(self) -> JSON: data = super().serialize() data["__type__"] = "Long" return data def __bytes__(self) -> bytes: return bson.dumps(asdict(self)) def __int__(self) -> int: if self.unsigned: pass result = \ ((self.high + (1 << 32 if self.high < 0 else 0)) << 32) + \ ( self.low + (1 << 32 if self.low < 0 else 0)) return result + (1 << 32 if self.unsigned and result < 0 else 0) def __str__(self) -> str: return str(int(self)) ZERO: ClassVar["Long"] Long.ZERO = Long(0, 0, False) class IntLong(Long): """Helper class for constructing a Long from an int.""" def __init__(self, val: int): if val < 0: pass super().__init__( high=(val & 0xffffffff00000000) >> 32, low = val & 0x00000000ffffffff, unsigned=val < 0, ) class StrLong(IntLong): """Helper class for constructing a Long from the string representation of an int.""" def __init__(self, val: str): super().__init__(int(val))