'//
'//  Free memory located at a specified location
'//     
Function MemFree(ByRef pMem As Dword) As Long
   If pMem Then 
      HeapFree ByVal GetProcessHeap(), ByVal 0, ByVal pMem
      pMem = 0
   End If
End Function


'//
'//  Manually allocate a block of memory at the specified location
'//                     
Function MemAlloc(ByVal nSize As Long) As Dword
   If nSize > 0 Then 
      Function = HeapAlloc( ByVal GetProcessHeap(), ByVal %HEAP_ZERO_MEMORY, ByVal nSize) 
   End If   
End Function
   
   
'//
'//  Resize an existing block of memory by creating a new block
'//  of memory and copying the old block into it.
'//
Function MemReAlloc( ByVal pMem As Dword, _
                     ByVal nNewSize As Dword _ 
                     ) As Long                  
   
   ' Do not use HeapReAlloc because it causes memory fragmentation on Win98 when
   ' many small allocations are done.
   Local pNewMem As Long

   If nNewSize = 0 Then Exit Function
   If pMem Then
      pNewMem = MemAlloc( nNewSize )
      MoveMemory ByVal pNewMem, ByVal pMem, nNewSize
      MemFree pMem
   Else
      pNewMem = MemAlloc( nNewSize )
   End If
  
   Function = pNewMem

End Function


'//
'//  Sub that will assign a dynamic string to a memory location
'//  and free any memory that may have already been allocated.
'//  pMem must be ByRef.
'//
Sub MemString( ByRef pMem As Dword, _
               ByVal sData As String )

    If pMem Then HeapFree( ByVal GetProcessHeap(), ByVal 0, ByVal pMem)  ' free any existing memory
    sData = sData & $Nul
    pMem = HeapAlloc( ByVal GetProcessHeap(), ByVal %HEAP_ZERO_MEMORY, ByVal Len( sData ) + 1)
    If pMem Then Poke$ pMem, sData

End Sub
   
    

'//
'//  MemCopyD - fast memory copy
'//
Sub MemCopyD( ByVal src As Dword, _
              ByVal dst As Dword, _
              ByVal ln  As Dword) 

   #Register None

     ! cld

     ! mov esi, src
     ! mov edi, dst
     ! mov ecx, ln

     ! shr ecx, 2
     ! rep movsd

     ! mov ecx, ln
     ! And ecx, 3
     ! rep movsb

End Sub



'//
'//  StrCmp3 - fast memory compare
'//            Returns -1 if less than, 0 if equal, +1 if greater
'//            Performs a case SENSITIVE comparison
'//
Function StrCmp3( ByVal src As Dword, _
                  ByVal dst As Dword, _
                  ByVal ln  As Dword _
                  ) As Long
   
   #Register None

   ! mov ecx, ln
   ! mov esi, src
   ! Add esi, ecx

   ! mov edi, dst
   ! Add edi, ecx

   ! neg ecx

 scLbl:
   ! mov al, [esi+ecx]     ; move the source character into AL For comparision
   ! cmp al, [edi+ecx]     ; compare the current destination character To AL
   ! ja lblGreater         ; source Is greater than destination
   ! jb lblLess            ; source Is less than destination
   
   ! inc ecx               ; move To the Next character To be compared
   ! jnz scLbl             ; continue the comparisons

   ! mov eax, 0            ; source And destination are equal
   ! jmp scOut

 lblGreater:
   ! mov eax, 1            ; source Is greater than destination
   ! jmp scOut

 lblLess:
   ! mov eax, -1            ; source Is less than destination

 scOut:
   ! mov Function, eax

End Function



'//
'//  MemInsert - fast insertion into a block of memory
'//
Function MemInsert( ByVal MainStringAddr As Dword, _
                    ByVal MainStringLength As Dword, _
                    ByVal InsertPosition As Dword, _
                    ByVal InsertStringAddr As Dword, _
                    ByVal InsertStringLength As Dword _
                    ) As Long 

   Static tempBuffer As Asciiz * %INDEX_NODE_SIZE
   
   ' copy the part of the buffer that needs to be moved to the right.
   MemCopyD MainStringAddr + InsertPosition, _
            VarPtr(tempBuffer), _
            MainStringLength - InsertPosition
              
   ' copy the insert string into the main string           
   MemCopyD InsertStringAddr, _
            MainStringAddr + InsertPosition, _
            InsertStringLength
   
   ' copy the saved buffer back to the main string
   MemCopyD VarPtr(tempBuffer), _          
            MainStringAddr + InsertPosition + InsertStringLength, _
            MainStringLength - InsertPosition - InsertStringLength 
                
End Function


'//
'//  MemDelete - fast deletion of a block of memory within a block of memory
'//
Function MemDelete( ByVal MainStringAddr As Dword, _
                    ByVal MainStringLength As Dword, _
                    ByVal DeletePosition As Dword, _
                    ByVal DeleteLength As Dword _
                    ) As Long 

   MemCopyD MainStringAddr + DeletePosition + DeleteLength, _
            MainStringAddr + DeletePosition, _
            MainStringLength - DeletePosition - DeleteLength
            
   ' Fill the remaining part of memory with nulls
   FillMemory MainStringAddr + MainStringLength - DeleteLength, _
              DeleteLength, 0

End Function
