Foro de elhacker.net

Programación => Programación Visual Basic => Mensaje iniciado por: BlackZeroX en 20 Septiembre 2011, 08:24 am



Título: [SRC] cListLink (Lista enlazada... mejor dicho bloques enlazados.)
Publicado por: BlackZeroX en 20 Septiembre 2011, 08:24 am
Estoy un poco aburrido y me e puesto a hacer esto:

Esta clase la he creado para tratar un poco las listas enlazadas de la manera:

Elemento 1, Elemento 2, ... , Elemento N

Es decir que la clase EMULA las listas enlazadas que libremente se pueden escribir con punteros en C/C++ pero en listas lineales.

* No estan enlazadas en forma de arbol.

De tal modo que Dejo de sustitucion a  Redim Preserve   NO en todos los casos Ojo.

Ventajas:

* Asigna memoria dependiendo sin cambiar la hubicacion de los demas elementos ( agregacion rapida de elementos ).
* Se trata a la memoria como un bloque de bytes como cualquier otro (Generico).


Desventajas:

* No se puede usar Copymemory para copiar a mas de 1 elemento...
* Solo es utilizable para casos contados...


cListLink.cls

Código
  1.  
  2. '
  3. '   /////////////////////////////////////////////////////////////
  4. '   // Autor:   BlackZeroX ( Ortega Avila Miguel Angel )       //
  5. '   //                                                         //
  6. '   // Web:     http://InfrAngeluX.Sytes.Net/                  //
  7. '   //                                                         //
  8. '   //    |-> Pueden Distribuir Este codigo siempre y cuando   //
  9. '   // no se eliminen los creditos originales de este codigo   //
  10. '   // No importando que sea modificado/editado o engrandecido //
  11. '   // o achicado, si es en base a este codigo                 //
  12. '   /////////////////////////////////////////////////////////////
  13. '   //                                                         //
  14. '   // * Esta es una lista de 1 solo Orden... es decir no es   //
  15. '   // de ordenamiento en arbol...                             //
  16. '   //                                                         //
  17. '   /////////////////////////////////////////////////////////////
  18. '   // http://infrangelux.hostei.com/index.php?option=com_content&view=article&id=29:clistlink&catid=15:catmoduloscls&Itemid=24
  19. '   /////////////////////////////////////////////////////////////
  20.  
  21. Option Explicit
  22.  
  23. Private Const MEM_DECOMMIT = &H4000
  24. Private Const MEM_RELEASE = &H8000
  25. Private Const MEM_COMMIT = &H1000
  26. Private Const MEM_RESERVE = &H2000
  27. Private Const MEM_RESET = &H80000
  28. Private Const MEM_TOP_DOWN = &H100000
  29. Private Const PAGE_READONLY = &H2
  30. Private Const PAGE_READWRITE = &H4
  31. Private Const PAGE_EXECUTE = &H10
  32. Private Const PAGE_EXECUTE_READ = &H20
  33. Private Const PAGE_EXECUTE_READWRITE = &H40
  34. Private Const PAGE_GUARD = &H100
  35. Private Const PAGE_NOACCESS = &H1
  36. Private Const PAGE_NOCACHE = &H200
  37. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal pDest As Long, ByVal pSrc As Long, ByVal ByteLen As Long)
  38. Private Declare Function VirtualAlloc Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
  39. Private Declare Function VirtualFree Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
  40. Private Declare Function VirtualLock Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long) As Long
  41. Private Declare Function VirtualUnlock Lib "kernel32" (ByVal lpAddress As Long, ByVal dwSize As Long) As Long
  42. 'Private Declare Function IsBadReadPtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long
  43. 'Private Declare Function IsBadWritePtr Lib "kernel32" (ByVal lp As Long, ByVal ucb As Long) As Long
  44. 'Private Declare Function IsBadStringPtr Lib "kernel32" Alias "IsBadStringPtrA" (ByVal lpsz As Long, ByVal ucchMax As Long) As Long
  45. 'Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpStringDest As String, ByVal lpStringSrc As Long) As Long
  46. 'Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Long) As Long
  47. Private Declare Sub ZeroMemory Lib "kernel32.dll" Alias "RtlZeroMemory" (ByVal Destination As Long, ByVal Length As Long)
  48.  
  49. Private Declare Sub PutMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal NewVal As Long)
  50. Private Declare Sub GetMem4 Lib "msvbvm60" (ByVal Addr As Long, ByVal RetVal As Long)
  51.  
  52. Dim pfirst          As Long
  53. Dim pLast           As Long
  54. Dim lSize           As Long
  55.  
  56. Const SIZEAB        As Long = &H8
  57. Const BEFORESIZE    As Long = &H0
  58. Const AFTERSIZE     As Long = (BEFORESIZE + &H4)
  59.  
  60. Public Function release(ByVal pStream As Long) As Boolean
  61. Dim lSizeF      As Long
  62. Dim pAfter       As Long
  63. Dim pBefore     As Long
  64.    If (pStream = &H0) Then Exit Function
  65.    lSizeF = (SIZEAB + lSize)
  66.    pAfter = after(pStream)
  67.    pBefore = before(pStream)
  68.    VirtualUnlock pStream, lSizeF
  69.    VirtualFree pStream, lSizeF, MEM_DECOMMIT
  70.    VirtualFree pStream, 0, MEM_RELEASE
  71.    If (pAfter) Then putBefore pAfter, pBefore
  72.    If (pBefore) Then putAfter pBefore, pAfter
  73.    If (pStream = pfirst) Then pfirst = pBefore
  74.    If (pStream = pLast) Then pLast = pAfter
  75.    release = True
  76. End Function
  77.  
  78. Public Function getPtr(ByVal lIndex As Long) As Long
  79. '   //  Retorna el puntero del elemento indicado en lIndex.
  80. Dim pTmp            As Long
  81. Dim i               As Long
  82.    pTmp = first()
  83.    Do Until (pTmp = &H0)
  84.        i = (i + &H1)
  85.        If (i > lIndex) Then Exit Do
  86.        pTmp = after(pTmp)
  87.    Loop
  88.    getPtr = pTmp
  89. End Function
  90.  
  91. Public Property Get size() As Long
  92.    size = lSize
  93. End Property
  94.  
  95. Public Property Let size(ByVal lVal As Long)
  96.    Call clear
  97.    lSize = lVal
  98. End Property
  99.  
  100. Friend Sub writeStream(ByVal pStruct As Long, ByVal pData As Long)
  101. '   //  Setea los valores en el bloque de la memoria de la lista enlazada.
  102.    CopyMemory pStruct, pData, lSize
  103. End Sub
  104.  
  105. Friend Function readStream(ByVal pStruct As Long, ByVal pData As Long)
  106. '   //  Retorna los valores del bloque de la lista enlazada a una bloque.
  107.    CopyMemory pData, pStruct, lSize
  108. End Function
  109.  
  110.  
  111. '   //  Estas funciones otienen el 1er y ultimo elemento agregado a la lista.
  112. Friend Function first() As Long
  113.    first = pfirst
  114. End Function
  115.  
  116. Friend Function last() As Long
  117.    last = pLast
  118. End Function
  119.  
  120.  
  121. '   //  funciones iteradoras.
  122. Friend Function after(ByVal pStruct As Long) As Long    '   //  Rectorna del puntero al bloque que se agrego despues de pStruct
  123. Dim pTmp            As Long
  124.    If (pStruct = &H0) Then Exit Function
  125.    GetMem4 ByVal (pStruct + lSize + AFTERSIZE), VarPtr(pTmp)
  126.    after = pTmp
  127. End Function
  128.  
  129. Friend Function before(ByVal pStruct As Long) As Long   '   //  Rectorna del puntero al bloque anteriormente agregado de pStruct
  130. Dim pTmp            As Long
  131.    If (pStruct = &H0) Then Exit Function
  132.    GetMem4 ByVal (pStruct + lSize + BEFORESIZE), VarPtr(pTmp)
  133.    before = pTmp
  134. End Function
  135.  
  136. Friend Function addNew() As Long                        '   //  Agrega un nuevo bloque y lo enlaza.
  137. Dim lSizeF      As Long
  138. Dim pNew        As Long
  139.    lSizeF = (SIZEAB + lSize)
  140.    pNew = VirtualAlloc(ByVal 0&, lSizeF, MEM_COMMIT, PAGE_EXECUTE_READWRITE)
  141.    VirtualLock pNew, lSizeF
  142.    ZeroMemory pNew, lSizeF                             '   //  llenamos de 0 el bloque.
  143.    If (pLast) Then                                     '   //  Actualizamos el ultimo...
  144.        putBefore pNew, pLast
  145.        putAfter pLast, pNew
  146.    End If
  147.    If (pfirst = &H0) Then pfirst = pNew
  148.    pLast = pNew
  149.    addNew = pNew
  150. End Function
  151.  
  152. Private Sub putAfter(ByVal pStruct As Long, ByVal pAfter As Long)
  153.    If (pStruct = &H0) Then Exit Sub
  154.    PutMem4 (pStruct + lSize + AFTERSIZE), pAfter        '   //  pNew.After
  155. End Sub
  156.  
  157. Private Sub putBefore(ByVal pStruct As Long, ByVal pBefore As Long)
  158.    If (pStruct = &H0) Then Exit Sub
  159.    PutMem4 (pStruct + lSize + BEFORESIZE), pBefore     '   //  pNOW.BEFORE
  160. End Sub
  161.  
  162. Public Function clear() As Long                         '   //  Libera la memoria asignada y retorna la cantidad liberada en bytes.
  163. Dim lSizeRet        As Long
  164. Dim pTmp            As Long
  165.    pTmp = first()      '   //  Seteamos el 1ro.
  166.    Do Until (release(pTmp) = False)
  167.        lSizeRet = (lSizeRet + lSize + SIZEAB)
  168.        pTmp = first()
  169.    Loop
  170.    clear = lSizeRet
  171. End Function
  172.  
  173. Private Sub Class_Terminate()
  174.    Call clear
  175. End Sub
  176.  
  177.  

Ejemplo de uso

Código
  1.  
  2. Option Explicit
  3.  
  4. Private Type DATOSPERSONALES
  5.    edad        As Long
  6.    categoria   As Long
  7.    nombre      As String * 20
  8.    apellidoP   As String * 10
  9.    apellidoM   As String * 10
  10. End Type
  11.  
  12. Private Sub Form_Load()
  13. Dim oList       As cListLink
  14. Dim tDatosP     As DATOSPERSONALES      '   //  Plantilla...
  15. Dim pElement    As Long                 '   //  Puntero al elemento...
  16.  
  17.    Set oList = New cListLink
  18.  
  19.    oList.size = LenB(tDatosP)                                  '   //  Tamaño de la estructura (bloque de datos).
  20.  
  21.    With tDatosP
  22.        .edad = 22
  23.        .categoria = 1
  24.        .nombre = "Miguel Angel"
  25.        .apellidoP = "Ortega"
  26.        .apellidoM = "Avila"
  27.    End With
  28.    Call oList.writeStream(oList.addNew(), VarPtr(tDatosP))     '   //  Escribimos la estructura en una lista enlazada.
  29.  
  30.    With tDatosP
  31.        .edad = 42
  32.        .categoria = 2
  33.        .nombre = "Angel"
  34.        .apellidoP = "Ortega"
  35.        .apellidoM = "Hernandez"
  36.    End With
  37.    Call oList.writeStream(oList.addNew(), VarPtr(tDatosP))     '   //  Escribimos la estructura en una lista enlazada.
  38.  
  39.    With tDatosP
  40.        .edad = 19
  41.        .categoria = 2
  42.        .nombre = "Maria Luisa"
  43.        .apellidoP = "Beltran"
  44.        .apellidoM = "Ramirez"
  45.    End With
  46.    Call oList.writeStream(oList.addNew(), VarPtr(tDatosP))     '   //  Escribimos la estructura en una lista enlazada.
  47.  
  48.  
  49.    'Call oList.release(oList.before(oList.firts()))             '   //  Liberamos el 2 registro ("Angel Ortega Hernandez"), para eso obtenemos el 1 elemento y obtenemos el siguiente elemento con before...
  50.    Call oList.release(oList.getPtr(1))                         '   //  Eliminamos el elemento con Index 1
  51.  
  52.    '   //  Retornamos los elementos...
  53.  
  54.    pElement = oList.first()
  55.  
  56.    Do Until (pElement = &H0)
  57.  
  58.        oList.readStream pElement, VarPtr(tDatosP)
  59.        With tDatosP
  60.            Debug.Print "Nombre:", .nombre
  61.            Debug.Print "ApellidoP:", .apellidoP
  62.            Debug.Print "ApellidoM:", .apellidoM
  63.            Debug.Print "Edad:", .edad
  64.            Debug.Print "Categoria:", .categoria
  65.            Debug.Print
  66.            Debug.Print
  67.            Debug.Print
  68.        End With
  69.        pElement = oList.after(pElement)
  70.    Loop
  71.  
  72.    Set oList = Nothing
  73.  
  74. End Sub
  75.  
  76.  

Temibles Lunas!¡.