51

Re: AHK: Сохранение Массива в файл

В моём варианте есть несколько отличий:
- пользователю не нужно предварительно подготавливать содержимое многострочных переменных;
- синтаксис функций очень похож на привычные  IniRead и IniWrite;
- я не ставил задачу сохранения массивов, просто многим интересно было бы сохранять многострочные переменные без особых костылей.

52

Re: AHK: Сохранение Массива в файл

Не вижу отличий:

Win_Counts_1 =
(
http://worldoftanks.ru Home - ROBLOX
ok.ru
)

MyIniWrite(Win_Counts_1, "Filename.ini", "Section", "Key")
MyIniRead(OutputVar, "Filename.ini", "Section", "Key", "MyError")
MsgBox, % OutputVar
Return

MyIniWrite(Value, Filename, Section, Key)
{
   Loop, Parse, value, `r`n
      IniWrite, %A_LoopField%, %Filename%, %Section%, %A_Index%|%Key%
}


MyIniRead(ByRef OutputVar, Filename, Section, Key, ByRef Default)
{
   loop
   {
      IniRead, Value, %Filename%, %Section%, %A_Index%|%Key%, %Default%
      If (Value = Default)
         break
      If A_Index = 1
         OutputVar := value 
      else
         OutputVar .= "`n" value
    }
}

53 (изменено: stealzy, 2017-02-23 21:23:30)

Re: AHK: Сохранение Массива в файл

ypppu, зачем <linefeed> выдумывать? У нас в AHK уже есть `n. А если строка содержит <linefeed>, что делать?

Win_Counts_1 =
(
http://worldoftanks.ru`n
Home - ROBLOX
ok.ru
--
)

MyIniWrite(Win_Counts_1, "Filename.ini", "Section", "Key")
value := MyIniRead("Filename.ini", "Section", "Key", "MyError")
MsgBox % value
Return

MyIniWrite(val, Filename, Section, Key) {
	StringReplace val, val, `n, ``n, All
	IniWrite %val%, %Filename%, %Section%, %Key%
}
MyIniRead(Filename, Section, Key, ByRef Default) {
	IniRead  val, %Filename%, %Section%, %Key%, %Default%
	StringReplace, val, val, ``n, `n, All
	Return val
}

Вообще дались вам эти ini функции. Я использую простую запись в файл в формате json в одном своем скрипте и ничего интересного в этом не вижу.

54

Re: AHK: Сохранение Массива в файл

Malcev пишет:

Не вижу отличий:

По сути то же самое, да.

stealzy пишет:

ypppu, зачем <linefeed> выдумывать? У нас в AHK уже есть `n. А если строка содержит <linefeed>, что делать?

А если строка содержит `n ? Я ж сразу написал, что можно любой другой разделитель подставить.
А функции полезные, люди иногда спрашивают, интересуются.

55 (изменено: stealzy, 2017-02-23 21:58:22)

Re: AHK: Сохранение Массива в файл

ypppu пишет:

А если строка содержит `n ?

Вопрос интересный с точки зрения написания парсера, потому и спрашиваю).

Win_Counts_1 =
(
http://worldoftanks.ru``n--
Home - ROBLOX
)

MyIniWrite(Win_Counts_1, "Filename.ini", "Section", "Key")
value := MyIniRead("Filename.ini", "Section", "Key", "MyError")
MsgBox % value
Return

MyIniWrite(val, Filename, Section, Key) {
	StringReplace val, val, ``, -temp-, All
	StringReplace val, val, `n, ``n, All
	StringReplace val, val, -temp-, ````, All
	IniWrite %val%, %Filename%, %Section%, %Key%
}
MyIniRead(Filename, Section, Key, ByRef Default) {
	IniRead  val, %Filename%, %Section%, %Key%, %Default%
	StringReplace, val, val, ````, -temp-, All
	StringReplace, val, val, ``n, `n, All
	StringReplace, val, val, -temp-, ````, All
	Return val
}

Можно ли обойтись без -temp-?
Нужно заменить все переносы строки на `n, а ` экранировать этим же символом.

56

Re: AHK: Сохранение Массива в файл

stealzy, все эти замены ненадёжны:

Win_Counts_1 =
(
http://worldoftanks.ru-temp-``n--
Home - ROBLOX
)

57 (изменено: stealzy, 2017-02-23 21:59:58)

Re: AHK: Сохранение Массива в файл

Malcev, я про то и спрашиваю, как без них обойтись. Пример в 55 сообщении подправлен.

58 (изменено: Malcev, 2017-02-23 22:01:23)

Re: AHK: Сохранение Массива в файл

Не работает ваш пример:

Win_Counts_1 =
(
http://worldoftanks.ru-temp-``n--
Home - ROBLOX
)
MsgBox % Win_Counts_1

MyIniWrite(Win_Counts_1, "Filename.ini", "Section", "Key")
value := MyIniRead("Filename.ini", "Section", "Key", "MyError")
MsgBox % value
Return

MyIniWrite(val, Filename, Section, Key) {
	StringReplace val, val, ``, -temp-, All
	StringReplace val, val, `n, ``n, All
	StringReplace val, val, -temp-, ````, All
	IniWrite %val%, %Filename%, %Section%, %Key%
}
MyIniRead(Filename, Section, Key, ByRef Default) {
	IniRead  val, %Filename%, %Section%, %Key%, %Default%
	StringReplace, val, val, ````, -temp-, All
	StringReplace, val, val, ``n, `n, All
	StringReplace, val, val, -temp-, ````, All
	Return val
}

Malcev, я про то и спрашиваю, как без них обойтись

52 пост.

59

Re: AHK: Сохранение Массива в файл

Malcev, вы уже дважды пишете что не работает, то что и не должно работать :@.
Вопрос то был, как без замен сделать.

60

Re: AHK: Сохранение Массива в файл

Так я и пишу, что в 52 посте сделано без замен.
Или вы мы про разные замены говорим?

61 (изменено: stealzy, 2017-02-23 22:35:04)

Re: AHK: Сохранение Массива в файл

Вроде понял: команда StringReplace val, val, `n, ``n, All заменяет без разбору, как переносы строки, так и сочетание символов `n. Т.е. после прохода такой заменой отличить одно от другого невозможно, вот в чем проблема.
А команда Loop, Parse, value, `n различает такие вещи. Malcev прав.

62

Re: AHK: Сохранение Массива в файл

+ stealzy
stealzy пишет:

Offtop: migomigo даже If Else не умеет использовать.

У вас другого способа самоутверждения кроме как пыжится собственным величием, гениального программиста  - нет?

Если вы тоже хотите стать разработчиком, добавьте скрипт, и модераторы моментально это отметят.

Даже мне, художнику-дизайнеру, с гуманитарным складом ума удалось пополнить коллекцию скриптов этого замечательного форума!
Вашему гению, с намного большими познаниями в матемматических науках, это может удастся намного лучше моего!
Как вы считаете?

Вас модератор уже спрашивал о вашей разработке.
http://forum.script-coding.com/viewtopi … 27#p112727
Это ваш шанс!

AutoHotKey Version: 1.1.09.02
Не спеши, а то успеешь..

63 (изменено: serzh82saratov, 2017-03-07 18:29:00)

Re: AHK: Сохранение Массива в файл

Уже выкладывал одну версию, теперь хочу добавить в коллекцию в таком виде.

Так как функции RawObject, RawObjectSize, ObjLoad настолько же изменил насколько их понял (то есть оставил почти в оригинале), то хочу спросить не находит ли кто ошибок, и нужно ли это в коллекции?


#SingleInstance Force
#NoEnv

Arr := {"1key":{2key:[,,"value"]}}
Base64 := ObjToBase64(Arr)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
MsgBox % Obj.1key.2key[3]

Prefix := {"LAlt":"<!","LCtrl":"<^","LShift":"<+","LWin":"<#"}
Base64 := ObjToBase64(Prefix)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
for k, v in Obj
	MsgBox % k " : " v


B := ["Ivan", 345, "London"]
Base64 := ObjToBase64(B)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
for k, v in Obj
	MsgBox % k " : " v



ObjToBase64(obj) {
	If !IsObject(obj)
		Return
	VarSetCapacity(Bin, Size := RawObjectSize(obj, 0) + 8, 0)
    RawObject(obj, NumPut(Size - 8, 0 + (addr := &Bin), "Int64"), 0)
	DllCall("Crypt32.dll\CryptBinaryToString" (A_IsUnicode ? "W" : "A")
		, Ptr, addr, UInt, Size, UInt, 0x00000001|0x40000000, UInt, 0, UIntP, TChars, "CDECL Int")
	VarSetCapacity(Base64, Req := TChars * (A_IsUnicode ? 2 : 1 ))
	DllCall("Crypt32.dll\CryptBinaryToString" (A_IsUnicode ? "W" : "A")
		, Ptr, addr, UInt, Size, UInt, 0x00000001|0x40000000, Str, Base64, UIntP, Req, "CDECL Int")
	Return Base64
}

ObjFromBase64(Base64) {
	DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), UInt, &Base64
		, UInt, StrLen(Base64), UInt, 1, UInt, 0, UIntP, Bytes, Int, 0, Int, 0, "CDECL Int")
	VarSetCapacity(OutData, Req := Bytes * (A_IsUnicode ? 2 : 1))
	DllCall("Crypt32.dll\CryptStringToBinary" (A_IsUnicode ? "W" : "A"), UInt, &Base64
		, UInt, StrLen(Base64), UInt, 1, Str, OutData, UIntP, Req, Int, 0, Int, 0, "CDECL Int")
	Return ObjLoad(&OutData)
}

RawObject(obj, addr, buf := 0, objects := 0) {
	; Type.Enum:    Char.1 UChar.2 Short.3 UShort.4 Int.5 UInt.6 Int64.7 UInt64.8 Double.9 String.10 Object.11
	; Negative for keys and positive for values
	if !objects
		objects:={(""):0,(obj):0}
	else objects[obj]:=(++objects[""])
	for k,v in obj
	{ ; 9 = Int64 for size and Char for type
		If IsObject(k){
			If objects.HasKey(k)
				NumPut(-12,addr+0,"Char"),NumPut(objects[k],addr+1,"Int64"),addr+=9
			else NumPut(-11,addr+0,"Char"),NumPut(sz:=RawObjectSize(k,buf),addr+1,"Int64"),RawObject(k,addr+9,buf,objects),addr+=sz+9
		}else if (k+0="")
			NumPut(-10,addr+0,"Char"),NumPut(sz:=StrPut(k,addr+9)*2,addr+1,"Int64"),addr+=sz+9
		else NumPut( InStr(k,".")?-9:k>4294967295?-8:k>65535?-6:k>255?-4:k>-1?-2:k>-129?-1:k>-32769?-3:k>-2147483649?-5:-7,addr+0,"Char")
			,NumPut(k,addr+1,InStr(k,".")?"Double":k>4294967295?"UInt64":k>65535?"UInt":k>255?"UShort":k>-1?"UChar":k>-129?"Char":k>-32769?"Short":k>-2147483649?"Int":"Int64")
			,addr+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v){
			if objects.HasKey(v)
				NumPut( 12,addr+0,"Char"),NumPut(objects[v],addr+1,"Int64"),addr+=9
			else NumPut( 11,addr+0,"Char"),NumPut(sz:=RawObjectSize(v,buf),addr+1,"Int64"),RawObject(v,addr+9,buf,objects),addr+=sz+9
			}else if (v+0="")
		NumPut( 10,addr+0,"Char"),NumPut(sz:=buf?obj.GetCapacity(k):StrPut(v)*2,addr+1,"Int64"),DllCall("RtlMoveMemory","PTR",addr+9,"PTR",buf?obj.GetAddress(k):&v,"PTR",sz),addr+=sz+9
		else NumPut(InStr(v,".")?9:v>4294967295?8:v>65535?6:v>255?4:v>-1?2:v>-129?1:v>-32769?3:v>-2147483649?5:7,addr+0,"Char")
			,NumPut(v,addr+1,InStr(v,".")?"Double":v>4294967295?"UInt64":v>65535?"UInt":v>255?"UShort":v>-1?"UChar":v>-129?"Char":v>-32769?"Short":v>-2147483649?"Int":"Int64")
			,addr+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
}

RawObjectSize(obj,buf:=0,objects:=0){
	if !objects
		objects:={(obj):1}
	else if !objects.HasKey(obj)
		objects[obj]:=1
	for k,v in obj
	{
		If IsObject(k)
			sz+=objects.HasKey(k)?9:RawObjectSize(k,buf,objects)+9
		else if (k+0="")
			sz+=StrPut(k)*2+9
		else sz+=InStr(k,".")||k>4294967295?9:k>65535?5:k>255?3:k>-129?2:k>-32769?3:k>-2147483649?5:9
		If IsObject(v)
			sz+=objects.HasKey(v)?9:RawObjectSize(v,buf,objects)+9
		else if (v+0="")
			sz+=(buf?obj.GetCapacity(k):StrPut(v)*2)+9
		else sz+=InStr(v,".")||v>4294967295?9:v>65535?5:v>255?3:v>-129?2:v>-32769?3:v>-2147483649?5:9
	}
	return sz
}

ObjLoad(addr, objects := 0) {
	obj:=[],end:=addr+8+(sz:=NumGet(addr+0,"Int64")),addr+=8
	if !objects
		objects:={0:obj}
	else objects.Push(obj)
	While addr<end{ ; 9 = Int64 for size and Char for type
		If NumGet(addr+0,"Char")=-12
			k:=objects[NumGet(addr+1,"Int64")],addr+=9
		else if NumGet(addr+0,"Char")=-11
			k:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
		else if NumGet(addr+0,"Char")=-10
			sz:=NumGet(addr+1,"Int64"),k:=StrGet(addr+9),addr+=sz+9
		else k:=NumGet(addr+1,SubStr("Char  UChar Short UShortInt   UInt  Int64 UInt64Double",(sz:=-NumGet(addr+0,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
		If NumGet(addr+0,"Char")= 12
			obj[k]:=objects[NumGet(addr+1,"Int64")],addr+=9
		else if NumGet(addr+0,"Char")= 11
			obj[k]:=ObjLoad(addr+1,objects),addr+=9+NumGet(addr+1,"Int64")
		else if NumGet(addr+0,"Char")= 10
			obj[k]:=StrGet(addr+9),obj.SetCapacity(k,sz:=NumGet(addr+1,"Int64")),DllCall("RtlMoveMemory","PTR",obj.GetAddress(k),"PTR",addr+9,"PTR",sz),addr+=sz+9
		else obj[k]:=NumGet(addr+1,SubStr("Char  UChar Short UShortInt   UInt  Int64 UInt64Double",(sz:=NumGet(addr+0,"Char"))*6-5,6)),addr+=SubStr("112244888",sz,1)+1
	}
	return obj
}
По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

64

Re: AHK: Сохранение Массива в файл

В коллекции нужно. Выкладывай с описанием, комментариями и примером использования.

65

Re: AHK: Сохранение Массива в файл

Что описать и прокомментировать?
Пример приведён:

Arr := {"1key":{2key:[,,"value"]}}
Base64 := ObjToBase64(Arr)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
MsgBox % Obj.1key.2key[3]

Prefix := {"LAlt":"<!","LCtrl":"<^","LShift":"<+","LWin":"<#"}
Base64 := ObjToBase64(Prefix)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
for k, v in Obj
	MsgBox % k " : " v


B := ["Ivan", 345, "London"]
Base64 := ObjToBase64(B)
MsgBox % Base64

Obj := ObjFromBase64(Base64)
for k, v in Obj
	MsgBox % k " : " v
По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

66

Re: AHK: Сохранение Массива в файл

Представленная функция позволяет...
Код функции (где возможно - с комментариями).
Пример использования: сохраняем массив в файл, считываем массив из файла.

В общем представь, что ты через 20 лет всё забыл. Потом зашёл в Коллекцию, заглянул в тему и сразу вспомнил. Это сейчас смотришь на голый код и всё понятно. А после без комментариев не разберёшься.

67

Re: AHK: Сохранение Массива в файл

Имена ObjToBase64, ObjFromBase64 говорят за себя, в них "стандартный" код касаемый Base64. Так что не знаю что комментировать.

Пример использования: сохраняем массив в файл, считываем массив из файла.

Пример таков и есть, но:
В таком случае в описание можно добавить что сохранение и восстановление всё таки связано не с файлом, а со строкой. Строку уже можно сохранить и в текстовый файл, и в ключ ини файла, тут уже кому как удобно.

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

68

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:

Так как функции RawObject, RawObjectSize, ObjLoad настолько же изменил насколько их понял (то есть оставил почти в оригинале), то хочу спросить не находит ли кто ошибок

Как ошибка, на лицо наличие рекурсии в них, если кто исправит, было бы понадёжнее.

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

69

Re: AHK: Сохранение Массива в файл

Почему это ошибка?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

70 (изменено: serzh82saratov, 2017-03-07 20:40:55)

Re: AHK: Сохранение Массива в файл

Переполнение стэка?
Мало ли, большая вложенность массивов.
Может быть повлияет не очень большая вложенность, а большой размер вложенных массивов?

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

71

Re: AHK: Сохранение Массива в файл

Нет, там именно большая вложенность влияет. На практике такое вряд ли встретится. А заменять рекурсию циклом вещь довольно мозголомная, сам знаешь.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

72

Re: AHK: Сохранение Массива в файл

Твой ответ ждал, выложу на досуге.

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).

73

Re: AHK: Сохранение Массива в файл

serzh82saratov пишет:
(A_IsUnicode ? "W" : "A")

Это не обязательно.

serzh82saratov пишет:
UInt, &Base64

Тут ошибка, должно быть Ptr.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

74

Re: AHK: Сохранение Массива в файл

Поправил.

По вопросам возмездной помощи пишите в личку
E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.25.02 (Unicode 32-bit).