diff --git a/SharpIpp/Mapping/Profiles/GetCUPSPrintersProfile.cs b/SharpIpp/Mapping/Profiles/GetCUPSPrintersProfile.cs index 01c7256..fbc55b9 100644 --- a/SharpIpp/Mapping/Profiles/GetCUPSPrintersProfile.cs +++ b/SharpIpp/Mapping/Profiles/GetCUPSPrintersProfile.cs @@ -130,6 +130,7 @@ public void CreateMaps(IMapperConstructor mapper) PrintColorModeDefault = map.MapFromDic(src, PrinterAttribute.PrintColorModeDefault), PrintColorModeSupported = map.MapFromDicSetNull(src, PrinterAttribute.PrintColorModeSupported), WhichJobsSupported = map.MapFromDicSetNull(src, PrinterAttribute.WhichJobsSupported), + PrinterUUID = map.MapFromDic(src, PrinterAttribute.PrinterUUID), }); mapper.CreateMap>( ( src, map ) => @@ -267,6 +268,8 @@ public void CreateMaps(IMapperConstructor mapper) dic.Add(PrinterAttribute.PrintColorModeSupported, src.PrintColorModeSupported.Select(x => new IppAttribute(Tag.Keyword, PrinterAttribute.PrintColorModeSupported, map.Map(x))).ToArray()); if (src.WhichJobsSupported?.Any() ?? false) dic.Add(PrinterAttribute.WhichJobsSupported, src.WhichJobsSupported.Select(x => new IppAttribute(Tag.Keyword, PrinterAttribute.WhichJobsSupported, map.Map(x))).ToArray()); + if (src.PrinterUUID?.Any() ?? false) + dic.Add(PrinterAttribute.PrinterUUID, new IppAttribute[] { new IppAttribute(Tag.Keyword, PrinterAttribute.PrinterUUID, src.PrinterUUID) }); return dic; } ); } diff --git a/SharpIpp/Protocol/IppProtocol.Attributes.cs b/SharpIpp/Protocol/IppProtocol.Attributes.cs index 9485ab7..5878042 100644 --- a/SharpIpp/Protocol/IppProtocol.Attributes.cs +++ b/SharpIpp/Protocol/IppProtocol.Attributes.cs @@ -187,7 +187,9 @@ private static string ReadString(BinaryReader stream, Encoding? encoding = null) private static void Write(StringWithLanguage value, BinaryWriter stream, Encoding? encoding) { - stream.WriteBigEndian((short)(value.Language.Length + value.Value.Length)); + var languageBytes = Encoding.ASCII.GetBytes(value.Language); + var valueBytes = (encoding ?? Encoding.ASCII).GetBytes(value.Value); + stream.WriteBigEndian((short)(languageBytes.Length + valueBytes.Length + 4)); Write(value.Language, stream, null); Write(value.Value, stream, encoding); } diff --git a/SharpIpp/Protocol/IppProtocol.cs b/SharpIpp/Protocol/IppProtocol.cs index cac2a6e..4655c69 100644 --- a/SharpIpp/Protocol/IppProtocol.cs +++ b/SharpIpp/Protocol/IppProtocol.cs @@ -28,6 +28,16 @@ namespace SharpIpp.Protocol /// public partial class IppProtocol : IIppProtocol { + /// + /// Controls the behavior of ReadIppRequestAsync() method. + /// If true, the whole incoming document is read into a memory stream, + /// and can be accessed via message.Document. + /// If false, the document is not read into a memory stream, and it should + /// be consumed from the input stream by the caller. + /// Defaults to true. + /// + public bool ReadDocumentStream { get; set; } = true; + public async Task WriteIppRequestAsync(IIppRequestMessage ippRequestMessage, Stream stream, CancellationToken cancellationToken = default) { if (ippRequestMessage is null) @@ -448,9 +458,16 @@ private static string GetNormalizedName(Tag tag, string name, IppAttribute? prev RequestId = reader.ReadInt32BigEndian() }; ReadSections( reader, message ); - message.Document = new MemoryStream(); - await reader.BaseStream.CopyToAsync( message.Document ); - message.Document.Seek( 0, SeekOrigin.Begin ); + if (ReadDocumentStream) + { + message.Document = new MemoryStream(); + await reader.BaseStream.CopyToAsync(message.Document); + message.Document.Seek(0, SeekOrigin.Begin); + } + else + { + message.Document = Stream.Null; + } return message; } diff --git a/SharpIpp/Protocol/Models/PrinterAttribute.cs b/SharpIpp/Protocol/Models/PrinterAttribute.cs index e27f92e..a537231 100644 --- a/SharpIpp/Protocol/Models/PrinterAttribute.cs +++ b/SharpIpp/Protocol/Models/PrinterAttribute.cs @@ -35,6 +35,7 @@ public static class PrinterAttribute public const string PrinterUpTime = "printer-up-time"; public const string PrinterCurrentTime = "printer-current-time"; public const string MultipleOperationTimeOut = "multiple-operation-time-out"; + public const string CompressionDefault = "compression-default"; public const string CompressionSupported = "compression-supported"; public const string JobKOctetsSupported = "job-k-octets-supported"; public const string JpegKOctetsSupported = "jpeg-k-octets-supported"; @@ -67,9 +68,15 @@ public static class PrinterAttribute public const string OutputBinDefault = "output-bin-default"; public const string OutputBinSupported = "output-bin-supported"; public const string MediaColDefault = "media-col-default"; + public const string MediaColSupported = "media-col-supported"; + public const string MediaColReady = "media-col-ready"; public const string PrintColorModeDefault = "print-color-mode-default"; public const string PrintColorModeSupported = "print-color-mode-supported"; public const string WhichJobsSupported = "which-jobs-supported"; + public const string PrinterUUID = "printer-uuid"; + public const string PdfVersionsSupported = "pdf-versions-supported"; + public const string IppFeaturesSupported = "ipp-features-supported"; + public const string MediaTypeSupported = "media-type-supported"; public static IEnumerable GetAttributes(IppVersion version) { @@ -104,6 +111,7 @@ public static IEnumerable GetAttributes(IppVersion version) yield return PrinterUpTime; yield return PrinterCurrentTime; yield return MultipleOperationTimeOut; + yield return CompressionDefault; yield return CompressionSupported; yield return JobKOctetsSupported; yield return JpegKOctetsSupported; @@ -136,9 +144,15 @@ public static IEnumerable GetAttributes(IppVersion version) yield return OutputBinDefault; yield return OutputBinSupported; yield return MediaColDefault; + yield return MediaColSupported; + yield return MediaColReady; yield return PrintColorModeDefault; yield return PrintColorModeSupported; yield return WhichJobsSupported; + yield return PrinterUUID; + yield return PdfVersionsSupported; + yield return IppFeaturesSupported; + yield return MediaTypeSupported; } } } diff --git a/SharpIpp/Protocol/Models/PrinterDescriptionAttributes.cs b/SharpIpp/Protocol/Models/PrinterDescriptionAttributes.cs index 43b3c37..861c5d5 100644 --- a/SharpIpp/Protocol/Models/PrinterDescriptionAttributes.cs +++ b/SharpIpp/Protocol/Models/PrinterDescriptionAttributes.cs @@ -248,5 +248,7 @@ public class PrinterDescriptionAttributes public PrintColorMode[]? PrintColorModeSupported { get; set; } public WhichJobs[]? WhichJobsSupported { get; set; } + + public string? PrinterUUID { get; set; } } } diff --git a/SharpIppTests/Protocol/IppProtocolTests.cs b/SharpIppTests/Protocol/IppProtocolTests.cs index aee3fde..7d177b8 100644 --- a/SharpIppTests/Protocol/IppProtocolTests.cs +++ b/SharpIppTests/Protocol/IppProtocolTests.cs @@ -108,7 +108,7 @@ public void WriteValue_Resolution_ShouldBeWritten( int width, int height, Resolu } [DataTestMethod] - [DataRow( "en-us", "Lorem", new byte[] { 0x00, 0x0A, 0x00, 0x05, 0x65, 0x6E, 0x2D, 0x75, 0x73, 0x00, 0x05, 0x4C, 0x6F, 0x72, 0x65, 0x6D } )] + [DataRow( "en-us", "Lorem", new byte[] { 0x00, 0x0E, 0x00, 0x05, 0x65, 0x6E, 0x2D, 0x75, 0x73, 0x00, 0x05, 0x4C, 0x6F, 0x72, 0x65, 0x6D } )] public void Write_StringWithLanguage_ShouldBeWritten( string language, string text, byte[] expected ) { // Arrange diff --git a/SharpIppTests/SharpIppIntegrationTests.cs b/SharpIppTests/SharpIppIntegrationTests.cs index 62ae9a4..4775a39 100644 --- a/SharpIppTests/SharpIppIntegrationTests.cs +++ b/SharpIppTests/SharpIppIntegrationTests.cs @@ -799,7 +799,8 @@ async Task func(Stream s, CancellationToken c) }, PrintColorModeDefault = PrintColorMode.Color, PrintColorModeSupported = [PrintColorMode.Color], - WhichJobsSupported = [WhichJobs.Completed] + WhichJobsSupported = [WhichJobs.Completed], + PrinterUUID = "{6541A875-C511-4273-909F-18CFBB38D9D0}" }, OperationAttributes = new() { @@ -1452,7 +1453,8 @@ async Task func(Stream s, CancellationToken c) }, PrintColorModeDefault = PrintColorMode.Color, PrintColorModeSupported = [PrintColorMode.Color], - WhichJobsSupported = [WhichJobs.Completed] + WhichJobsSupported = [WhichJobs.Completed], + PrinterUUID = "{6541A875-C511-4273-909F-18CFBB38D9D0}" } ] };