/*
* Copyright (C) 2007-2024 C# Port
* Original Copyright (C) 2007-2018 Siemens AG
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
using System.IO;
namespace V2GDecoderNet.EXI
{
///
/// Byte Stream utilities for file operations
///
public static class ByteStream
{
///
/// Write bytes to file
///
/// byte array
/// File name
/// Error-Code != 0 on failure
public static int WriteBytesToFile(byte[] data, string filename)
{
try
{
if (data == null)
return EXIErrorCodes.EXI_ERROR_OUT_OF_BYTE_BUFFER;
if (string.IsNullOrEmpty(filename))
return EXIErrorCodes.EXI_ERROR_OUTPUT_FILE;
File.WriteAllBytes(filename, data);
return 0; // Success
}
catch (UnauthorizedAccessException)
{
return EXIErrorCodes.EXI_ERROR_OUTPUT_FILE;
}
catch (DirectoryNotFoundException)
{
return EXIErrorCodes.EXI_ERROR_OUTPUT_FILE;
}
catch (IOException)
{
return EXIErrorCodes.EXI_ERROR_OUTPUT_FILE;
}
catch
{
return EXIErrorCodes.EXI_ERROR_OUTPUT_FILE;
}
}
///
/// Read bytes from file
///
/// File name
/// Output byte array
/// Number of bytes actually read
/// Error-Code != 0 on failure
public static int ReadBytesFromFile(string filename, out byte[] data, out int bytesRead)
{
data = Array.Empty();
bytesRead = 0;
try
{
if (string.IsNullOrEmpty(filename))
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
if (!File.Exists(filename))
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
data = File.ReadAllBytes(filename);
bytesRead = data.Length;
return 0; // Success
}
catch (UnauthorizedAccessException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (DirectoryNotFoundException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (FileNotFoundException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (IOException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
}
///
/// Read bytes from file with buffer size limit
///
/// File name
/// Maximum buffer size
/// Output byte array
/// Number of bytes actually read
/// Error-Code != 0 on failure
public static int ReadBytesFromFile(string filename, int maxSize, out byte[] data, out int bytesRead)
{
data = Array.Empty();
bytesRead = 0;
try
{
if (string.IsNullOrEmpty(filename))
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
if (!File.Exists(filename))
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
using var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
var fileSize = (int)fileStream.Length;
if (fileSize > maxSize)
return EXIErrorCodes.EXI_ERROR_OUT_OF_BYTE_BUFFER;
data = new byte[fileSize];
bytesRead = fileStream.Read(data, 0, fileSize);
return 0; // Success
}
catch (UnauthorizedAccessException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (DirectoryNotFoundException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (FileNotFoundException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch (IOException)
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
catch
{
return EXIErrorCodes.EXI_ERROR_INPUT_FILE_HANDLE;
}
}
///
/// Convert hex string to byte array
///
/// Hex string
/// Byte array
public static byte[] HexStringToByteArray(string hex)
{
if (string.IsNullOrEmpty(hex))
return Array.Empty();
// Remove any whitespace or separators
hex = hex.Replace(" ", "").Replace("-", "").Replace(":", "");
if (hex.Length % 2 != 0)
throw new ArgumentException("Hex string must have even number of characters");
var result = new byte[hex.Length / 2];
for (int i = 0; i < result.Length; i++)
{
if (!byte.TryParse(hex.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out result[i]))
throw new ArgumentException($"Invalid hex characters at position {i * 2}");
}
return result;
}
///
/// Convert byte array to hex string
///
/// Byte array
/// Use uppercase hex digits
/// Hex string
public static string ByteArrayToHexString(byte[] data, bool uppercase = true)
{
if (data == null || data.Length == 0)
return string.Empty;
var format = uppercase ? "X2" : "x2";
return string.Concat(data.Select(b => b.ToString(format)));
}
}
}