Flexible FillMemory procedure

Share your advanced PureBasic knowledge/code with the community.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Flexible FillMemory procedure

Post by wilbert »

Code: Select all

Structure FillMemoryExStruct
  StructureUnion
    b.a
    w.w
    l.l
    q.q
  EndStructureUnion
EndStructure
  
Procedure FillMemoryEx(*Memory, Size, FillData.s)
  If Size = 0 : ProcedureReturn : EndIf
    
  ; ** convert fill data into bytes **
  
  Protected *m.FillMemoryExStruct = @FillData
  Protected *m1.FillMemoryExStruct = @FillData
  Protected d.FillMemoryExStruct
  Protected b.a, nibble
  Repeat
    b = *m\b
    Select b
      Case $30 To $39; 0 - 9
        d\q = (d\q << 4) | (b - $30)
        nibble + 1
      Case $41 To $46; A - F
        d\q = (d\q << 4) | (b - $37)
        nibble + 1
      Case $61 To $66; a - f
        d\q = (d\q << 4) | (b - $57)
        nibble + 1
      Default
        If nibble > 8
          *m1\q = d\q
          *m1 + 8
        ElseIf nibble > 4 
          *m1\l = d\l
          *m1 + 4
        ElseIf nibble > 2   
          *m1\w = d\w
          *m1 + 2
        ElseIf nibble > 0
          *m1\b = d\b
          *m1 + 1
        EndIf
        nibble = 0
    EndSelect
    *m + SizeOf(Character)
  Until b = 0
  Protected numBytes = *m1 - @FillData
  If numBytes = 0 : ProcedureReturn : EndIf  
  
  ; ** actual fill routine
  
  EnableASM
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    Protected r_ebx, r_edi, r_esi
    MOV r_ebx, ebx
    MOV r_edi, edi
    MOV r_esi, esi
    MOV esi, FillData
    MOV edx, numBytes
    MOV edi, *Memory
    MOV ecx, Size
    !mov ebx, edx 
    !fmex_loop:
    !mov al, [esi]
    !inc esi
    !dec ebx
    !jnz fmex_skip
    !sub esi, edx
    !mov ebx, edx
    !fmex_skip:
    !mov [edi], al
    !inc edi
    !dec ecx
    !jnz fmex_loop
    MOV ebx, r_ebx
    MOV edi, r_edi
    MOV esi, r_esi
  CompilerElse
    MOV r10, FillData
    MOV rdx, numBytes
    MOV r11, *Memory
    MOV rcx, Size
    !mov r8, rdx 
    !fmex_loop:
    !mov al, [r10]
    !inc r10
    !dec r8
    !jnz fmex_skip
    !sub r10, rdx
    !mov r8, rdx
    !fmex_skip:
    !mov [r11], al
    !inc r11
    !dec rcx
    !jnz fmex_loop
  CompilerEndIf
  DisableASM
  
ProcedureReturn
EndProcedure

; ** example code **

memSize = 10000000
*mem = AllocateMemory(memSize)

FillMemoryEx(*mem, memSize, "0D 0A"); fill memory with bytes $0D $0A
FillMemoryEx(*mem, memSize, "0a0d"); fill memory with word $0A0D
FillMemoryEx(*mem, memSize, "1234567890abcdef"); fill memory with quad $1234567890abcdef
FillMemoryEx(*mem, memSize, "0D-0A-12345678"); fill memory with bytes $0D $0A followed by long $12345678
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Flexible FillMemory procedure

Post by idle »

looks useful thanks for sharing
Windows 11, Manjaro, Raspberry Pi OS
Image
Post Reply