|
Imports SpoolfileReaderBase
Imports System.IO
Imports System.Diagnostics
Public Class EMFSpoolfileReader
Implements ISpoolfileReaderBase
#Region "Application trace switch"
Public Shared ApplicationTracing As New System.Diagnostics.TraceSwitch("EMFSpoolfileReader", "EMF Spool File reader application tracing")
#End Region
#Region "Perfomance monitoring information"
Private Const PERFORMANCE_COUNTER_NAME As String = "EMF Spoolfile Pages"
Private Const PERFORMANCE_TIMER_NAME As String = "EMF Spoolfile Pages/sec"
Private Const PERFORMANCE_COUNTER_CATEGORY As String = "Spoolfile Readers"
Private Shared SpoolfileReaderPerformaceCounter As PerformanceCounter
Private Sub InitialiseCounterCategory()
'\\ Create the performace category if it is not already done
If PerformanceCounterCategory.Exists(PERFORMANCE_COUNTER_CATEGORY) Then
PerformanceCounterCategory.Delete(PERFORMANCE_COUNTER_CATEGORY)
End If
Dim SpoolerCounterCreationDataCollection As New CounterCreationDataCollection()
Dim SpoolfileReaderCounterCreationDataCollection As New CounterCreationDataCollection()
Dim SpoolfileReaderCounterCreationData As New CounterCreationData(PERFORMANCE_COUNTER_NAME, "Spoolfile pages read", PerformanceCounterType.NumberOfItems32)
Dim SpoolfileReaderTimerCreationData As New CounterCreationData(PERFORMANCE_TIMER_NAME, "Spoolfile pages read second", PerformanceCounterType.NumberOfItems32)
SpoolfileReaderCounterCreationDataCollection.Add(SpoolfileReaderCounterCreationData)
SpoolfileReaderCounterCreationDataCollection.Add(SpoolfileReaderTimerCreationData)
Try
PerformanceCounterCategory.Create(PERFORMANCE_COUNTER_CATEGORY, "", System.Diagnostics.PerformanceCounterCategoryType.MultiInstance, SpoolerCounterCreationDataCollection)
Catch ex As System.Security.SecurityException
System.Diagnostics.Trace.TraceError(ex.ToString())
End Try
End Sub
Private Sub InitialiseCounter()
'SpoolfileReaderPerformaceCounter = New PerformanceCounter(PERFORMANCE_COUNTER_CATEGORY, PERFORMANCE_COUNTER_NAME, True)
End Sub
#End Region
#Region "Private member variables"
Private _Copies As Integer = 1 '\\ The number of copies per page
Private _Pages As Integer = 0
Private _EMFPages As New EMFPages()
#End Region
#Region "Private enumerated types"
Private Enum SpoolerRecordTypes
SRT_EOF = &H0 ' // int32 zero
SRT_RESERVED_1 = &H1 '* 1 */
SRT_FONTDATA = &H2 ' 2 Font Data */
SRT_DEVMODE = &H3 ' 3 DevMode */
SRT_FONT2 = &H4 '4 Font Data */
SRT_RESERVED_5 = &H5 ' 5 */
SRT_FONT_MM = &H6 ' 6 Font Data (Multiple Master) */
SRT_FONT_SUB1 = &H7 ' 7 Font Data (SubsetFont 1) */
SRT_FONT_SUB2 = &H8 ' 8 Font Data (SubsetFont 2)
SRT_RESERVED_9 = &H9
SRT_UNKNOWN = &H10 ' // int unknown...
SRT_RESERVED_A = &HA
SRT_RESERVED_B = &HB
SRT_PAGE = &HC ' 12 Enhanced Meta File (EMF) */
SRT_EOPAGE1 = &HD ' 13 EndOfPage */
SRT_EOPAGE2 = &HE ' 14 EndOfPage */
SRT_EXT_FONT = &HF ' 15 Ext Font Data */
SRT_EXT_FONT2 = &H10 ' 16 Ext Font Data */
SRT_EXT_FONT_MM = &H11 ' 17 Ext Font Data (Multiple Master)
SRT_EXT_FONT_SUB1 = &H12 ' 18 Ext Font Data (SubsetFont 1) */
SRT_EXT_FONT_SUB2 = &H13 '* 19 Ext Font Data (SubsetFont 2) */
SRT_EXT_PAGE = &H14 ' 20 Enhanced Meta File?
SRT_JOB_INFO = &H10000 ' // int length, wchar jobDescription
End Enum
#End Region
#Region "Private type defs"
Private Structure EMFMetaRecordHeader
Dim Seek As Long
Dim iType As SpoolerRecordTypes
Dim nSize As Int32
End Structure
#End Region
#Region "ISpoolerfileReaderBase implementation"
Public Function GetTruePageCount(ByVal SpoolFilename As String) As Integer Implements ISpoolfileReaderBase.GetTruePageCount
If ApplicationTracing.TraceVerbose Then
Trace.WriteLine("GetTruePageCount for " & SpoolFilename, Me.GetType.ToString)
End If
'\\ The number of copies is held in the shadow file
Dim ShadowFilename As String
If Not Path.GetExtension(SpoolFilename).ToUpper = ".SHD" Then
ShadowFilename = Path.ChangeExtension(SpoolFilename, ".SHD")
Else
ShadowFilename = SpoolFilename
End If
Dim fiShadow As New System.IO.FileInfo(ShadowFilename)
If fiShadow.Exists Then
Dim ShadowFileStream As New System.IO.FileStream(ShadowFilename, FileMode.Open, FileAccess.Read)
Dim ShadowBinaryReader As New BinaryReader(ShadowFileStream)
'\\ Close the shadow file
ShadowBinaryReader.Close()
ShadowFileStream.Close()
End If
SpoolFilename = Path.ChangeExtension(SpoolFilename, ".SPL")
'\\ Open a binary reader for the spool file
Dim SpoolFileStream As New System.IO.FileStream(SpoolFilename, FileMode.Open, FileAccess.Read)
Dim SpoolBinaryReader As New BinaryReader(SpoolFileStream, System.Text.Encoding.UTF8)
'Read the spooler records and count the total pages
Dim recNext As EMFMetaRecordHeader = NextHeader(SpoolBinaryReader)
While recNext.iType <> SpoolerRecordTypes.SRT_EOF
If recNext.iType = SpoolerRecordTypes.SRT_PAGE Then
_Pages += 1
End If
'SpoolfileReaderPerformaceCounter.Increment()
Call SkipAHeader(recNext, SpoolBinaryReader)
recNext = NextHeader(SpoolBinaryReader)
End While
'\\ Close the spool file
SpoolBinaryReader.Close()
SpoolFileStream.Close()
Return _Pages * _Copies
End Function
#End Region
#Region "Private functions"
Private Function NextHeader(ByRef SpoolBinaryReader As BinaryReader) As EMFMetaRecordHeader
Dim recRet As New EMFMetaRecordHeader()
With recRet
'\\ get the record type
.Seek = SpoolBinaryReader.BaseStream.Position
Try
.iType = CType(SpoolBinaryReader.ReadInt32, EMFSpoolfileReader.SpoolerRecordTypes)
Catch e As EndOfStreamException
.iType = SpoolerRecordTypes.SRT_EOF
Exit Function
End Try
'\\ Get the record size
.nSize = SpoolBinaryReader.ReadInt32
End With
Return recRet
End Function
Private Sub SkipAHeader(ByVal Header As EMFMetaRecordHeader, ByRef SpoolBinaryReader As BinaryReader)
With Header
If .nSize <= 0 Then
.nSize = 8
End If
If .iType = SpoolerRecordTypes.SRT_JOB_INFO Then
Dim JobInfo() As Byte
JobInfo = SpoolBinaryReader.ReadBytes(.nSize)
SpoolBinaryReader.BaseStream.Seek(.Seek + .nSize, SeekOrigin.Begin)
ElseIf .iType = SpoolerRecordTypes.SRT_EOF Then
'\\ End of file reached..do nothing
ElseIf .iType = SpoolerRecordTypes.SRT_DEVMODE Then
'\\ Spool job DEVMODE
Dim _dmThis As New DevMode(SpoolBinaryReader)
_Copies = _dmThis.Copies
SpoolBinaryReader.BaseStream.Seek(.Seek + 8 + .nSize, SeekOrigin.Begin)
ElseIf .iType = SpoolerRecordTypes.SRT_PAGE Or .iType = SpoolerRecordTypes.SRT_EXT_PAGE Then
'\\
Call ProcessEMFRecords(Header, SpoolBinaryReader)
ElseIf .iType = SpoolerRecordTypes.SRT_EOPAGE1 Or .iType = SpoolerRecordTypes.SRT_EOPAGE2 Then
'\\ int plus long
Dim EOPAGE() As Byte
EOPAGE = SpoolBinaryReader.ReadBytes(.nSize)
If .nSize = &H8 Then
SpoolBinaryReader.BaseStream.Seek(.Seek + .nSize + 8, SeekOrigin.Begin)
End If
ElseIf .iType = SpoolerRecordTypes.SRT_UNKNOWN Then
SpoolBinaryReader.BaseStream.Seek(.Seek + 4, SeekOrigin.Begin)
Else
SpoolBinaryReader.BaseStream.Seek(.Seek + .nSize, SeekOrigin.Begin)
End If
End With
End Sub
Private Sub ProcessEMFRecords(ByVal EMFRecord As EMFMetaRecordHeader, ByVal SpoolBinaryReader As BinaryReader)
Dim nNextRecordStart As Long
nNextRecordStart = EMFRecord.Seek + 8
SpoolBinaryReader.BaseStream.Seek(nNextRecordStart, SeekOrigin.Begin)
'\\ EMRMETAHEADER followed by other EMR records
Dim ThisPage As New EMFPage(SpoolBinaryReader)
_EMFPages.Add(ThisPage)
nNextRecordStart = nNextRecordStart + ThisPage.Header.FileSize
SpoolBinaryReader.BaseStream.Seek(nNextRecordStart, SeekOrigin.Begin)
End Sub
#End Region
#Region "Public interface"
Public ReadOnly Property Pages() As EMFPages
Get
Return _EMFPages
End Get
End Property
#End Region
#Region "Public constructor"
Public Sub New()
Call InitialiseCounterCategory()
Call InitialiseCounter()
End Sub
#End Region
End Class
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.