On-line: Pasha, гостей 2. Всего: 3 [подробнее..]
АвторСообщение



Пост N: 58
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 23.04.07 09:17. Заголовок: Тонкая работа с .mem - файлами


Я храню в .mem-файлах (т.е. save-restore) параметры конфигурации программы, которых м.б. много. Очень полезно иметь такое средство - получить из любого файла значение любой переменной (но не присваивать это значение такой переменной!). Если нет стандартных средств - кто бы подсказал формат .mem-файла, я бы написал. Может, ещё кому сгодится.

Спасибо: 0 
Профиль
Ответов - 7 [только новые]


модератор




Пост N: 473
Зарегистрирован: 25.05.05
ссылка на сообщение  Отправлено: 23.04.07 10:01. Заголовок: Re:


AM пишет:

 цитата:
Если нет стандартных средств - кто бы подсказал формат .mem-файла, я бы написал.


Можешь забрать утилиту по адресу:
http://gfilatov.front.ru/READMEM.ZIP


Спасибо: 0 
Профиль



Пост N: 59
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 23.04.07 12:01. Заголовок: Re:


Спасибо, Григорий, это, похоже - то, что надо. Сейчас времени нет, как будет - причешу в удобный вид. Как я понял, в Харборе формат такой же, как и в Клиппере.

Спасибо: 0 
Профиль



Пост N: 60
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 24.04.07 10:59. Заголовок: Получилась полезная функция


После причёски (отбрасывания лишнего) получилось так:
function get_var(file,varName)
local b:=fopen(file),f_len,xVarValue,cID,cBuffer,cMemBuffer,nSize,nLen,cData
local nHi,nLon,Value,lFlag,nB1,nB2,nB3,nB4,nTotal,nOutput
if b<0
return nil
endif
f_len=fseek(b,0,2)
fseek(b,0)
do while fseek( b, 0, 1 ) + 1 < f_len .and. !FEOF( b )
cMemBuff := space( 18 )
fread( b, @cMemBuff, 18 )
cVarName := left( cMemBuff, at( chr( 0 ), cMemBuff ) - 1 )
cID := substr( cMemBuff, 12, 1 )
nSize := bin2w( right( cMemBuff, 2 ) )
nLen := if( cID $ "ГМ", 14 + nSize, 22 )
cBuffer := space( nLen )
fread( b, @cBuffer, nLen )
cData := substr( cBuffer, 15 )
if cVarName=upper(varName) //нашли нужную переменную
if cID == chr( 195 ) // character Г
xVarValue := cData
elseif cID == chr( 204 ) // logic М
xVarValue := asc( cData ) == 1
elseif cID == chr( 206 ) // Numeric О
cBuffer := substr( cBuffer, 15 )
nHi := MODULUS( asc( substr( cBuffer, 8, 1 ) ), 128 ) * 16
nLo := int( asc( substr( cBuffer, 7, 1 ) ) / 16 )
nValue := nHi + nLo - 1023
lFlag := int( asc( substr( cBuffer, 8, 1 ) ) / 16 ) >= 8
nB1 := MODULUS( asc( substr( cBuffer, 7, 1 ) ), 16 ) / 16
nB2 := bin2w( substr( cBuffer, 5, 2 ) ) / ( 65536 * 16 )
nB3 := bin2w( substr( cBuffer, 3, 2 ) ) / ( 65536 * 65536 * 16 )
nB4 := bin2w( substr( cBuffer, 1, 2 ) ) / ( 65536 * 65536 * 65536 * 16 )
nTotal := nB1 + nB2 + nB3 + nB4
nOutput := if( lFlag, - ( 1 + nTotal ) * 2 ^ nValue, ( 1 + nTotal ) * 2 ^ nValue )
xVarValue := val( transform( nOutput, "@B" ) )
elseif cID == chr( 196 ) // Date
cBuffer := substr( cBuffer, 15 )
nHi := MODULUS( asc( substr( cBuffer, 8, 1 ) ), 128 ) * 16
nLo := int( asc( substr( cBuffer, 7, 1 ) ) / 16 )
nValue := nHi + nLo - 1023
lFlag := int( asc( substr( cBuffer, 8, 1 ) ) / 16 ) >= 8
nB1 := MODULUS( asc( substr( cBuffer, 7, 1 ) ), 16 ) / 16
nB2 := bin2w( substr( cBuffer, 5, 2 ) ) / ( 65536 * 16 )
nB3 := bin2w( substr( cBuffer, 3, 2 ) ) / ( 65536 * 65536 * 16 )
nB4 := bin2w( substr( cBuffer, 1, 2 ) ) / ( 65536 * 65536 * 65536 * 16 )
nTotal := nB1 + nB2 + nB3 + nB4
nOutput := if( lFlag, - ( 1 + nTotal ) * 2 ^ nValue, ( 1 + nTotal ) * 2 ^ nValue )
xVarValue := dtoc( ctod( "01/01/0100" ) + nOutput - 1757585 )
endif
exit
endif //нашли нужную переменную
enddo
fclose( b )
return xVarValue
function FEOF( nHandle )
local nCurrPos,nFileSize
nCurrPos := fseek( nHandle, 0, 1 )
nFileSize := fseek( nHandle, 0, 2 )
fseek( nHandle, nCurrPos, 0 )
return nFileSize < nCurrPos
function MODULUS( nParm1, nParm2 )
local x,nRetVal := 0
if valtype( nParm1 ) = "N" .and. valtype( nParm2 ) = "N"
if nParm2 = 0
nRetVal := nParm1
else
x := nParm1 % nParm2
nRetVal := if( x * nParm2 < 0, x + nParm2, x )
endif
endif
return nRetVal

Хотя исходная читалка тоже полезная.

Спасибо: 0 
Профиль
постоянный участник


Пост N: 309
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 24.04.07 13:33. Заголовок: Re:


Покритикуем?!
Не вникая в код, но уже на первый поверхностный взгляд обратил внимание, что имеются две переменные varName и cVarName, причем cVarName не объявлена.
Вообще-то это плохая практика называть две переменные одинаковым именем за исключением префикса, который опередляет тип данных переменной. Читая подобный код можно подумать, что программист просто сделал опечатку, забыв в спешке перед varName указать префикс 'c'.
Также я советую свои проверки типа

if valtype( nParm1 ) = "N" .and. valtype( nParm2 ) = "N"

заменять общепринятыми макросами

if isnumber( nParm1 ) .and. isnumber( nParm2 )

А самое главное из программы вообще не возможно понять, а какова структура этого файла, с которым работает функция!
Если бы кому-то пришлось сопровождать ваш код, то ему потребовалось наверное дня два, чтобы разобраться в вашем коде. То есть слету ваш код читать очень тяжело!

А главное в программах- это что? Это чтобы другим была понятна ваша программа!
Простите старика за ворчание!

Спасибо: 0 
Профиль



Пост N: 61
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 24.04.07 16:21. Заголовок: Re:


Григорьев Владимир пишет:

 цитата:
причем cVarName не объявлена.


Да, это в процессе причёски забыл. А вообще программа не моя, я её только слегка приспособил под свои нужды (надеюсь, не только свои). Мне показал её gfilatov, а мои переделки минимальны, я из неё больше выкинул, чем добавил. Использовать можно и не вполне понимая. Хотя хорошо бы сделать возможным не только читать, но и менять переменные в файлах. Но это и сложней, и менее нужно.




Спасибо: 0 
Профиль



Пост N: 85
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 14.08.07 09:53. Заголовок: Обнаружилась неувязочка


Вдруг обнаружил такую неувязочку: при вытаскивания из файла символьной переменной она становится на байт длиннее (сзади присобачивается chr(0)). Наверно, что-то изменилось, вроде раньше этого не было, да и исходная программа-то работала. Видимо, изменился формат записи.
Пришлось вместо
nSize := bin2w( right( cMemBuff, 2 ) )
сделать
nSize := bin2w( right( cMemBuff, 2 ) ) - 1


Спасибо: 0 
Профиль



Пост N: 86
Зарегистрирован: 15.12.06
ссылка на сообщение  Отправлено: 14.08.07 14:53. Заголовок: Re:


Опять не так. Там оставить как было. nSize := bin2w( right( cMemBuff, 2 ) )
Но вместо

if cID == chr( 195 ) // character Г
xVarValue := cData

надо

if cID == chr( 195 ) // character Г
xVarValue := left(cData,nSize-1)
Теперь вроде работает.

Спасибо: 0 
Профиль
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 79
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет