Files
Mapo-IOB-WIN/IOB-UT-NEXT/baseUtils.cs
T

1082 lines
37 KiB
C#

using NLog;
using RestSharp;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace IOB_UT_NEXT
{
public class baseUtils
{
#region Public Fields
/// <summary>
/// Indicazione VETO PING a server sino alla data-ora indicata
/// </summary>
public static DateTime dtVetoPing = DateTime.Now;
/// <summary>
/// Indicazione VETO accodamento INGRESSI/EVENTI sino alla data-ora indicata
/// </summary>
public static DateTime dtVetoQueueIN = DateTime.Now;
/// <summary>
/// Indicazione VETO invio a server sino alla data-ora indicata
/// </summary>
public static DateTime dtVetoSend = DateTime.Now;
/// <summary>
/// Status IOB
/// </summary>
public static bool IOB_Online = false;
/// <summary>
/// Status MP_IO
/// </summary>
public static bool MPIO_Online = false;
#endregion Public Fields
#region Public Properties
/// <summary>
/// Calcola una pausa con errore casuale x il prossimo send programmato verso SERVER
/// </summary>
public static int nextPauseSendMSec
{
get
{
// parto dal dato std di veto per pauseSendMSec
int answ = CRI("pauseSendMSec");
// aggiungo NOISE... +/- 50%
Random rnd = new Random();
int noise = rnd.Next(1, answ / 2);
answ += noise - (answ / 4);
return answ;
}
}
#endregion Public Properties
#region Public Methods
/// <summary>
/// formatta un numero in forma binaria 0/1
/// </summary>
/// <param name="valore"></param>
/// <returns></returns>
public static string binaryForm(int valore)
{
string answ = "";
try
{
answ = string.Format(new BinaryUtils(), "{0:B}", valore);
}
catch
{ }
return answ;
}
/// <summary>
/// formatta un numero in forma binaria 0/1
/// </summary>
/// <param name="valore"></param>
/// <returns></returns>
public static string binaryForm(uint valore)
{
string answ = "";
try
{
answ = string.Format(new BinaryUtils(), "{0:B}", valore);
}
catch
{ }
return answ;
}
/// <summary>
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
/// </summary>
/// <param name="url">URI da chiamare</param>
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
/// <returns></returns>
public static string ExecCallGet(string url, bool fastCall = false)
{
string answ = "";
// divido url tra base e opzionale...
Uri uri = new Uri(url);
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
string resource = uri.AbsolutePath;
RestClientOptions restOptStd = new RestClientOptions
{
BaseUrl = new Uri(baseUrl),
Timeout = TimeSpan.FromSeconds(60)
};
if (!string.IsNullOrEmpty(url))
{
if (fastCall)
{
restOptStd.Timeout = TimeSpan.FromSeconds(5);
}
try
{
// client chiamate rest
using (var client = new RestClient(restOptStd))
{
var actReq = new RestRequest(resource, Method.Get);
// effettuo vera chiamata
var currResp = client.Get(actReq);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
answ = currResp.Content ?? "";
}
}
}
catch (Exception exc)
{
lg.Error($"Eccezione in callRestUrl{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
/// </summary>
/// <param name="url">URI da chiamare</param>
/// <param name="payload">Payload da allegare (già serializzato)</param>
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
/// <returns></returns>
public static string ExecCallPostJson(string url, string payload, bool fastCall = false)
{
string answ = "";
// divido url tra base e opzionale...
Uri uri = new Uri(url);
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
string resource = uri.AbsolutePath;
RestClientOptions restOptStd = new RestClientOptions
{
BaseUrl = new Uri(baseUrl),
Timeout = TimeSpan.FromSeconds(60)
};
if (!string.IsNullOrEmpty(url))
{
if (fastCall)
{
restOptStd.Timeout = TimeSpan.FromSeconds(5);
}
try
{
// client chiamate rest
using (var client = new RestClient(restOptStd))
{
var actReq = new RestRequest(resource, Method.Post);
actReq.AddJsonBody(payload);
// effettuo vera chiamata
var currResp = client.Post(actReq);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
answ = currResp.Content ?? "";
}
}
}
catch (Exception exc)
{
lg.Error($"Eccezione in callRestUrlJson{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Effettua chiamata URL tramite RestSharp e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
/// </summary>
/// <param name="url">URI da chiamare</param>
/// <param name="payload">Payload da allegare (già serializzato)</param>
/// <param name="fastCall">Chiamata rapida (timeout rapido = 5sec)</param>
/// <returns></returns>
public static string ExecCallPostPlain(string url, string payload, bool fastCall = false)
{
string answ = "";
// divido url tra base e opzionale...
Uri uri = new Uri(url);
string baseUrl = $"{uri.Scheme}://{uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}";
string resource = uri.AbsolutePath;
RestClientOptions restOptStd = new RestClientOptions
{
BaseUrl = new Uri(baseUrl),
Timeout = TimeSpan.FromSeconds(60)
};
if (!string.IsNullOrEmpty(url))
{
if (fastCall)
{
restOptStd.Timeout = TimeSpan.FromSeconds(5);
}
try
{
// client chiamate rest
using (var client = new RestClient(restOptStd))
{
var actReq = new RestRequest(resource, Method.Post);
actReq.AddStringBody(payload, ContentType.Plain);
// effettuo vera chiamata
var currResp = client.Post(actReq);
if (currResp.StatusCode == System.Net.HttpStatusCode.OK && currResp.Content != null)
{
answ = currResp.Content ?? "";
}
}
}
catch (Exception exc)
{
lg.Error($"Eccezione in callRestUrlJson{Environment.NewLine}{exc}");
}
}
return answ;
}
/// <summary>
/// Effettua chiamata URL e restituisce risultato, SE NON E' in veto send (x mitigare chiamate...)
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string callUrl(string URL)
{
string answ = "";
// controllo se ho un VETO all'invio...
if (dtVetoSend < DateTime.Now)
{
answ = callUrlNow(URL);
}
return answ;
}
/// <summary>
/// Effettua chiamata URL e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <returns></returns>
public static string callUrl(string URL, string payload)
{
string answ = "";
// controllo se ho un VETO all'invio...
if (dtVetoSend < DateTime.Now)
{
answ = callUrlNow(URL, payload);
}
// restituisco valore!
return answ;
}
/// <summary>
/// Client HTTP statico e riutilizzabile per tutto il ciclo di vita dell'app
/// </summary>
private static readonly HttpClient _httpClient = new HttpClient();
/// <summary>
/// Metodo chiamata URL con POST async
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task<string> callUrlAsync(string URL, string payload, CancellationToken ct = default)
{
try
{
// Se hai un payload, probabilmente è una POST
var content = new StringContent(payload, Encoding.UTF8, "application/json");
// Qui il thread viene RILASCIATO. La CPU dell'istanza va a 0%
// mentre aspetta la risposta dal server.
HttpResponseMessage response = await _httpClient.PostAsync(URL, content, ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (OperationCanceledException)
{
// Gestisci la cancellazione (quando chiudi l'app o scade il timeout)
return "Canceled";
}
catch (Exception ex)
{
// Gestisci errori di rete
return $"Error: {ex.Message}";
}
}
/// <summary>
/// Metodo chiamata URL con GET async
/// </summary>
/// <param name="URL"></param>
/// <param name="ct"></param>
/// <returns></returns>
public static async Task<string> callUrlAsync(string URL,CancellationToken ct = default)
{
try
{
// Qui il thread viene RILASCIATO. La CPU dell'istanza va a 0%
// mentre aspetta la risposta dal server.
HttpResponseMessage response = await _httpClient.GetAsync(URL, ct);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (OperationCanceledException)
{
// Gestisci la cancellazione (quando chiudi l'app o scade il timeout)
return "Canceled";
}
catch (Exception ex)
{
// Gestisci errori di rete
return $"Error: {ex.Message}";
}
}
/// <summary>
/// Effettua chiamata URL IMMEDIATAMENTE e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <returns></returns>
public static string callUrlNow(string URL)
{
string answ = "";
if (client == null)
{
client = new WebClientWT();
}
client.Headers.Add("user-agent", $"{CRS("appName")}");
try
{
// problema certificati locali...
// https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html
// hack x certificati locali in 10.74.82.*
if (URL.Contains("10.74.82."))
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
}
answ = client.DownloadString(URL);
}
catch (Exception exc)
{
// imposto veto
int pauseSendMSec = nextPauseSendMSec;
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
// controllo log permesso...
if (logValuePermit(URL))
{
lg.Error($"Errore in callURL verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}");
}
}
// restituisco valore!
return answ;
}
/// <summary>
/// Effettua chiamata IMMEDIATAMENTE URL e restituisce risultato
/// </summary>
/// <param name="URL"></param>
/// <param name="payload"></param>
/// <returns></returns>
public static string callUrlNow(string URL, string payload)
{
string answ = "";
if (clientPayload == null)
{
clientPayload = new WebClientWT();
}
clientPayload.Headers.Add("user-agent", $"{CRS("appName")}-PAYLOAD");
clientPayload.Headers.Add("Content-Type", "application/json");
try
{
// problema certificati locali...
// https://living-sun.com/it/c/226351-webexception-could-not-establish-trust-relationship-for-the-ssl-tls-secure-channel-c-aspnet-web-services-ssl-webexception.html
// hack x certificati locali in 10.74.*
if (URL.Contains("10.74."))
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = (senderX, certificate, chain, sslPolicyErrors) => { return true; };
}
answ = clientPayload.UploadString(URL, payload);
if (answ != "OK")
{
// controllo log permesso...
if (logValuePermit($"{URL}|[{answ}]"))
{
lg.Error($"Invio dati fallito, ricevuto messaggio [{answ}]:{Environment.NewLine}- URL{Environment.NewLine}{URL}{Environment.NewLine}- payload{Environment.NewLine}{payload}");
}
}
}
catch (Exception exc)
{
// imposto veto
int pauseSendMSec = nextPauseSendMSec;
dtVetoSend = DateTime.Now.AddMilliseconds(pauseSendMSec);
// controllo log permesso...
if (logValuePermit(URL))
{
lg.Error($"Errore in callURL con PAYLOAD verso {URL}: impostato attesa di {pauseSendMSec} ms prima della prossima chiamata. Dump Payload:{Environment.NewLine}{payload}{Environment.NewLine}Eccezione:{Environment.NewLine}{exc}");
}
}
// restituisco valore!
return answ;
}
/// <summary>
/// Test esistenza/creazione directory
/// </summary>
/// <param name="dirPath"></param>
public static void checkDir(string dirPath)
{
if (!Directory.Exists(dirPath))
{
lg.Info($"Dir not found: {dirPath}");
Directory.CreateDirectory(dirPath);
lg.Info($"reated local dir {dirPath}");
}
}
/// <summary>
/// Conteggio valori true in un array di boolean
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
public static int CountTrue(params bool[] args)
{
return args.Count(t => t);
}
/// <summary>
/// legge conf in formato BOOLean
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool CRB(string key)
{
bool answ = false;
try
{
answ = Convert.ToBoolean(CRS(key));
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato char
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static char CRC(string key)
{
char answ = '-';
try
{
answ = ConfigurationManager.AppSettings[key].ToCharArray()[0];
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato INT
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static Int32 CRI(string key)
{
int answ = 0;
try
{
answ = Convert.ToInt32(CRS(key));
}
catch
{ }
return answ;
}
/// <summary>
/// legge conf in formato stringa
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string CRS(string key)
{
return ConfigurationManager.AppSettings[key] ?? string.Empty;
}
/// <summary>
/// Calcolo MD5 del fine indicato
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string GetFileMd5(string fileName)
{
string answ = "";
using (var md5 = MD5.Create())
{
using (var stream = File.OpenRead(fileName))
{
var hash = md5.ComputeHash(stream);
answ = BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
}
}
return answ;
}
/// <summary>
/// Restituisce la prima cifra (a sx) da un numero (es x decodere quale memoria modbus sia)
/// </summary>
/// <param name="num">Numero di cui trovare la priam cifra</param>
/// <returns></returns>
public static int getFirstInt(int num)
{
if (num >= 100000000) num /= 100000000;
if (num >= 10000) num /= 10000;
if (num >= 100) num /= 100;
if (num >= 10) num /= 10;
#if false
// formulazione alternativa con ciclo...
while (num >= 10)
num /= 10;
#endif
return num;
}
/// <summary>
/// IP della macchina
/// </summary>
/// <returns></returns>
public static string GetIP()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sIpAddr = string.Empty;
try
{
foreach (NetworkInterface adapter in nics)
{
if (sIpAddr == String.Empty)// only return IP Address from first card
{
IPInterfaceProperties properties = adapter.GetIPProperties();
foreach (var item in properties.UnicastAddresses)
{
if (item.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
sIpAddr = item.Address.ToString();
}
}
}
}
}
catch (Exception exc)
{
// controllo log permesso...
if (logValuePermit("GetIP"))
{
lg.Error(exc);
}
}
return sIpAddr;
}
/// <summary>
/// Macaddress della macchina
/// </summary>
/// <returns></returns>
public static string GetMACAddress()
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
String sMacAddress = string.Empty;
foreach (NetworkInterface adapter in nics)
{
if (sMacAddress == String.Empty)// only return MAC Address from first card
{
IPInterfaceProperties properties = adapter.GetIPProperties();
//sMacAddress = adapter.GetPhysicalAddress().ToString();
sMacAddress = string.Join(":", (from z in adapter.GetPhysicalAddress().GetAddressBytes() select z.ToString("X2")).ToArray());
}
}
return sMacAddress;
}
/// <summary>
/// Restituisce una stringa di soli caratteri numerici (stripe caratteri alfabetici)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string GetNumbers(string input)
{
return new string(input.Where(c => char.IsDigit(c)).ToArray());
}
/// <summary>
/// Method to convert an integer to a string containing the number in binary. A negative
/// number will be formatted as a 32-character binary number in two's compliment.
/// </summary>
/// <param name="theNumber">self-explanatory</param>
/// <param name="minimumDigits">
/// if binary number contains fewer characters leading zeros are added
/// </param>
/// <returns>string as described above</returns>
public static string IntToBinStr(int theNumber, int minimumDigits)
{
return Convert.ToString(theNumber, 2).PadLeft(minimumDigits, '0');
}
/// <summary>
/// verifica se un dato bit sia alzato (come flag di strobe)
/// </summary>
/// <param name="value">valore da testare</param>
/// <param name="flag">
/// valore cercato, può essere un singolo valore o un insieme in modalità AND
/// </param>
/// <returns></returns>
public static bool IsSetAll(StFlag32 value, StFlag32 flag)
{
return ((value & flag) == flag);
}
/// <summary>
/// verifica se un dato bit sia alzato (come flag di strobe)
/// </summary>
/// <param name="value">valore da testare</param>
/// <param name="flag">
/// valore cercato, può essere un singolo valore o un insieme in modalità OR
/// </param>
/// <returns></returns>
public static bool IsSetAny(StFlag32 value, StFlag32 flag)
{
return ((value & flag) != 0);
}
/// <summary>
/// Test ping x indirizzo indicato
/// </summary>
/// <param name="address"></param>
/// <returns></returns>
public static bool pingAddress(IPAddress address)
{
bool answ = false;
try
{
Ping pingSender = new Ping();
PingReply reply = pingSender.Send(address, 100);
// se passa il ping do OK...
if (reply.Status == IPStatus.Success)
{
answ = true;
}
}
catch (Exception exc)
{
// controllo log permesso...
if (logValuePermit("pingAddr"))
{
lg.Error(exc);
}
}
return answ;
}
/// <summary>
/// Lettura dictionary da file
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static Dictionary<string, string> ReadBin(string file)
{
var result = new Dictionary<string, string>();
// verifico file esista...
if (!File.Exists(file))
{
FileStream fs = File.Create(file);
fs.Close();
}
using (FileStream fs = File.OpenRead(file))
using (BinaryReader reader = new BinaryReader(fs))
{
// Get count.
int count = 0;
try
{
count = reader.ReadInt32();
}
catch
{ }
// Read in all pairs.
for (int i = 0; i < count; i++)
{
string key = reader.ReadString();
string value = reader.ReadString();
result[key] = value;
}
}
return result;
}
/// <summary>
/// Lettura dictionary da file
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
public static Dictionary<string, string> ReadPlain(string file)
{
// inizializzo num righe lette...
int numRow = 0;
var result = new Dictionary<string, string>();
// verifico file esista...
if (!File.Exists(file))
{
FileStream fs = File.Create(file);
fs.Close();
}
try
{
string[] lines = File.ReadAllLines(file);
result = lines.Select(l => l.Split(':')).ToDictionary(a => a[0], a => a[1]);
numRow = result.Count;
}
catch
{ }
// se leggesse un valore NON coerente (senza righe) restituisce un file vuoto...
if (numRow == 0)
{
result = new Dictionary<string, string>();
}
return result;
}
public static void resetWebClients()
{
// resetto i webclients...
client = new WebClientWT();
clientPayload = new WebClientWT();
}
/// <summary>
/// Effettua reverse della stringa
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string reverseStr(string s)
{
char[] arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
/// <summary>
/// imposta un bit al valore richiesto duplicando il valore IN come OUT
/// </summary>
/// <param name="original">valore originale da aggiornare</param>
/// <param name="bitBool">valore richiesto x il bit (0/1)</param>
/// <param name="bitIndex">indice bit, 0 based (es: 0..31 per 32bit)</param>
/// <returns></returns>
public static byte[] setBitOnStFlag(byte[] original, bool bitBool, int bitIndex)
{
int bitVal = 0;
if (bitBool)
{
bitVal = 1;
}
// risposta è identica ad originale...
byte[] answ = original;
// verifico se il bit è 0/1b
if (bitVal <= 1 && bitVal >= 0)
{
// verifico se si possa aggiornare il bit richiesto (<= al totale dei bit...)
if (bitIndex <= original.Length * 8 - 1)
{
// calcolo byte
int byteIndex = bitIndex / 8;
// bit nel byte
int bitInByteIndex = bitIndex % 8;
// bit richiesto
byte mask = (byte)(bitVal << bitInByteIndex);
// imposto!
answ[byteIndex] |= mask;
}
}
return answ;
}
/// <summary>
/// provvede a verificare la dim della cartella dei log e cancella i + vecchi fino a restare
/// a dim inferiori a _logMaxMb
/// </summary>
public static void shrinkDir(string dirPath)
{
// obj filemover...
fileMover.obj.setDirectory(dirPath);
float dirSizeMb = fileMover.obj.totalMb();
lg.Info("Inizio shrinkDir LOG folder: {0} Mb", dirSizeMb);
// ottengo elenco files *.txt
FileInfo[] _fis = fileMover.obj.elencoFiles_FI("*.log");
int numDdMax = 2;
try
{
numDdMax = CRI("zipLogOldDay");
}
catch
{ }
foreach (FileInfo _file in _fis)
{
if (_file.LastWriteTime < DateTime.Now.AddDays(-1)) // zippo files + vecchi di 2 gg...
{
fileMover.obj.zippaSingoloFile(_file);
// cancello l'originale...
fileMover.obj.eliminaFile(_file);
}
}
// inizio con eliminare file + vecchi della data indicata...
int maxLogDays = CRI("maxLogDays");
fileMover.obj.deleteOlderThan(maxLogDays);
// ora controllo SE sia superata la dim max della directory --> in tal caso cancello dal
// + vecchio...
dirSizeMb = fileMover.obj.totalMb();
int maxLogDirSize = CRI("maxLogDirSize");
int maxTry = 100;
// controllo se serva eliminare...
if (dirSizeMb > maxLogDirSize)
{
lg.Info("Continuo shrinkDir LOG folder: {0} Mb --> ELIMINAZIONE FILES", dirSizeMb);
while (dirSizeMb > maxLogDirSize)
{
fileMover.obj.deleteOldest();
maxTry--;
if (maxTry > 0)
{
dirSizeMb = fileMover.obj.totalMb();
}
else
{
// per uscire fingo di aver ridotto...
dirSizeMb = maxLogDirSize - 1;
}
}
dirSizeMb = fileMover.obj.totalMb();
lg.Info("Completata shrinkDir LOG folder: {0} Mb", dirSizeMb);
}
}
/// <summary>
/// Restitusice la stringa prima dell'ultima occorrenza del char richiesto
/// </summary>
/// <param name="origString">string originale</param>
/// <param name="sepChar">char separatore da cercare</param>
/// <returns></returns>
public static string StringBeforeLastChar(string origString, char sepChar)
{
int index = origString.LastIndexOf(sepChar);
string answ = (index == -1) ? origString : origString.Substring(0, index);
return answ;
}
/// <summary>
/// Converte un bitarray a byte[]
/// </summary>
/// <param name="bits"></param>
/// <returns></returns>
public static byte[] ToByteArray(BitArray bits)
{
int numBytes = bits.Count / 8;
if (bits.Count % 8 != 0)
{
numBytes++;
}
byte[] bytes = new byte[numBytes];
int byteIndex = 0, bitIndex = 0;
for (int i = 0; i < bits.Count; i++)
{
if (bits[i])
{
bytes[byteIndex] |= (byte)(1 << (7 - bitIndex));
}
bitIndex++;
if (bitIndex == 8)
{
bitIndex = 0;
byteIndex++;
}
}
return bytes;
}
/// <summary>
/// Scrittura dictionary su file
/// </summary>
/// <param name="dictionary"></param>
/// <param name="file"></param>
public static void WriteBin(Dictionary<string, string> dictionary, string file)
{
using (FileStream fs = File.OpenWrite(file))
using (BinaryWriter writer = new BinaryWriter(fs))
{
// Put count.
writer.Write(dictionary.Count);
// Write pairs.
foreach (var pair in dictionary)
{
writer.Write(pair.Key);
writer.Write(pair.Value);
}
}
}
/// <summary>
/// Scrittura dictionary su file
/// </summary>
/// <param name="dictionary"></param>
/// <param name="file"></param>
public static void WritePlain(Dictionary<string, string> dictionary, string file)
{
string dirPath = file.Substring(0, file.LastIndexOf('\\'));
// verifico directory
checkDir(dirPath);
string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray();
//string[] lines = dictionary.OrderBy(i => i.Key).Select(kvp => kvp.Key + ":" + kvp.Value).ToArray();
try
{
File.WriteAllLines(file, lines);
}
catch (Exception exc)
{
lg.Info(exc, string.Format("Errore in scrittura file {0}", file));
}
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// Classe logger
/// </summary>
protected static Logger lg = LogManager.GetCurrentClassLogger();
#endregion Protected Fields
#region Protected Properties
/// <summary>
/// Oggetto WebClient BASE da riutilizzare
/// </summary>
protected static WebClientWT client { get; set; }
/// <summary>
/// Oggetto WebClient con PAYLOAD da riutilizzare
/// </summary>
protected static WebClientWT clientPayload { get; set; }
#endregion Protected Properties
#region Private Fields
/// <summary>
/// Dizionario dei valori bloccati x evitare log eccessivo
/// </summary>
private static Dictionary<string, DateTime> vetoLogError = new Dictionary<string, DateTime>();
/// <summary>
/// Periodo di veto log in minuti
/// </summary>
private static int vetoPeriodMin = 30;
#endregion Private Fields
#region Private Methods
/// <summary>
/// Verifica se il log di un dato errore sia permesso
/// </summary>
/// <param name="logKey">ID del valore log da loggare/verificare</param>
/// <returns></returns>
private static bool logValuePermit(string logKey)
{
bool doLog = false;
if (vetoLogError.ContainsKey(logKey))
{
// verifico se veto scaduto...
if (DateTime.Now > vetoLogError[logKey])
{
doLog = true;
vetoLogError[logKey] = DateTime.Now.AddMinutes(vetoPeriodMin);
}
}
else
{
doLog = true;
vetoLogError.Add(logKey, DateTime.Now.AddMinutes(vetoPeriodMin));
}
return doLog;
}
#endregion Private Methods
}
/// <summary>
/// Override metodo WebClient con gesitone TimeOut corto
/// </summary>
public class WebClientWT : WebClient
{
#region Protected Properties
/// <summary>
/// timeout da conf
/// </summary>
protected int urlCallTOut
{
get
{
int answ = 5000;
answ = baseUtils.CRI("urlCallTOut");
if (answ < 0 || answ > 10000)
{
answ = 3000;
}
return answ;
}
}
#endregion Protected Properties
#region Protected Methods
protected override WebRequest GetWebRequest(Uri address)
{
WebRequest wr = base.GetWebRequest(address);
wr.Timeout = urlCallTOut; // timeout in milliseconds (ms)
return wr;
}
#endregion Protected Methods
}
}