625 lines
23 KiB
VB.net
625 lines
23 KiB
VB.net
Imports System
|
|
Imports System.Collections.Generic
|
|
Imports System.Text
|
|
Imports System.Text.RegularExpressions
|
|
Imports System.Linq
|
|
|
|
Namespace ErrorsManager
|
|
Public Class ErrorsManager
|
|
|
|
Public Shared ReadOnly ALPHABET As Char() = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/=".ToCharArray()
|
|
Public Shared ReadOnly ERRORS_MESSAGES As String() = New String(){
|
|
"invalid_alphabet",
|
|
"invalid_base",
|
|
"invalid_alphabet_type",
|
|
"too_short_alphabet",
|
|
"repeated_characters_in_alphabet",
|
|
"too_long_alphabet",
|
|
"base_lower_than_2",
|
|
"base_greater_than_128",
|
|
"base_greater_than_alphabet"
|
|
}
|
|
|
|
Public Shared ReadOnly RE_KEY As New Regex("^[a-zA-Z0-9_]+$", RegexOptions.IgnoreCase Or RegexOptions.Compiled)
|
|
|
|
Private _error As Integer = 0
|
|
Private _alphabet As Char() = New Char(){}
|
|
Private dictionary As New Dictionary(Of Char, Byte)()
|
|
Private _base As Byte
|
|
Private power As Byte
|
|
|
|
Public Sub New(Optional inputs As Object = Nothing)
|
|
|
|
set_alphabet(
|
|
ErrorsManager.[get](Of Object)("alphabet", inputs, ALPHABET),
|
|
ErrorsManager.[get](Of Integer)("base", inputs, 64)
|
|
)
|
|
|
|
end Sub
|
|
|
|
Public Function set_alphabet(alphabet As Object, Optional _base As Integer = 64) As Integer
|
|
|
|
Dim original_length As Integer
|
|
|
|
_error = 0
|
|
|
|
If alphabet Is Nothing Then
|
|
_alphabet = ALPHABET
|
|
ElseIf TypeOf alphabet Is String Then
|
|
_alphabet = DirectCast(alphabet, String).ToCharArray()
|
|
ElseIf TypeOf alphabet Is IEnumerable(Of Char) Then
|
|
_alphabet = DirectCast(alphabet, IEnumerable(Of Char)).ToArray()
|
|
Else
|
|
_error = _error Or (1 << 0)
|
|
Return _error
|
|
End If
|
|
|
|
original_length = _alphabet.Length
|
|
|
|
_alphabet = _alphabet.Distinct().ToArray()
|
|
|
|
If _alphabet.Length < 2 Then
|
|
_error = _error Or (1 << 3)
|
|
_alphabet = ALPHABET
|
|
End If
|
|
If _alphabet.Length <> original_length Then _error = _error Or (1 << 4)
|
|
If _alphabet.Length > 128 Then _error = _error Or (1 << 5)
|
|
|
|
_error = _error Or (
|
|
If(_base < 2, 1 << 0,
|
|
If(_base > 128, 1 << 1,
|
|
If(_base > _alphabet.Length, 1 << 2,
|
|
0)))) << 6
|
|
|
|
If (_error >> 6) = 0 Then _alphabet = _alphabet.Take(_base).ToArray()
|
|
|
|
power = CByte(Math.Truncate(Math.Log(_alphabet.Take(128).Count(), 2)))
|
|
Me._base = CByte(Math.Truncate(Math.Pow(2, power)))
|
|
_alphabet = _alphabet.Take(Me._base).ToArray()
|
|
|
|
dictionary.Clear()
|
|
For i As Byte = 0 To _alphabet.Length - 1
|
|
dictionary(_alphabet(i)) = i
|
|
Next
|
|
|
|
Return _error
|
|
End Function
|
|
|
|
Public Function get_alphabet() As String
|
|
Return New String(_alphabet)
|
|
End Function
|
|
|
|
Public Function to_array(code As String) As Byte()
|
|
Return code.Select(Function(character) dictionary(character)).ToArray()
|
|
End Function
|
|
|
|
Public Function to_array(code As Byte()) As Byte()
|
|
Return code
|
|
End Function
|
|
|
|
Public Function to_array(code As Integer) As Byte()
|
|
|
|
Dim hexas As New List(Of Byte)()
|
|
|
|
While code > 0
|
|
hexas.Add(CByte(code Mod _base))
|
|
code \= _base
|
|
End While
|
|
|
|
Return hexas.ToArray()
|
|
End Function
|
|
|
|
Public Function to_string(code As Byte()) As String
|
|
Return New String(code.Select(Function(hexa) _alphabet(hexa)).ToArray())
|
|
End Function
|
|
|
|
Public Function to_string(code As Integer) As String
|
|
|
|
Dim hexas As New StringBuilder()
|
|
|
|
While code > 0
|
|
hexas.Append(_alphabet(code Mod _base))
|
|
code \= _base
|
|
End While
|
|
|
|
Return hexas.ToString()
|
|
End Function
|
|
|
|
Public Function to_string(code As String) As String
|
|
Return code
|
|
End Function
|
|
|
|
Public Function to_integer(code As Byte()) As Integer
|
|
|
|
Dim _integer As Integer = 0
|
|
|
|
For i As Integer = code.Length - 1 To 0 Step -1
|
|
_integer = _integer * _base + code(i)
|
|
Next
|
|
|
|
Return _integer
|
|
End Function
|
|
|
|
Public Function to_integer(code As String) As Integer
|
|
|
|
Dim _integer As Integer = 0
|
|
|
|
For i As Integer = code.Length - 1 To 0 Step -1
|
|
_integer = _integer * _base + dictionary(code(i))
|
|
Next
|
|
|
|
Return _integer
|
|
End Function
|
|
|
|
Public Function to_integer(code As Integer) As Integer
|
|
Return code
|
|
End Function
|
|
|
|
Public Function to_string_binary(code As Byte()) As String
|
|
Return String.Concat(code.Reverse().Select(Function(hexa) Convert.ToString(hexa, 2).PadLeft(power, "0"c)))
|
|
End Function
|
|
|
|
Public Function to_string_binary(code As Integer) As String
|
|
|
|
Dim binary As String = Convert.ToString(code, 2)
|
|
Dim remainer As Integer = binary.Length Mod power
|
|
|
|
Return If(remainer = 0, binary, binary.PadLeft(binary.Length + power - remainer, "0"c))
|
|
End Function
|
|
|
|
Public Function to_string_binary(code As String) As String
|
|
Return String.Concat(code.Reverse().Select(Function(character) Convert.ToString(dictionary(character), 2).PadLeft(power, "0"c)))
|
|
End Function
|
|
|
|
Public Function get_bits(code As String) As Integer
|
|
Return If(code.Length = 0, 0, (code.Length - 1) * power + CInt(Math.Ceiling(Math.Log(dictionary(code.Last()) + 1, 2))))
|
|
End Function
|
|
|
|
Public Function get_bits(code As Byte()) As Integer
|
|
Return If(code.Length = 0, 0, (code.Length - 1) * power + CInt(Math.Ceiling(Math.Log(code.Last() + 1, 2))))
|
|
End Function
|
|
|
|
Public Function get_bits(code As Integer) As Integer
|
|
Return CInt(Math.Ceiling(Math.Log(code + 1, 2)))
|
|
End Function
|
|
|
|
Public Sub get_from_bits(code As String, ByRef [from] As Integer, ByRef bits As Integer)
|
|
get_from_bits(to_array(code), from, bits)
|
|
End Sub
|
|
|
|
Public Sub get_from_bits(code As Byte(), ByRef [from] As Integer, ByRef bits As Integer)
|
|
If [from] < 0 Then
|
|
[from] = get_bits(code) + from
|
|
If [from] < 0 Then [from] = 0
|
|
End If
|
|
If bits < 0 Then
|
|
[from] += bits
|
|
bits *= -1
|
|
If [from] < 0 Then
|
|
bits += [from]
|
|
[from] = 0
|
|
End If
|
|
End If
|
|
End Sub
|
|
|
|
Public Sub get_from_bits(code As Integer, ByRef [from] As Integer, ByRef bits As Integer)
|
|
get_from_bits(to_array(code), [from], bits)
|
|
End Sub
|
|
|
|
Public Function clean(code As String) As String
|
|
|
|
Dim l As Integer = code.Length
|
|
|
|
While l > 0 AndAlso code(l - 1) = _alphabet(0)
|
|
l -= 1
|
|
End While
|
|
|
|
Return (
|
|
If(code.Length = l, code,
|
|
If(l = 0, _alphabet(0).ToString(),
|
|
code.Substring(0, l))))
|
|
End Function
|
|
|
|
Public Function clean(code As Byte()) As Byte()
|
|
|
|
Dim l As Integer = code.Length
|
|
|
|
While l > 0 AndAlso code(l - 1) = 0
|
|
l -= 1
|
|
End While
|
|
|
|
Return (
|
|
If(code.Length = l, code,
|
|
If(l = 0, New Byte(){0},
|
|
code.Take(l).ToArray())))
|
|
End Function
|
|
|
|
Public Function clean(code As Integer) As Integer
|
|
Return code
|
|
End Function
|
|
|
|
Public Function get_range(code As String, [from] As Integer, bits As Integer) As String
|
|
Return to_string(get_range(to_array(code), [from], bits))
|
|
End Function
|
|
|
|
Public Function get_range(code As Byte(), [from] As Integer, bits As Integer) As Byte()
|
|
|
|
Dim hexas As List(Of Byte)
|
|
|
|
get_from_bits(code, [from], bits)
|
|
|
|
If bits = 0 Then bits = get_bits(code) - [from]
|
|
If bits <= 0 Then Return New Byte(){}
|
|
|
|
hexas = code.ToList()
|
|
|
|
If [from] > 0 Then
|
|
|
|
Dim shift As Byte = CByte([from] Mod power)
|
|
Dim mask As Integer = CInt((1 << shift) - 1)
|
|
|
|
hexas = hexas.Skip([from] \ power).ToList()
|
|
If shift <> 0 AndAlso hexas.Count() > 0 Then
|
|
|
|
Dim l = hexas.Count() - 2
|
|
|
|
For i As Integer = 0 To l
|
|
hexas(i) = CByte((hexas(i) >> shift) Or ((hexas(i + 1) << (power - shift)) And mask))
|
|
Next
|
|
hexas(l + 1) = CByte(hexas(l + 1) >> shift)
|
|
|
|
End If
|
|
|
|
ElseIf bits > 0 Then
|
|
|
|
Dim shift As Byte = CByte(bits Mod power)
|
|
|
|
hexas = hexas.Take(CInt(Math.Ceiling(bits / CDbl(power)))).ToList()
|
|
If shift <> 0 AndAlso hexas.Count() > 0 Then
|
|
hexas(hexas.Count() - 1) = CByte(hexas.Last() And ((1 << shift) - 1))
|
|
End If
|
|
|
|
End If
|
|
|
|
Return clean(hexas.ToArray())
|
|
End Function
|
|
|
|
Public Function get_range(code As Integer, [from] As Integer, bits As Integer) As Integer
|
|
|
|
get_from_bits(code, [from], bits)
|
|
|
|
If [from] > 0 Then code = (code >> [from]) And ((1 << (31 - [from])) - 1)
|
|
If bits <= 0 OrElse bits >= 31 Then Return code
|
|
If [from] + bits > 31 Then bits = 31 - [from]
|
|
|
|
Return code And ((1 << bits) - 1)
|
|
End Function
|
|
|
|
Public Function process(code As String, messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
|
|
Return process(to_array(code), messages, blocks)
|
|
End Function
|
|
|
|
Public Function process(code As Byte(), messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
|
|
|
|
Dim response As new List(Of (Integer, String))()
|
|
Dim k As Integer = 0
|
|
Dim l = code.Length * power
|
|
Dim i As Integer = 0
|
|
Dim m As Integer = messages.Count()
|
|
|
|
If blocks Is Nothing Then blocks = New Dictionary(Of Integer, Integer)()
|
|
|
|
While i < l
|
|
If blocks.ContainsKey(i) AndAlso blocks(i) > 0 Then
|
|
|
|
Dim logarithm As Integer = CInt(Math.Log(blocks(i), 2))
|
|
Dim _k As Integer
|
|
|
|
If logarithm = 0 Then logarithm = 1
|
|
_k = to_integer(get_range(code, i, logarithm))
|
|
|
|
If _k > 0 Then
|
|
_k = k + _k
|
|
response.Add((_k, If(k < m, messages(k), "")))
|
|
End If
|
|
|
|
k += blocks(i)
|
|
i += logarithm
|
|
|
|
Else
|
|
If (code(i \ power) And (1 << i Mod power)) <> 0 Then
|
|
response.Add((k, If(k < m, messages(k), "")))
|
|
End If
|
|
k += 1
|
|
i += 1
|
|
End If
|
|
End While
|
|
|
|
return response.ToArray()
|
|
End Function
|
|
|
|
Public Function process(code As Integer, messages As IEnumerable(Of String), Optional blocks As Dictionary(Of Integer, Integer) = Nothing) As (Integer, String)()
|
|
Return process(to_array(code), messages, blocks)
|
|
End Function
|
|
|
|
Public Function bitwise(code As String, bits As Integer) As String
|
|
Return to_string(get_range(to_array(code), 0, bits))
|
|
End Function
|
|
|
|
Public Function bitwise(code As Byte(), bits As Integer) As Byte()
|
|
If code.Length = 0 OrElse bits = 0 Then Return code
|
|
|
|
Dim shift As Byte = CByte(Math.Abs(bits) Mod power)
|
|
Dim mask As Integer = _base - 1
|
|
Dim hexas As List(Of Byte) = code.ToList()
|
|
|
|
If bits < 0 Then
|
|
|
|
hexas.RemoveRange(0, -bits \ power)
|
|
|
|
If shift <> 0 AndAlso hexas.Count() <> 0 Then
|
|
|
|
Dim l As Integer = hexas.Count() - 2
|
|
|
|
For i As Integer = 0 To l
|
|
hexas(i) = CByte(((hexas(i) >> shift) Or (hexas(i + 1) << (power - shift))) And mask)
|
|
Next
|
|
hexas(hexas.Count - 1) = CByte((hexas.Last() >> shift) And mask)
|
|
|
|
End If
|
|
|
|
Else
|
|
|
|
If shift <> 0 Then
|
|
|
|
Dim last_hexa As Byte = hexas.Last() << shift
|
|
|
|
For i As Integer = hexas.Count() - 1 To 1 Step -1
|
|
hexas(i) = CByte(((hexas(i) << shift) And mask) Or (hexas(i - 1) >> (power - shift)))
|
|
Next
|
|
hexas(0) = CByte((hexas(0) << shift) And mask)
|
|
|
|
If last_hexa >= _base Then hexas.Add(CByte(last_hexa >> power))
|
|
|
|
End If
|
|
|
|
For i As Integer = bits \ power To 1 Step -1
|
|
hexas.Insert(0, 0)
|
|
Next
|
|
|
|
End If
|
|
|
|
Return clean(hexas.ToArray())
|
|
End Function
|
|
|
|
Public Function bitwise(code As Integer, bits As Integer) As Integer
|
|
Return (
|
|
If(bits > 0, code << bits,
|
|
If(bits < 0, code >> -bits,
|
|
code)))
|
|
End Function
|
|
|
|
Public Function reset(code As String, [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As String
|
|
Return to_string(reset(to_array(code), [from], bits, reversed))
|
|
End Function
|
|
|
|
Public Function reset(code As Byte(), [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As Byte()
|
|
|
|
Dim hexas As List(Of Byte) = code.ToList()
|
|
Dim hexa_from As Integer
|
|
Dim hexa_to As Integer
|
|
Dim l As Integer
|
|
Dim from_mask As Byte
|
|
Dim to_mask As Byte
|
|
|
|
get_from_bits(code, [from], bits)
|
|
hexa_from = [from] \ power
|
|
hexa_to = ([from] + bits) \ power
|
|
|
|
If reversed Then
|
|
|
|
l = [from] Mod power
|
|
from_mask = CByte(((1 << power - l) - 1) << l)
|
|
to_mask = Cbyte(((1 << ([from] + bits)) - 1) Mod power)
|
|
|
|
For i As Integer = 0 To hexas.Count() - 1
|
|
If i < hexa_from AndAlso i > hexa_to Then hexas(i) = 0
|
|
Next
|
|
|
|
If hexa_from = hexa_to Then
|
|
hexas(hexa_to) = CByte(hexas(hexa_to) And (from_mask And to_mask))
|
|
Else
|
|
hexas(hexa_from) = CByte(hexas(hexa_from) And from_mask)
|
|
If hexa_to < hexas.Count() Then hexas(hexa_to) = CByte(hexas(hexa_to) And to_mask)
|
|
End If
|
|
|
|
Else
|
|
|
|
l = ([from] + bits) Mod power
|
|
from_mask = CByte((1 << ([from] Mod power)) - 1)
|
|
to_mask = CByte(((1 << (power - l)) - 1) << l)
|
|
|
|
If hexa_from = hexa_to Then
|
|
hexas(hexa_to) = CByte(hexas(hexa_to) And (from_mask Or to_mask))
|
|
Else
|
|
hexas(hexa_from) = CByte(hexas(hexa_from) And from_mask)
|
|
For i As Integer = hexa_from + 1 To hexa_to - 1
|
|
If i < hexas.Count() Then hexas(i) = 0
|
|
Next
|
|
If hexa_to < hexas.Count() Then hexas(hexa_to) = CByte(hexas(hexa_to) And to_mask)
|
|
End If
|
|
|
|
End If
|
|
|
|
Return clean(hexas.ToArray())
|
|
End Function
|
|
|
|
Public Function reset(code As Integer, [from] As Integer, Optional bits As Integer = 0, Optional reversed As Boolean = False) As Integer
|
|
|
|
get_from_bits(code, [from], bits)
|
|
If [from] + bits > 31 Then bits = 31 - [from]
|
|
|
|
Return code And (
|
|
If(reversed, ((1 << bits) - 1) << [from],
|
|
((1 << get_bits(code)) << [from] + bits Or ((1 << [from]) - 1))))
|
|
End Function
|
|
|
|
Public Function has(code As String, [from] As Integer, bits As Integer) As Boolean
|
|
Return get_range(to_array(code), [from], bits).Length > 0
|
|
End Function
|
|
|
|
Public Function has(code As Byte(), [from] As Integer, bits As Integer) As Boolean
|
|
Return get_range(code, [from], bits).Length > 0
|
|
End Function
|
|
|
|
Public Function has(code As Integer, [from] As Integer, bits As Integer) As Boolean
|
|
Return get_range(code, [from], bits) <> 0
|
|
End Function
|
|
|
|
Public Function [set]([error] As String, code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
|
|
Return to_string([set](to_array([error]), to_array(code), [from], bits))
|
|
End Function
|
|
|
|
Public Function [set]([error] As String, code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
|
|
Return to_string([set](to_array([error]), code, [from], bits))
|
|
End Function
|
|
|
|
Public Function [set]([error] As String, code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As String
|
|
Return to_string([set](to_array([error]), to_array(code), [from], bits))
|
|
End Function
|
|
|
|
Public Function [set]([error] As Byte(), code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
|
|
Return [set]([error], to_array(code), [from], bits)
|
|
End Function
|
|
|
|
Public Function [set]([error] As Byte(), code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
|
|
|
|
Dim l As Integer
|
|
Dim m As Integer
|
|
Dim n As Integer
|
|
Dim results As New List(Of Byte)()
|
|
|
|
If bits <> 0 Then
|
|
[error] = reset([error], [from], bits)
|
|
m = [error].Length
|
|
End If
|
|
If [from] <> 0 Then
|
|
code = bitwise(code, [from])
|
|
n = code.Length
|
|
End If
|
|
l = If(m > n, m, n)
|
|
|
|
For i As Integer = 0 To l - 1
|
|
results.Add(CByte(
|
|
(If(i < m, [error](i), CByte(0))) Or
|
|
(If(i < n, code(i), CByte(0)))
|
|
))
|
|
Next
|
|
|
|
Return clean(results.ToArray())
|
|
End Function
|
|
|
|
Public Function [set]([error] As Byte(), code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Byte()
|
|
Return [set]([error], to_array(code), [from], bits)
|
|
End Function
|
|
|
|
Public Function [set]([error] As Integer, code As String, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
|
|
Return [set]([error], to_integer(code), [from], bits)
|
|
End Function
|
|
|
|
Public Function [set]([error] As Integer, code As Byte(), Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
|
|
Return [set]([error], to_integer(code), [from], bits)
|
|
End Function
|
|
|
|
Public Function [set]([error] As Integer, code As Integer, Optional [from] As Integer = 0, Optional bits As Integer = 0) As Integer
|
|
|
|
If bits <> 0 Then [error] = reset([error], [from], bits)
|
|
If [from] <> 0 Then [error] = bitwise([error], [from])
|
|
|
|
Return [error] Or code
|
|
End Function
|
|
|
|
Public Shared Function get_keys(items As Object) As String()
|
|
|
|
Dim keys As New List(Of String)()
|
|
|
|
If TypeOf items Is String Then
|
|
If RE_KEY.IsMatch(DirectCast(items, String)) Then keys.Add(DirectCast(items, String))
|
|
ElseIf TypeOf items Is String() Then
|
|
For Each item As String In DirectCast(items, String())
|
|
If RE_KEY.IsMatch(item) AndAlso Not keys.Contains(item) Then keys.Add(item)
|
|
Next
|
|
ElseIf TypeOf items Is IEnumerable(Of Object) Then
|
|
For Each item As Object In DirectCast(items, IEnumerable(Of Object))
|
|
If item Is Nothing Then Continue For
|
|
If TypeOf item Is String Then
|
|
If RE_KEY.IsMatch(DirectCast(item, String)) AndAlso Not keys.Contains(DirectCast(item, String)) Then keys.Add(DirectCast(item, String))
|
|
Else
|
|
For Each key As String In get_keys(item)
|
|
If Not keys.Contains(key) Then keys.Add(key)
|
|
Next
|
|
End If
|
|
Next
|
|
End If
|
|
|
|
Return keys.ToArray()
|
|
End Function
|
|
|
|
Public Shared Function get_dictionaries(items As Object) As List(Of Dictionary(Of String, Object))
|
|
|
|
Dim dictionaries As New List(Of Dictionary(Of String, Object))()
|
|
|
|
If TypeOf items Is Dictionary(Of String, Object) Then
|
|
dictionaries.Add(DirectCast(items, Dictionary(Of String, Object)))
|
|
ElseIf TypeOf items Is IEnumerable(Of Object) Then
|
|
For Each item As Object In DirectCast(items, IEnumerable(Of Object))
|
|
dictionaries.AddRange(get_dictionaries(item))
|
|
Next
|
|
End If
|
|
|
|
Return dictionaries
|
|
End Function
|
|
|
|
Public Shared Function [get](Of T)(keys As Object, inputs As Object, Optional _default As T = Nothing) As T
|
|
|
|
Dim keys_list As String() = get_keys(keys)
|
|
|
|
If keys_list.Length <> 0 Then
|
|
For Each dictionary As Dictionary(Of String, Object) In get_dictionaries(inputs)
|
|
For Each key As String In keys_list
|
|
|
|
Dim value As Object = Nothing
|
|
|
|
If dictionary.TryGetValue(key, value) AndAlso TypeOf value Is T Then Return DirectCast(value, T)
|
|
|
|
Next
|
|
Next
|
|
End If
|
|
Return _default
|
|
End Function
|
|
|
|
Public Shared Function Unique(Of T)(items As IEnumerable(Of T)) As T()
|
|
Return items.Distinct().ToArray()
|
|
End Function
|
|
|
|
Public Shared Function is_array(value As Object) As Boolean
|
|
Return TypeOf value Is Array
|
|
End Function
|
|
|
|
Public Shared Function is_integer(value As Object) As Boolean
|
|
Return TypeOf value Is Integer
|
|
End Function
|
|
|
|
Public Shared Sub for_each_enumerate(Of T)(items As IEnumerable(Of T), action As Action(Of T, Integer))
|
|
|
|
Dim index As Integer = 0
|
|
|
|
For Each item As T In items
|
|
action(item, index)
|
|
index += 1
|
|
Next
|
|
|
|
End Sub
|
|
|
|
End Class
|
|
End Namespace |