Advertisement
AZJIO

IniVirtual

Jan 7th, 2013
437
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
AutoIt 8.95 KB | None | 0 0
  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
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement