Me ha surgido la necesidad de guardar un array en un fichero. En principio no hay problemas, lo codifico con ASave() y lo guardo con MEMOWRIT(). Después lo recupero con MEDMOREAD() y reconstruyo el array con AREad(). Hasta ahí todo bien. El problema aparece cuando tengo que codificar un array muy grande. Y es que ASave()y ARead() sólo funcionna con arrays de hasta 256 elementos y elementos de hasta 256 caracteres. Si hay más de 256 elementos (en alguna dimensión) o algún elemento mide más de 256 caracteres, ASave() no funciona porque trabaja con BYTES.
SOLUCIÓN: he implementado dso funciones, prácticamente copiadas de ASave() y ARead() pero que trabajan con WORDS y ahora puedo codificar arrays de hasta 65536 elementos.
Estas son las funciones:
- Code: Select all Expand view
- FUNCTION ADblSave( aArray )
LOCAL n, cType, uData
LOCAL cInfo := ""
*
FOR n = 1 to Len( aArray )
cType = ValType( aArray[ n ] )
DO CASE
CASE cType == "A"
cInfo += ADblSave( aArray[ n ] )
CASE cType == "O"
cInfo += aArray[ n ]:Save()
otherwise
cInfo += ( cType + D2Bin( Len( uData := cValToChar( aArray[ n ] ) ) ) + uData )
ENDCASE
NEXT
RETURN "A" + D2Bin( 8 + Len( cInfo ) ) + D2Bin( Len( aArray ) ) + cInfo
*
FUNCTION ADblRead( cInfo )
LOCAL nPos := 10, nLen, n
LOCAL aArray, cType, cBuffer
*
nLen = Bin2d( SubStr( cInfo, nPos, 8 ) )
nPos += 8
aArray = Array( nLen )
*
FOR n = 1 to Len( aArray )
cType = SubStr( cInfo, nPos++, 1 )
nLen = Int(Bin2d( SubStr( cInfo, nPos, 8 ) ))
nPos += 8
cBuffer = SubStr( cInfo, nPos, nLen )
nPos += nLen
DO CASE
CASE cType == "A"
aArray[ n ] = ADblRead( "A" + D2Bin( nLen ) + cBuffer )
CASE cType == "O"
aArray[ n ] = ORead( cBuffer )
CASE cType == "C"
aArray[ n ] = cBuffer
CASE cType == "D"
aArray[ n ] = CToD( cBuffer )
CASE cType == "L"
aArray[ n ] = ( cBuffer == ".T." )
CASE cType == "N"
aArray[ n ] = Val( cBuffer )
ENDCASE
NEXT
RETURN aArray
Espero que os sirva.
Saludos.