summary refs log tree commit diff
path: root/crypto/src/bcpg/UserAttributeSubpacketsReader.cs
blob: f0cc1b8e41413eb6ff947d4401bba86f8e1e7200 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
using System;
using System.IO;
using Org.BouncyCastle.Bcpg.Attr;
using Org.BouncyCastle.Utilities.IO;

namespace Org.BouncyCastle.Bcpg
{
    /**
    * reader for user attribute sub-packets
    */
    public class UserAttributeSubpacketsParser
    {
        private readonly Stream input;

        public UserAttributeSubpacketsParser(
            Stream input)
        {
            this.input = input;
        }

        public virtual UserAttributeSubpacket ReadPacket()
        {
            int l = input.ReadByte();
            if (l < 0)
                return null;

            int bodyLen = 0;
            bool longLength = false;
            if (l < 192)
            {
                bodyLen = l;
            }
            else if (l <= 223)
            {
                bodyLen = ((l - 192) << 8) + (input.ReadByte()) + 192;
            }
            else if (l == 255)
            {
                bodyLen = (input.ReadByte() << 24) | (input.ReadByte() << 16)
                    |  (input.ReadByte() << 8)  | input.ReadByte();
                longLength = true;
            }
            else
            {
                throw new IOException("unrecognised length reading user attribute sub packet");
            }

            int tag = input.ReadByte();
            if (tag < 0)
                throw new EndOfStreamException("unexpected EOF reading user attribute sub packet");

            byte[] data = new byte[bodyLen - 1];
            if (Streams.ReadFully(input, data) < data.Length)
                throw new EndOfStreamException();

            UserAttributeSubpacketTag type = (UserAttributeSubpacketTag) tag;
            switch (type)
            {
                case UserAttributeSubpacketTag.ImageAttribute:
                    return new ImageAttrib(longLength, data);
            }
            return new UserAttributeSubpacket(type, longLength, data);
        }
    }
}