struct TMemoryStream
  .size    dd   ?
  .offset  dd   ?
  label .data byte
ends


;------------------------------------------------------------
; Returns: ebx - base addr
;          edi - offset to put data.
;------------------------------------------------------------
proc GetStreamRoom, .ptrVarStream, .room
begin
        push    esi ecx

        mov     esi, [.ptrVarStream]
        mov     ebx, [esi]              ; pointer to the array

        mov     edi, [ebx+TMemoryStream.offset]
        mov     eax, [ebx+TMemoryStream.size]
        sub     eax, edi
        cmp     eax, [.room]      ; check for enough room
        jge     .sizeok

        mov     ecx, [ebx+TMemoryStream.size]
        call    [ResizeIt]

        mov     eax, [ebx+TMemoryStream.offset]
        add     eax, [.room]
        add     eax, 1024       ; 1k more...
        cmp     eax, ecx
        jbe     @f
        mov     ecx, eax
@@:
        stdcall ResizeMem, ebx, ecx
        mov     ebx, eax
        mov     [esi], eax  ; new pointer
        jc      .exit

        mov     [ebx+TMemoryStream.size], ecx   ; new size.

.sizeok:
        mov     eax, [.room]
        add     [ebx+TMemoryStream.offset], eax

.exit:
        pop     ecx esi
        return
endp




proc SetStreamOfs, .ptrVarStream, .offset
begin
        push    esi edi ebx

        mov     edi, [.ptrVarStream]
        mov     eax, [edi]
        mov     ebx, [.offset]
        mov     esi, [eax+TMemoryStream.size]

        cmp     ebx, esi
        jl      .sizeok

        lea     esi, [ebx+$1000]        ; new size
        stdcall ResizeMem, eax, esi
        mov     [edi], eax

.sizeok:
        mov     [eax+TMemoryStream.size], esi
        mov     [eax+TMemoryStream.offset], ebx
        pop     ebx edi esi
        return
endp





proc CreateMemoryStream, .ptrVarStream, .initsize
begin
        push    ebx esi

        mov     ebx, [.initsize]
        mov     esi, [.ptrVarStream]
        add     ebx, sizeof.TMemoryStream

        stdcall GetMem, ebx
        mov     [esi], eax
        mov     [eax+TMemoryStream.size], ebx
        mov     [eax+TMemoryStream.offset], TMemoryStream.data

        pop     esi ebx
        return
endp