Definizione ed uso dei Memory Stream
La classe Memory-Stream crea flussi che utilizzano la memoria, anziché un disco o una connessione di rete. Pertanto, i "Memory-Stream" sono dei flussi di dati in memoria.
Con Gambas-3 non è più possibile usare un puntatore (Pointer) in uno stream. Si deve invece utilizzare uno stream di memoria con l'istruzione MEMORY.
Sintassi:
Flusso = MEMORY Puntatore FOR [ READ ] [ WRITE ]
- Se la parola chiave READ viene specificata, allora è permessa la lettura.
- Se la parola chiave WRITE viene specificata, allora è permessa la scrittura.
Memory Stream in modalità "For Write"
La modalità in "Scrittura" (For Write) risulta utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata. Si può quindi scrivere nella variabile Stream con l'istruzione "Write" o anche con l'istruzione "Print".
Per esempio, se si intende creare una sequenza di byte &h80, &h81, &h82, &h83, lo si può fare con i chr(); oppure si può scrivere:
Public Sub Button1_Click() Dim p As Pointer Dim sW As Stream Dim bW As Byte p = Alloc(4) ' riserviamo 4 byte da qualche parte in memoria sW = Memory p For Write ' questa memoria sarà un flusso (stream) che creeremo appositamente, e... ' ...nel quale andiamo a scrivere i 4 valori byte. ' Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati: For bW = 80 to 83 Write #sW, bW As Byte Next End
Secondo esempio - scriviamo nello Stream un testo, poi lo recuperiamo leggendo lo Stream:
Public Sub Button1_Click() Dim p As Pointer Dim st As Stream Dim s, ss As String Dim j As Byte p = Alloc(4) st = Memory p For Read Write s = "testo qualsiasi" ' Scriviamo la stringa nella variabile di tipo "Stream": Print #st, s ''''''''''''''' ' Leggiamo nella variabile di tipo "Stream" ' In caso di contenuto di tipo "stringa", ' è necessario impostare anche la funzione "Seek". ' In questo semplice esempio "Seek" avrà un indice costante pari a zero: Seek #st, 0 Line Input #st, ss Print "Contenuto dello stream: "; ss ' Liberiamo la parte di memoria precedentemente allocata: Free(p) End
Terzo esempio - leggiamo con l'istruzione Shell congiunta al comando bash "ls" nella cartella "/proc", e riportiamo in una TextArea il contenuto ivi letto distinguendo ciascuna sub-cartella o file mediante Line Input:
Public Sub Button1_Click() Dim s, ss As String Dim p As Pointer Dim m As Stream Dim j As Integer Shell "ls /proc" To s ' Allochiamo sufficiente memoria, ' e vi puntiamo con una variabile di tipo "puntatore": p = Alloc(2048) ' Creiamo la variabile "m" di tipo "Stream": m = Memory p For Read Write ' Scriviamo nella variabile "m" il contenuto della variabile stringa "s": Print #m, s While Not Eof(m) ' Guidiamo la lettura nella variabile "m" mediante il comando "Seek": Seek #m, j Line Input #m, ss ' Se non vi sono più dati relativi a caratteri alfanumerici, allora si esce dal ciclo: If ss = "" Then Exit TextArea1.Text = TextArea1.Text & ss & Chr(10) ' Si dà il valore al comando "Seek per far cominciare" ' la lettura dal byte corrispondente nella variabile "s" ad ogni inizio riga: j = j + Len(ss) + 1 Wend End
Memory Stream in modalità "For Read"
In modalità "For Read" i Memory-Stream possono essere usati per dereferenziare i puntatori.
Abbiamo visto nell'esempio del paragrafo precedente, relativo alla modalità in "scrittura" dei Memory-Stream, che quattro valori numerici sono stati memorizzati in un area riservata, pumtata dalla variabile puntatore "p".
Ora procediamo a dereferenziare quella variabile di tipo pointer, e ad estrarre i valori contenuti nell'aera riservata di memoria:
Public Sub Button2_Click() Dim p As Pointer Dim sR As Stream Dim j, bR As Byte sR = Memory p For Read For j = 0 To 3 ' Il puntatore nello Stream avanzerà di un byte per volta coerentemente con l'area della memoria allocata: Read #sR, bR ' A fini didattici, mostriamo il valore in console Print "---> ", bR Next
In modalità "Lettura" per dereferenziare i puntatori passati da funzioni esterne
Si procederà ugualmente per dereferenziare i puntatori passati da funzioni esterne.
Public Sub Button1_Click() Dim pEst As Pointer Dim pS As Stream Dim by As Byte ' Prendiamo da una funzione esterna un valore di tipo puntatore: funzione_esterna_che_passa_un puntatore(pEst) ' Usiamo i Memory Stream in modalità di "lettura": pS = Memory pEst For Read 'Andiamo a dereferenziare e, quindi, a leggere il dato: Read #pS, by ' Ora, a fini didattici, mostriamo il valore in console: Print by End