public virtual async Task <StorageResponseHolder> Read(string key , string directory = null , CancellationToken?cancel = null , bool useEncryption = true) { var request = new StorageRequestHolder(key, cancel, directory); return(await CallCloudBlockBlob(request, async (rq, rs, exists) => { if (exists) { var sData = new MemoryStream(); await rq.Blob.DownloadToStreamAsync(sData, rq.CancelSet); rs.Data = new byte[sData.Length]; sData.Position = 0; sData.Read(rs.Data, 0, rs.Data.Length); // If encryption provided decrypt the blob if (useEncryption && mEncryption != null) { rs.Data = mEncryption.Decrypt(rs.Data); } MetadataGet(rq.Blob, rs); } else { rq.CopyTo(rs); } rs.IsSuccess = exists; rs.StatusCode = exists ? 200 : 404; })); }
public bool MoveNext() { if (isDisposed) { throw new ObjectDisposedException(nameof(PdfTokenScanner)); } // Read until we find object-number generation obj, e.g. "69 420 obj". int tokensRead = 0; while (coreTokenScanner.MoveNext() && !Equals(coreTokenScanner.CurrentToken, OperatorToken.StartObject)) { if (coreTokenScanner.CurrentToken is CommentToken) { continue; } tokensRead++; previousTokens[0] = previousTokens[1]; previousTokenPositions[0] = previousTokenPositions[1]; previousTokens[1] = previousTokens[2]; previousTokenPositions[1] = previousTokenPositions[2]; previousTokens[2] = coreTokenScanner.CurrentToken; previousTokenPositions[2] = coreTokenScanner.CurrentTokenStart; } // We only read partial tokens. if (tokensRead < 2) { return(false); } var startPosition = previousTokenPositions[1]; var objectNumber = previousTokens[1] as NumericToken; var generation = previousTokens[2] as NumericToken; if (objectNumber == null || generation == null) { // Handle case where the scanner correctly reads most of an object token but includes too much of the first token // specifically %%EOF1 0 obj where scanning starts from 'F'. if (generation != null && previousTokens[1] is OperatorToken op) { var match = EndsWithNumberRegex.Match(op.Data); if (match.Success && int.TryParse(match.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var number)) { startPosition = previousTokenPositions[1] + match.Index; objectNumber = new NumericToken(number); } else { return(false); } } else { return(false); } } var readStream = false; // Read all tokens between obj and endobj. while (coreTokenScanner.MoveNext() && !Equals(coreTokenScanner.CurrentToken, OperatorToken.EndObject)) { if (coreTokenScanner.CurrentToken is CommentToken) { continue; } if (ReferenceEquals(coreTokenScanner.CurrentToken, OperatorToken.StartObject)) { if (readStream && readTokens[0] is StreamToken streamRead) { readTokens.Clear(); readTokens.Add(streamRead); coreTokenScanner.Seek(previousTokenPositions[0]); break; } if (readTokens.Count == 3 && readTokens[1] is NumericToken extraObjNum && readTokens[2] is NumericToken extraGenNum) { // An obj was encountered after reading the actual token and the object and generation number of the following token. var actualReference = new IndirectReference(objectNumber.Int, generation.Int); var actualToken = encryptionHandler.Decrypt(actualReference, readTokens[0]); CurrentToken = new ObjectToken(startPosition, actualReference, actualToken); readTokens.Clear(); coreTokenScanner.Seek(previousTokenPositions[0]); return(true); } // This should never happen. Debug.Assert(false, "Encountered a start object 'obj' operator before the end of the previous object."); return(false); } if (ReferenceEquals(coreTokenScanner.CurrentToken, OperatorToken.StartStream)) { var streamIdentifier = new IndirectReference(objectNumber.Long, generation.Int); // Prevent an infinite loop where a stream's length references the stream or the stream's offset. var getLengthFromFile = !isBruteForcing && !(callingObject.HasValue && callingObject.Value.Equals(streamIdentifier)); var outerCallingObject = callingObject; try { callingObject = streamIdentifier; // Read stream: special case. if (TryReadStream(coreTokenScanner.CurrentTokenStart, getLengthFromFile, out var stream)) { readTokens.Clear(); readTokens.Add(stream); readStream = true; } } finally { callingObject = outerCallingObject; } } else { readTokens.Add(coreTokenScanner.CurrentToken); } previousTokens[0] = previousTokens[1]; previousTokenPositions[0] = previousTokenPositions[1]; previousTokens[1] = previousTokens[2]; previousTokenPositions[1] = previousTokenPositions[2]; previousTokens[2] = coreTokenScanner.CurrentToken; previousTokenPositions[2] = coreTokenScanner.CurrentTokenStart; } if (!readStream && !ReferenceEquals(coreTokenScanner.CurrentToken, OperatorToken.EndObject)) { readTokens.Clear(); return(false); } var reference = new IndirectReference(objectNumber.Long, generation.Int); IToken token; if (readTokens.Count == 3 && readTokens[0] is NumericToken objNum && readTokens[1] is NumericToken genNum && ReferenceEquals(readTokens[2], OperatorToken.R)) { // I have no idea if this can ever happen. token = new IndirectReferenceToken(new IndirectReference(objNum.Long, genNum.Int)); }