1 package org.bouncycastle.asn1; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 class ConstructedOctetStream 7 extends InputStream 8 { 9 private final ASN1StreamParser _parser; 10 11 private boolean _first = true; 12 private InputStream _currentStream; 13 ConstructedOctetStream( ASN1StreamParser parser)14 ConstructedOctetStream( 15 ASN1StreamParser parser) 16 { 17 _parser = parser; 18 } 19 read(byte[] b, int off, int len)20 public int read(byte[] b, int off, int len) throws IOException 21 { 22 if (_currentStream == null) 23 { 24 if (!_first) 25 { 26 return -1; 27 } 28 29 ASN1OctetStringParser next = getNextParser(); 30 if (next == null) 31 { 32 return -1; 33 } 34 35 _first = false; 36 _currentStream = next.getOctetStream(); 37 } 38 39 int totalRead = 0; 40 41 for (;;) 42 { 43 int numRead = _currentStream.read(b, off + totalRead, len - totalRead); 44 45 if (numRead >= 0) 46 { 47 totalRead += numRead; 48 49 if (totalRead == len) 50 { 51 return totalRead; 52 } 53 } 54 else 55 { 56 ASN1OctetStringParser next = getNextParser(); 57 if (next == null) 58 { 59 _currentStream = null; 60 return totalRead < 1 ? -1 : totalRead; 61 } 62 63 _currentStream = next.getOctetStream(); 64 } 65 } 66 } 67 read()68 public int read() 69 throws IOException 70 { 71 if (_currentStream == null) 72 { 73 if (!_first) 74 { 75 return -1; 76 } 77 78 ASN1OctetStringParser next = getNextParser(); 79 if (next == null) 80 { 81 return -1; 82 } 83 84 _first = false; 85 _currentStream = next.getOctetStream(); 86 } 87 88 for (;;) 89 { 90 int b = _currentStream.read(); 91 92 if (b >= 0) 93 { 94 return b; 95 } 96 97 ASN1OctetStringParser next = getNextParser(); 98 if (next == null) 99 { 100 _currentStream = null; 101 return -1; 102 } 103 104 _currentStream = next.getOctetStream(); 105 } 106 } 107 getNextParser()108 private ASN1OctetStringParser getNextParser() throws IOException 109 { 110 ASN1Encodable asn1Obj = _parser.readObject(); 111 if (asn1Obj == null) 112 { 113 return null; 114 } 115 116 if (asn1Obj instanceof ASN1OctetStringParser) 117 { 118 return (ASN1OctetStringParser)asn1Obj; 119 } 120 121 throw new IOException("unknown object encountered: " + asn1Obj.getClass()); 122 } 123 } 124