Element StrList GlobalConst implements_IArray StrList StrListError db 'error',0 Vars Self#.IArray dd ? ; vtbl, must be first Self#.ListBuffer dd ? Self#.ListCount dd ? Self#.BufferSize dd ? Self#.BufferUsed dd ? Self#.Text dd ? GlobalProc proc StrListSkip cld test edx,edx jz .L2 mov ecx,-1 xor eax,eax .L1: repne scasb dec edx jnz .L1 .L2: ret endp proc StrList.IArray.Set self,idx,data locals datalen dd ? diff dd ? offs dd ? endl push esi edi mov esi,[self] mov edx,[idx] cmp edx,[pStrList.ListCount] mov eax,StrListError jae .LE mov edi,[pStrList.ListBuffer] call StrListSkip mov eax,edi sub edi,[pStrList.ListBuffer] mov [offs],edi call __strlen push eax mov eax,[data] call __strlen mov [datalen],eax pop edx sub eax,edx mov [diff],eax jb .L2 jz .L4 add eax,[pStrList.BufferUsed] cmp eax,[pStrList.BufferSize] jb .L1 and eax,0FFFFFC00h add eax,400h mov [pStrList.BufferSize],eax mov edx,eax mov eax,[pStrList.ListBuffer] call __realloc mov [pStrList.ListBuffer],eax .L1: mov eax,[offs] add eax,[pStrList.ListBuffer] mov edx,eax add eax,[diff] jmp .L3 .L2: mov eax,[offs] add eax,[pStrList.ListBuffer] mov edx,eax sub edx,[diff] .L3: mov ecx,[pStrList.BufferUsed] sub ecx,[offs] call __memmove mov eax,[diff] add [pStrList.BufferUsed],eax .L4: mov edi,[pStrList.ListBuffer] add edi,[offs] mov esi,[data] mov ecx,[datalen] cld rep movsb .LE: pop edi esi ret endp proc StrList.IArray.Get self,idx push esi edi mov esi,[self] mov edx,[idx] cmp edx,[pStrList.ListCount] mov eax,StrListError jae .L1 mov edi,[pStrList.ListBuffer] call StrListSkip mov eax,edi .L1: pop edi esi ret endp proc StrList.IArray.Count self push esi mov esi,[self] mov eax,[pStrList.ListCount] pop esi ret endp proc StrList.IArray.Add self,data push esi edi mov eax,[data] call __strlen push eax mov esi,[self] mov ecx,[pStrList.BufferUsed] add eax,ecx mov [pStrList.BufferUsed],eax cmp eax,[pStrList.BufferSize] jb .L1 push ecx and eax,0FFFFFC00h add eax,400h mov [pStrList.BufferSize],eax mov edx,eax mov eax,[pStrList.ListBuffer] call __realloc mov [pStrList.ListBuffer],eax pop ecx .L1: add ecx,[pStrList.ListBuffer] inc dword [pStrList.ListCount] mov edi,ecx mov esi,[data] pop ecx cld rep movsb pop edi esi ret endp proc StrList.SetText self,text push esi edi mov esi,[self] mov eax,[text] call __strlen cmp eax,[pStrList.BufferSize] jb .L1 and eax,0FFFFFC00h add eax,400h mov [pStrList.BufferSize],eax mov edx,eax mov eax,[pStrList.ListBuffer] call __realloc mov [pStrList.ListBuffer],eax .L1: mov edi,[pStrList.ListBuffer] mov esi,[text] xor edx,edx mov ah,0Ah .L2: lodsb or al,al je .L4 mov ah,al cmp al,0Dh je .L2 cmp al,0Ah jne .L3 xor al,al inc edx .L3: stosb jmp .L2 .L4: cmp ah,0Ah je .L5 inc edx stosb .L5: mov esi,[self] sub edi,[pStrList.ListBuffer] mov [pStrList.ListCount],edx mov [pStrList.BufferUsed],edi pop edi esi ret endp proc StrList.GetText self push esi edi mov esi,[self] mov eax,[pStrList.ListCount] add eax,[pStrList.BufferUsed] sub eax,2 lea edx,[pStrList.Text] call __strsetlength mov edi,[pStrList.Text] mov ecx,[pStrList.ListCount] mov esi,[pStrList.ListBuffer] jcxz .L3 cld jmp .L2 .L1: mov al,0Dh stosb mov al,0Ah stosb .L2: lodsb stosb or al,al jne .L2 dec edi loop .L1 .L3: xor al,al stosb pop edi esi ret endp proc StrList.Load self,szFileName locals hFile dd ? nRd dd ? endl push esi mov esi,[self] invoke CreateFile,[szFileName],GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax cmp eax,INVALID_HANDLE_VALUE je .end invoke GetFileSize,[hFile],0 mov [nRd],eax lea edx,[pStrList.Text] call __strsetlength lea eax,[nRd] mov ecx,[pStrList.Text] invoke ReadFile,[hFile],ecx,[nRd],eax,0 invoke CloseHandle,[hFile] stdcall StrList.SetText,esi,[pStrList.Text] .end: pop esi ret endp proc StrList.Save self,szFileName locals hFile dd ? nWr dd ? endl push esi stdcall StrList.GetText,[self] mov esi,[self] invoke CreateFile,[szFileName],GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0 mov [hFile],eax cmp eax,INVALID_HANDLE_VALUE je .end lea eax,[nWr] mov ecx,[pStrList.Text] invoke WriteFile,[hFile],ecx,[ecx-4],eax,0 invoke CloseHandle,[hFile] .end: pop esi ret endp Create mov [Self#.IArray],StrList.IArray mov [Self#.ListCount],Self#.prop.Strings.count mov [Self#.BufferUsed],Self#.prop.Strings.size xor eax,eax mov [Self#.Text],eax mov eax,(Self#.prop.Strings.size+100h) and 0FFFFFF00h mov [Self#.BufferSize],eax call __alloc mov [Self#.ListBuffer],eax if Self#.prop.Strings.size>0 mov edx,Self#.prop.Strings mov ecx,Self#.prop.Strings.size call __memcpy end if Destroy mov eax,[Self#.ListBuffer] call __free lea edx,[Self#.Text] call __strclear PointWork doAdd \local res ReadStr res,data,data.type,Self#.Str,0 comcall Self#.IArray,IArray,Add,res EndPoint PointWork doClear xor eax,eax mov [Self#.ListCount],eax mov [Self#.BufferUsed],eax EndPoint PointWork doText \local res ToString res,data,data.type lea ecx,[Self#.IArray] stdcall StrList.SetText,ecx,res EndPoint PointWork doLoad \local res ReadStr res,data,data.type,Self#.FileName,Self#.prop.FileName lea ecx,[Self#.IArray] stdcall StrList.Load,ecx,res EndPoint PointWork doSave \local res ReadStr res,data,data.type,Self#.FileName,Self#.prop.FileName lea ecx,[Self#.IArray] stdcall StrList.Save,ecx,res EndPoint PointVar Text,data_str lea ecx,[Self#.IArray] stdcall StrList.GetText,ecx mov eax,[Self#.Text] result equ eax EndPoint PointVar Count,data_int result equ [Self#.ListCount] EndPoint PointVar Array,data_str_array result equ Self#.IArray EndPoint EndElement