public static PdfObject ParseAny(Lexer lexer, string endToken) { string token = lexer.ReadToken(); if (token is null) { return(null); } switch (token) { case "null": return(PdfNull.Null); // null object case "true": case "false": return(PdfBoolean.Parse(token)); case "/": return(PdfName.Parse(lexer)); case "%": return(PdfComment.Parse(lexer)); case "<": return(PdfHexadecimalString.Parse(lexer)); case "(": return(PdfLiteralString.Parse(lexer)); case "xref": return(PdfXRef.Parse(lexer)); case "trailer": return(PdfTrailer.Parse(lexer)); case "<<": var dic = PdfDictionary.Parse(lexer); // check for stream and combine put dictionary into stream object token = lexer.PeekToken1(); if (token == "stream") { return(PdfStream.Parse(dic, lexer)); } return(dic); case "[": return(PdfArray.Parse(lexer)); case "startxref": return(PdfStartXRef.Parse(lexer)); case ")": case ">": case ">>": case "]": case "}": case "stream": case "endstream": case "endobj": if (endToken == token) { return(null); // expected end } throw new ParsingException("Out of sync"); default: // must be an integer or double value PdfNumeric num = PdfNumeric.Parse(token); if (num.IsInteger) { string token2 = lexer.PeekToken2(); switch (token2) { case "obj": return(PdfIndirectObject.Parse(lexer, num.ToInt32())); case "R": PdfIndirectReference ir = PdfIndirectReference.Parse(lexer, num.ToInt32()); ir.Resolver = lexer.IndirectReferenceResolver; return(ir); default: // ignore; return(num); } } else { return(num); } } throw new ParsingException("Could not read object"); }
public static PdfXRefSection Parse(PdfStream pdfStream) { var dictionary = pdfStream.StreamDictionary; var type = dictionary["Type"] as PdfName; if (type.Name != "XRef") { throw new ParsingException("A stream of type XRef is expected"); } // W[1 2 1] (4 columns) // W[1 3 1] (5 columns, larger indexes) var w = dictionary["W"] as PdfArray; int firstId = 0; int size = 0; if (dictionary.TryGetValue("Index", out IPdfObject indexObject)) { var index = (PdfArray)indexObject; firstId = ((PdfNumeric)index.Items[0]).ToInt32(); size = ((PdfNumeric)index.Items[1]).ToInt32(); } else if (dictionary.TryGetValue("Size", out IPdfObject sizeObject)) { size = ((PdfNumeric)sizeObject).ToInt32(); } int items = w.Items.Count; // for xref this shall always be 3 if (items != 3) { throw new ParsingException("The W[] parameter must contain 3 columns for an XRef"); } int[] sizes = new int[w.Items.Count]; int bytesPerEntry = 0; for (int i = 0; i < items; i++) { sizes[i] = ((PdfNumeric)w.Items[i]).ToInt32(); bytesPerEntry += sizes[i]; } var decodedXRef = pdfStream.Decode(); // Use W[...] to build up the xref int rowCount = decodedXRef.Length / bytesPerEntry; if (size != rowCount) { throw new ParsingException("The number of refs inside the Index value must match the actual refs count present in the stream"); } var entries = new IPdfObject[rowCount]; for (int row = 0; row < rowCount; row++) { var entry = PdfXRefEntry.Parse(firstId + row, decodedXRef, sizes, row, bytesPerEntry); entries[row] = entry; } return(new PdfXRefSection(firstId, size, entries)); }