📄 pdfxref.cs
字号:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace AnotherPDFLib
{
/// <summary>
/// Cross-Reference Table
/// </summary>
public class PdfXref
{
public UInt32 Offset;
public List<PdfXrefSection> Sections;
PdfXrefSection OriginalSection;
public bool InStream;
public PdfXref()
{
Sections = new List<PdfXrefSection>();
OriginalSection = new PdfXrefSection(0);
Sections.Add(OriginalSection);
}
internal void AddXrefEntry(UInt32 offset)
{
PdfXrefEntry entry = new PdfXrefEntryNoraml(offset, 0);
OriginalSection.Entries.Add(entry);
}
internal void AddXrefFreeEntry(UInt32 offset)
{
PdfXrefEntry entry = new PdfXrefEntryFree(offset, 0);
OriginalSection.Entries.Add(entry);
}
internal void AddXrefFreeEntry(UInt32 nextObjNum, UInt16 generation)
{
PdfXrefEntry entry = new PdfXrefEntryFree(nextObjNum, generation);
OriginalSection.Entries.Add(entry);
}
public void Initialize()
{
foreach (PdfXrefSection section in Sections)
{
section.Entries.Clear();
}
Sections.Clear();
OriginalSection.Entries.Add(PdfXrefEntryFree.FirstEntry);
Sections.Add(OriginalSection);
}
public IEnumerable<PdfXrefEntry> Entries
{
get
{
foreach (PdfXrefSection section in Sections)
{
foreach (PdfXrefEntry entry in section.Entries)
{
yield return entry;
}
}
}
}
/// <summary>
/// The total number of entries in cross-reference table
/// </summary>
public int EntryCount
{
get
{
int count = 0;
foreach (PdfXrefSection section in Sections)
{
count += section.Entries.Count;
}
return count;
}
}
public void Output(PdfWriter writer)
{
writer.WriteLine("xref");
foreach (PdfXrefSection section in Sections)
{
section.Output(writer);
}
}
public void ReadEntriesFromStream(PdfXRefStream xrefstream)
{
PdfArray sectionIndex = xrefstream.Index;
if (sectionIndex == null)
{
sectionIndex = new PdfArray();
sectionIndex.Add(new PdfInteger(0));
sectionIndex.Add(new PdfInteger(xrefstream.Size));
}
int bytesFirst = ((PdfInteger)xrefstream.FieldWidths[0]).Value;
int bytesSecond = ((PdfInteger)xrefstream.FieldWidths[1]).Value;
int bytesThird = ((PdfInteger)xrefstream.FieldWidths[2]).Value;
int bytesTotal = bytesFirst + bytesSecond + bytesThird;
xrefstream.Content.Position = 0;
BinaryReader reader = new BinaryReader(xrefstream.Content);
for (int i = 0; i < sectionIndex.Length / 2; i++)
{
int startObjectNumber = ((PdfInteger)sectionIndex[i * 2]).Value;
int numberOfEntries = ((PdfInteger)sectionIndex[i * 2 + 1]).Value;
PdfXrefSection section = new PdfXrefSection((UInt32)startObjectNumber);
for (int j = 0; j < numberOfEntries; j++)
{
byte[] bytes = reader.ReadBytes(bytesTotal);
int entryType = 1;
if (bytesFirst > 0)
{
entryType = (int)ReadBigEndianInterger(bytes, 0, bytesFirst);
}
PdfXrefEntry entry;
switch (entryType)
{
case 0: //free object
entry = ReadFreeEntry(bytesFirst, bytesSecond, bytesThird, bytes);
break;
case 1: //normal object
entry = ReadNormalEntry(bytesFirst, bytesSecond, bytesThird, bytes);
break;
case 2: //compressed object
entry = ReadCompressedEntry(bytesFirst, bytesSecond, bytesThird, bytes);
break;
default:
entry = new PdfXrefEntryFree();
break;
}
section.Entries.Add(entry);
}
Sections.Add(section);
}
}
private PdfXrefEntryCompressed ReadCompressedEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
{
PdfXrefEntryCompressed entry = new PdfXrefEntryCompressed();
entry.ContainerObjectNumber = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
entry.Index = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
return entry;
}
private PdfXrefEntryNoraml ReadNormalEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
{
PdfXrefEntryNoraml entry = new PdfXrefEntryNoraml(0, 0);
entry.Offset = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
if (bytesThird > 0)
{
entry.Generation = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
}
return entry;
}
private PdfXrefEntryFree ReadFreeEntry(int bytesFirst, int bytesSecond, int bytesThird, byte[] bytes)
{
PdfXrefEntryFree entry = new PdfXrefEntryFree();
entry.NextObjectNumber = ReadBigEndianInterger(bytes, bytesFirst, bytesSecond);
entry.Generation = (UInt16)ReadBigEndianInterger(bytes, bytesFirst + bytesSecond, bytesThird);
return entry;
}
private uint ReadBigEndianInterger(byte[] bytes, int startIndex, int numBytes)
{
uint value = 0;
for (int i = 0; i < numBytes; i++)
{
value = (value << 8) + bytes[startIndex + i];
}
return value;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -