import t, c
from stdint import *


class Buf:
    data: t.CChar | t.CPtr
    length: t.CSizeT
    capacity: t.CSizeT
    owned: bool

    def __init__(self, data: t.CChar | t.CPtr, capacity: t.CSizeT, length: t.CSizeT = 0, owned: bool = False):
        self.data = data
        self.capacity = capacity
        self.length = length
        self.owned = owned

    def clear(self):
        self.length = 0
        if self.data != None and self.capacity > 0:
            self.data[0] = 0

    def write(self, src: t.CChar | t.CPtr, count: t.CSizeT) -> t.CSizeT:
        if self.data == None: return 0
        if src == None: return 0
        if count == 0: return 0
        avail: t.CSizeT = self.capacity - self.length
        if avail <= 0: return 0
        n: t.CSizeT = count if count < avail else avail
        i: t.CSizeT = 0
        while i < n:
            self.data[self.length + i] = src[i]
            i += 1
        self.length += n
        self.data[self.length] = 0
        return n

    def cstr(self) -> t.CChar | t.CPtr:
        return self.data

    def reset(self):
        self.length = 0
        if self.data != None and self.capacity > 0:
            self.data[0] = 0

    def __enter__(self) -> 'Buf' | t.CPtr:
        return self

    def __exit__(self):
        self.reset()

    def free(self):
        if self.owned and self.data != None:
            self.data[0] = 0
            self.owned = False
        self.data = None
        self.length = 0
        self.capacity = 0
