daily pastebin goal
81%
SHARE
TWEET

IniVirtual

AZJIO Jan 7th, 2013 127 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <Array.au3>
  2.  
  3. ; Формат возвращаемых значений и ошибок максимально приближен к нативным функциям (например ошибки записи быть не может, так как данные пишутся в памяти).
  4.  
  5. ; =======================================
  6. ; Title .........: IniVirtual
  7. ; AutoIt Version : 3.3.6.1 - 3.3.8.1
  8. ; Language ......: English + Русский
  9. ; Description ....: Операции с ini-файлом в памяти
  10. ; Author(s) .......: AZJIO
  11. ; =======================================
  12.  
  13. ; #CURRENT# =============================
  14. ; _IniVirtual_Delete
  15. ; _IniVirtual_Initial
  16. ; _IniVirtual_Read
  17. ; _IniVirtual_ReadSection
  18. ; _IniVirtual_ReadSectionNames
  19. ; _IniVirtual_RenameSection
  20. ; _IniVirtual_Write
  21. ; _IniVirtual_WriteSection
  22. ; _IniVirtual_Save
  23. ; _IniVirtual_IsDuplicateKeys
  24. ; _IniVirtual_IsDuplicateSection
  25. ; __GetKeysVal
  26. ; =======================================
  27.  
  28. Func _IniVirtual_Initial($s_INI_Text)
  29.         Local $aSection, $d, $u
  30.         $s_INI_Text = StringRegExpReplace($s_INI_Text, '\h+\r\n\h*|\r\n\h+|\s+\z', @CRLF) ; Удаление пробельных символов в начале и в конце каждой строки. (упрощает слудующее рег.выр. и в параметрах лишнее)
  31.         $s_INI_Text = StringRegExpReplace($s_INI_Text, '\]\r\n\[', ']' & @CRLF & @CRLF & '[') ;
  32.         ; $aSection = StringRegExp($s_INI_Text, '(?s)(?:\r\n|\A)\h*\[\h*(.*?)\h*\]\h*\r\n(.*?)(?=\r\n\h*\[\h*.*?\h*\]\h*\r\n|\z)', 3)
  33.         ; $aSection = StringRegExp($s_INI_Text, '(?s)(?:\r\n|\A)\[\h*(.*?)\h*\]\r\n(.*?)(?=\r\n\[\h*.*?\h*\]\r\n|\z)', 3)
  34.         $aSection = StringRegExp($s_INI_Text, '(?s)(?:\r\n|\A)\[\h*(.*?)\h*\]\r\n(.*?)(?=\r\n\[|\z)', 3)
  35.         $u = UBound($aSection)
  36.         Local $a_Ini_Virtual2D[$u / 2 + 1][2] = [[$u / 2]]
  37.         For $i = 0 To $u - 1 Step 2
  38.                 $d = Int($i / 2) + 1
  39.                 $a_Ini_Virtual2D[$d][0] = $aSection[$i]
  40.                 $a_Ini_Virtual2D[$d][1] = __GetKeysVal($aSection[$i + 1]) ; массив массивов
  41.         Next
  42.         Return $a_Ini_Virtual2D
  43. EndFunc   ;==>_IniVirtual_Initial
  44.  
  45. Func __GetKeysVal($vData)
  46.         $vData = StringRegExp($vData, '(?m)^([^;].*?)\h*=\h*(["'']?)(.*?)\2\r?$', 3) ; учитывает пробелы между элементами и обрамление кавычками
  47.         Local $d, $u = UBound($vData) ; 0 как индикатор ошибки
  48.         Local $aData2D[$u / 3 + 1][2] = [[$u / 3]]
  49.         For $i = 0 To $u - 1 Step 3
  50.                 $d = Int($i / 3) + 1
  51.                 $aData2D[$d][0] = $vData[$i]
  52.                 $aData2D[$d][1] = $vData[$i + 2]
  53.         Next
  54.         Return $aData2D
  55. EndFunc   ;==>__GetKeysVal
  56.  
  57. Func _IniVirtual_ReadSectionNames($a_Ini_Virtual2D)
  58.         Local $aSection[$a_Ini_Virtual2D[0][0] + 1] = [$a_Ini_Virtual2D[0][0]]
  59.         For $i = 1 To $a_Ini_Virtual2D[0][0]
  60.                 $aSection[$i] = $a_Ini_Virtual2D[$i][0]
  61.         Next
  62.         If $aSection[0] = 0 Then Return SetError(1, 0, 0)
  63.         Return $aSection
  64. EndFunc   ;==>_IniVirtual_ReadSectionNames
  65.  
  66. Func _IniVirtual_Read($a_Ini_Virtual2D, $sSection, $sKey, $sDefault = '')
  67.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  68.         If @error Then Return $sDefault
  69.         Local $aKey = $a_Ini_Virtual2D[$i][1]
  70.         $i = _ArraySearch($aKey, $sKey, 1, 0, 0, 0, 1, 0)
  71.         If @error Then Return $sDefault
  72.         Return $aKey[$i][1]
  73. EndFunc   ;==>_IniVirtual_Read
  74.  
  75. Func _IniVirtual_Write(ByRef $a_Ini_Virtual2D, $sSection, $sKey, $sValue)
  76.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  77.         If @error Then ; создаёт, если не существует
  78.                 $a_Ini_Virtual2D[0][0] += 1
  79.                 ReDim $a_Ini_Virtual2D[$a_Ini_Virtual2D[0][0] + 1][2]
  80.                 $i = $a_Ini_Virtual2D[0][0]
  81.                 $a_Ini_Virtual2D[$i][0] = $sSection
  82.                 Local $aKey[2][2] = [[1],[$sKey, $sValue]]
  83.         Else
  84.                 Local $aKey = $a_Ini_Virtual2D[$i][1]
  85.                 Local $j = _ArraySearch($aKey, $sKey, 1, 0, 0, 0, 1, 0)
  86.                 If @error Then
  87.                         ReDim $aKey[$aKey[0][0] + 2][2]
  88.                         $aKey[$aKey[0][0] + 1][0] = $sKey
  89.                         $aKey[$aKey[0][0] + 1][1] = $sValue
  90.                 Else
  91.                         $aKey[$j][1] = $sValue
  92.                 EndIf
  93.         EndIf
  94.         $a_Ini_Virtual2D[$i][1] = $aKey
  95.         Return 1
  96. EndFunc   ;==>_IniVirtual_Write
  97.  
  98. Func _IniVirtual_WriteSection(ByRef $a_Ini_Virtual2D, $sSection, $vData, $iIndex = 1)
  99.         Local $u = 0
  100.         If IsArray($vData) Then
  101.                 If UBound($vData, 0) <> 2 Then Return SetError(1, 0, 0)
  102.                 $u = UBound($vData)
  103.                 If $iIndex > $u - 1 Or $iIndex < 0 Or Not StringIsDigit($iIndex) Then Return SetError(2, 0, 0)
  104.         EndIf
  105.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  106.         If @error Then ; Если секция не существует, выделяем ячеку для неё
  107.                 $a_Ini_Virtual2D[0][0] += 1
  108.                 ReDim $a_Ini_Virtual2D[$a_Ini_Virtual2D[0][0] + 1][2]
  109.                 $i = $a_Ini_Virtual2D[0][0] ; индекс новой ячейки
  110.         EndIf
  111.         If $u Then
  112.                 If $iIndex = 1 Then
  113.                         $vData[0][0] = $u - 1
  114.                 ElseIf $iIndex = 0 Then
  115.                         ReDim $vData[$u + 1][2]
  116.                         For $j = $u To 1 Step -1
  117.                                 $vData[$j][0] = $vData[$j - 1][0]
  118.                                 $vData[$j][1] = $vData[$j - 1][1]
  119.                         Next
  120.                         $vData[0][0] = $u
  121.                 Else
  122.                         $vData[0][0] = $u - $iIndex
  123.                         For $j = 1 To $vData[0][0]
  124.                                 $vData[$j][0] = $vData[$iIndex + $j - 1][0]
  125.                                 $vData[$j][1] = $vData[$iIndex + $j - 1][1]
  126.                         Next
  127.                         ReDim $vData[$j][2]
  128.                 EndIf
  129.                 $a_Ini_Virtual2D[$i][1] = $vData
  130.         Else
  131.                 $a_Ini_Virtual2D[$i][0] = $sSection
  132.                 $a_Ini_Virtual2D[$i][1] = __GetKeysVal(StringRegExpReplace($vData, '(?<!\r)\n', @CRLF))
  133.         EndIf
  134.         Return 1
  135. EndFunc   ;==>_IniVirtual_WriteSection
  136.  
  137. Func _IniVirtual_Delete(ByRef $a_Ini_Virtual2D, $sSection, $sKey = Default)
  138.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  139.         If @error Then Return SetError(0, 1, 1) ; отсутствие раздела/ключа не является ошибкой, но устанавливаем @extended
  140.         If $sKey = Default Then
  141.                 __IniVirtual_Delete2D($a_Ini_Virtual2D, $i)
  142.         Else
  143.                 Local $aKey = $a_Ini_Virtual2D[$i][1]
  144.                 Local $j = _ArraySearch($aKey, $sKey, 1, 0, 0, 0, 1, 0)
  145.                 If @error Then Return SetError(0, 2, 1)
  146.                 __IniVirtual_Delete2D($aKey, $j)
  147.                 $a_Ini_Virtual2D[$i][1] = $aKey
  148.         EndIf
  149.         Return 1
  150. EndFunc   ;==>_IniVirtual_Delete
  151.  
  152. Func __IniVirtual_Delete2D(ByRef $aArr2D, $ind)
  153.         For $i = $ind To $aArr2D[0][0] - 1
  154.                 $aArr2D[$i][0] = $aArr2D[$i + 1][0]
  155.                 $aArr2D[$i][1] = $aArr2D[$i + 1][1]
  156.         Next
  157.         ReDim $aArr2D[$aArr2D[0][0]][2]
  158.         $aArr2D[0][0] -= 1
  159. EndFunc
  160.  
  161. Func _IniVirtual_RenameSection(ByRef $a_Ini_Virtual2D, $sSection, $sNewName, $flag = 0)
  162.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  163.         If @error Then Return SetError(1, 0, 0) ; если секции для переименования не существует, то выход с @error
  164.         Local $j = _ArraySearch($a_Ini_Virtual2D, $sNewName, 1, 0, 0, 0, 1, 0)
  165.         If @error Then
  166.                 $a_Ini_Virtual2D[$i][0] = $sNewName ; если новый раздел не существует, то просто меняем имя раздела
  167.         Else
  168.                 If $flag Then
  169.                         $a_Ini_Virtual2D[$j][1] = $a_Ini_Virtual2D[$i][1] ; если перезапись, то копируем старый массив в позицию нового
  170.                         ; _IniVirtual_Delete($a_Ini_Virtual2D, $sSection) ; а старый удаляем
  171.                         __IniVirtual_Delete2D($a_Ini_Virtual2D, $i)
  172.                 Else
  173.                         Return SetError(2, 0, 0)
  174.                 EndIf
  175.         EndIf
  176.         Return 1
  177. EndFunc   ;==>_IniVirtual_RenameSection
  178.  
  179. Func _IniVirtual_ReadSection($a_Ini_Virtual2D, $sSection)
  180.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  181.         If @error Then Return SetError(1, 0, 0)
  182.         Return $a_Ini_Virtual2D[$i][1]
  183. EndFunc   ;==>_IniVirtual_ReadSection
  184.  
  185. Func _IniVirtual_Save($a_Ini_Virtual2D)
  186.         Local $aKey, $sText = ''
  187.         For $i = 1 To $a_Ini_Virtual2D[0][0]
  188.                 $sText &= '[' & $a_Ini_Virtual2D[$i][0] & ']' & @CRLF
  189.                 $aKey = $a_Ini_Virtual2D[$i][1]
  190.                 For $j = 1 To $aKey[0][0]
  191.                         $aKey[$j][1] = StringRegExpReplace($aKey[$j][1], '^([''"]).*\1\z', '"\0"')
  192.                         ; Если значение содержит пробел справа или слева, то обрамляем в кавычки
  193.                         If StringRegExp($aKey[$j][1], '^\h|\h\z') Then $aKey[$j][1] = '"' & $aKey[$j][1] & '"'
  194.                         $sText &= $aKey[$j][0] & '=' & $aKey[$j][1] & @CRLF
  195.                 Next
  196.                 $sText &= @CRLF
  197.         Next
  198.         Return StringTrimRight($sText, 2)
  199. EndFunc   ;==>_IniVirtual_Save
  200.  
  201. Func _IniVirtual_IsDuplicateKeys($a_Ini_Virtual2D, $sSection)
  202.         Local $i = _ArraySearch($a_Ini_Virtual2D, $sSection, 1, 0, 0, 0, 1, 0)
  203.         If @error Then Return SetError(1, 0, 0)
  204.         Local $aKey = $a_Ini_Virtual2D[$i][1]
  205.         $sRes = _IniVirtual_IsDuplicateSection($aKey)
  206.         Return SetError(@error, 0, $sRes)
  207. EndFunc   ;==>_IsDuplicateKeys
  208.  
  209. Func _IniVirtual_IsDuplicateSection($aArr2D)
  210.         Local $s = Chr(1)
  211.         Assign($s, 1, 1)
  212.         For $i = 1 To $aArr2D[0][0]
  213.                 If IsDeclared($aArr2D[$i][0] & $s) Then
  214.                         If $aArr2D[$i][0] == '' Then Return SetError(1, 0, True) ; присутсвтует пустое имя секции
  215.                         Return SetError(2, 0, $aArr2D[$i][0]) ; присутсвтует дубликат секции
  216.                 Else
  217.                         Assign($aArr2D[$i][0] & $s, 1, 1)
  218.                 EndIf
  219.         Next
  220.         Return False
  221. EndFunc   ;==>_IsDuplicate
RAW Paste Data
Top