 a3ef00a687
			
		
	
	a3ef00a687
	
	
	
		
			
			- Port core EXI encoding/decoding functionality to C# - Implement V2G protocol parsing and analysis - Add simplified decoder/encoder for roundtrip testing - Create comprehensive error handling with EXI exceptions - Support both byte array and file stream operations - Include packet structure analysis for V2GTP data - Successfully builds and runs basic functionality tests 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			198 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| /*
 | |
|  * 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
 | |
| {
 | |
|     /// <summary>
 | |
|     /// Byte Stream utilities for file operations
 | |
|     /// </summary>
 | |
|     public static class ByteStream
 | |
|     {
 | |
|         /// <summary>
 | |
|         /// Write bytes to file
 | |
|         /// </summary>
 | |
|         /// <param name="data">byte array</param>
 | |
|         /// <param name="filename">File name</param>
 | |
|         /// <returns>Error-Code != 0 on failure</returns>
 | |
|         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;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Read bytes from file
 | |
|         /// </summary>
 | |
|         /// <param name="filename">File name</param>
 | |
|         /// <param name="data">Output byte array</param>
 | |
|         /// <param name="bytesRead">Number of bytes actually read</param>
 | |
|         /// <returns>Error-Code != 0 on failure</returns>
 | |
|         public static int ReadBytesFromFile(string filename, out byte[] data, out int bytesRead)
 | |
|         {
 | |
|             data = Array.Empty<byte>();
 | |
|             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;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Read bytes from file with buffer size limit
 | |
|         /// </summary>
 | |
|         /// <param name="filename">File name</param>
 | |
|         /// <param name="maxSize">Maximum buffer size</param>
 | |
|         /// <param name="data">Output byte array</param>
 | |
|         /// <param name="bytesRead">Number of bytes actually read</param>
 | |
|         /// <returns>Error-Code != 0 on failure</returns>
 | |
|         public static int ReadBytesFromFile(string filename, int maxSize, out byte[] data, out int bytesRead)
 | |
|         {
 | |
|             data = Array.Empty<byte>();
 | |
|             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;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Convert hex string to byte array
 | |
|         /// </summary>
 | |
|         /// <param name="hex">Hex string</param>
 | |
|         /// <returns>Byte array</returns>
 | |
|         public static byte[] HexStringToByteArray(string hex)
 | |
|         {
 | |
|             if (string.IsNullOrEmpty(hex))
 | |
|                 return Array.Empty<byte>();
 | |
| 
 | |
|             // 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;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Convert byte array to hex string
 | |
|         /// </summary>
 | |
|         /// <param name="data">Byte array</param>
 | |
|         /// <param name="uppercase">Use uppercase hex digits</param>
 | |
|         /// <returns>Hex string</returns>
 | |
|         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)));
 | |
|         }
 | |
|     }
 | |
| } |