/* * 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))); } } }