private CosBase ReadNormalObjectStream(IRandomAccessRead reader, CosBase currentBase, long offset, bool isLenientParsing, out string endObjectKey) { if (currentBase is PdfDictionary dictionary) { PdfRawStream stream = streamParser.Parse(reader, dictionary, isLenientParsing, null); currentBase = stream; } else { // this is not legal // the combination of a dict and the stream/endstream // forms a complete stream object throw new InvalidOperationException($"Stream not preceded by dictionary (offset: {offset})."); } ReadHelper.SkipSpaces(reader); endObjectKey = ReadHelper.ReadLine(reader); // we have case with a second 'endstream' before endobj if (!endObjectKey.StartsWith("endobj") && endObjectKey.StartsWith("endstream")) { endObjectKey = endObjectKey.Substring(9).Trim(); if (endObjectKey.Length == 0) { // no other characters in extra endstream line // read next line endObjectKey = ReadHelper.ReadLine(reader); } } return(currentBase); }
public static CosBase GetDictionaryObject(this PdfDictionary dictionary, CosName firstKey, CosName secondKey) { CosBase result = dictionary.GetDictionaryObject(firstKey); if (result == null && secondKey != null) { result = dictionary.GetDictionaryObject(secondKey); } return(result); }
private ICosNumber GetLength(IRandomAccessRead source, CosBase lengthBaseObj, CosName streamType, bool isLenientParsing, IPdfObjectParser parser) { if (lengthBaseObj == null) { return(null); } // Length is given directly in the stream dictionary if (lengthBaseObj is ICosNumber number) { return(number); } // length in referenced object if (lengthBaseObj is CosObject lengthObj) { var currentObject = lengthObj.GetObject(); if (currentObject == null) { if (parser == null) { throw new InvalidOperationException("This method required access to the PDF object parser but it was not created yet. Figure out how to fix this."); } var currentOffset = source.GetPosition(); var obj = parser.Parse(lengthObj.ToIndirectReference(), source, isLenientParsing); source.Seek(currentOffset); if (obj is ICosNumber referenceNumber) { return(referenceNumber); } throw new InvalidOperationException("Length object content was not read."); } if (currentObject is ICosNumber objectNumber) { return(objectNumber); } throw new InvalidOperationException("Wrong type of referenced length object " + lengthObj + ": " + lengthObj.GetObject().GetType().Name); } throw new InvalidOperationException($"Wrong type of length object: {lengthBaseObj.GetType().Name}"); }
public CosBase Parse(IRandomAccessRead reader, CosObjectPool pool) { CosBase retval = null; ReadHelper.SkipSpaces(reader); int nextByte = reader.Peek(); if (nextByte == -1) { return(null); } char c = (char)nextByte; switch (c) { case '<': { // pull off first left bracket int leftBracket = reader.Read(); // check for second left bracket c = (char)reader.Peek(); reader.Unread(leftBracket); if (c == '<') { retval = dictionaryParser.Parse(reader, this, pool); ReadHelper.SkipSpaces(reader); } else { retval = stringParser.Parse(reader); } break; } case '[': { // array retval = arrayParser.Parse(reader, this, pool); break; } case '(': retval = stringParser.Parse(reader); break; case '/': // name retval = nameParser.Parse(reader); break; case 'n': { // null ReadHelper.ReadExpectedString(reader, "null"); retval = CosNull.Null; break; } case 't': { string truestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(4)); if (truestring.Equals("true")) { retval = PdfBoolean.True; } else { throw new IOException("expected true actual='" + truestring + "' " + reader + "' at offset " + reader.GetPosition()); } break; } case 'f': { string falsestring = OtherEncodings.BytesAsLatin1String(reader.ReadFully(5)); if (falsestring.Equals("false")) { retval = PdfBoolean.False; } else { throw new IOException("expected false actual='" + falsestring + "' " + reader + "' at offset " + reader.GetPosition()); } break; } case 'R': reader.Read(); retval = new CosObject(null); break; default: if (char.IsDigit(c) || c == '-' || c == '+' || c == '.') { StringBuilder buf = new StringBuilder(); int ic = reader.Read(); c = (char)ic; while (char.IsDigit(c) || c == '-' || c == '+' || c == '.' || c == 'E' || c == 'e') { buf.Append(c); ic = reader.Read(); c = (char)ic; } if (ic != -1) { reader.Unread(ic); } retval = CosNumberFactory.get(buf.ToString()) as CosBase; } else { //This is not suppose to happen, but we will allow for it //so we are more compatible with POS writers that don't //follow the spec string badstring = ReadHelper.ReadString(reader); if (badstring == string.Empty) { int peek = reader.Peek(); // we can end up in an infinite loop otherwise throw new IOException("Unknown dir object c='" + c + "' cInt=" + (int)c + " peek='" + (char)peek + "' peekInt=" + peek + " at offset " + reader.GetPosition()); } // if it's an endstream/endobj, we want to put it back so the caller will see it if (string.Equals("endobj", badstring) || string.Equals("endstream", badstring)) { reader.Unread(OtherEncodings.StringAsLatin1Bytes(badstring)); } } break; } return(retval); }