示例#1
0
		/// <summary>
		/// Resets the decoder.
		/// </summary>
		/// <remarks>
		/// Resets the state of the decoder.
		/// </remarks>
		public void Reset ()
		{
			state = initial;
			nsaved = 0;
			saved = 0;
			uulen = 0;
		}
示例#2
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Encodings.UUDecoder"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new Unix-to-Unix decoder.
		/// </remarks>
		/// <param name="payloadOnly">
		/// If <c>true</c>, decoding begins immediately rather than after finding a begin-line.
		/// </param>
		public UUDecoder (bool payloadOnly)
		{
			initial = payloadOnly ? UUDecoderState.Payload : UUDecoderState.ExpectBegin;
			Reset ();
		}
示例#3
0
		/// <summary>
		/// Decodes the specified input into the output buffer.
		/// </summary>
		/// <remarks>
		/// <para>Decodes the specified input into the output buffer.</para>
		/// <para>The output buffer should be large enough to hold all of the
		/// decoded input. For estimating the size needed for the output buffer,
		/// see <see cref="EstimateOutputLength"/>.</para>
		/// </remarks>
		/// <returns>The number of bytes written to the output buffer.</returns>
		/// <param name="input">A pointer to the beginning of the input buffer.</param>
		/// <param name="length">The length of the input buffer.</param>
		/// <param name="output">A pointer to the beginning of the output buffer.</param>
		public unsafe int Decode (byte* input, int length, byte* output)
		{
			if (state == UUDecoderState.Ended)
				return 0;

			bool last_was_eoln = uulen == 0;
			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;
			byte c;

			if (state < UUDecoderState.Payload) {
				if ((inptr = ScanBeginMarker (inptr, inend)) == inend)
					return 0;
			}

			while (inptr < inend) {
				if (*inptr == (byte) '\r') {
					inptr++;
					continue;
				}

				if (*inptr == (byte) '\n') {
					last_was_eoln = true;
					inptr++;
					continue;
				}

				if (uulen == 0 || last_was_eoln) {
					// first octet on a line is the uulen octet
					uulen = uudecode_rank[*inptr];
					last_was_eoln = false;
					if (uulen == 0) {
						state = UUDecoderState.Ended;
						break;
					}

					inptr++;
					continue;
				}

				c = *inptr++;

				if (uulen > 0) {
					// save the byte
					saved = (saved << 8) | c;
					nsaved++;

					if (nsaved == 4) {
						byte b0 = (byte) ((saved >> 24) & 0xFF);
						byte b1 = (byte) ((saved >> 16) & 0xFF);
						byte b2 = (byte) ((saved >> 8) & 0xFF);
						byte b3 = (byte) (saved & 0xFF);

						if (uulen >= 3) {
							*outptr++ = (byte) (uudecode_rank[b0] << 2 | uudecode_rank[b1] >> 4);
							*outptr++ = (byte) (uudecode_rank[b1] << 4 | uudecode_rank[b2] >> 2);
							*outptr++ = (byte) (uudecode_rank[b2] << 6 | uudecode_rank[b3]);
							uulen -= 3;
						} else {
							if (uulen >= 1) {
								*outptr++ = (byte) (uudecode_rank[b0] << 2 | uudecode_rank[b1] >> 4);
								uulen--;
							}

							if (uulen >= 1) {
								*outptr++ = (byte) (uudecode_rank[b1] << 4 | uudecode_rank[b2] >> 2);
								uulen--;
							}
						}

						nsaved = 0;
						saved = 0;
					}
				} else {
					break;
				}
			}

			return (int) (outptr - output);
		}
示例#4
0
		unsafe byte* ScanBeginMarker (byte* inptr, byte* inend)
		{
			while (inptr < inend) {
				if (state == UUDecoderState.ExpectBegin) {
					if (nsaved != 0 && nsaved != (byte) '\n') {
						while (inptr < inend && *inptr != (byte) '\n')
							inptr++;

						if (inptr == inend) {
							nsaved = *(inptr - 1);
							return inptr;
						}

						nsaved = *inptr++;
						if (inptr == inend)
							return inptr;
					}

					nsaved = *inptr++;
					if (nsaved != (byte) 'b')
						continue;

					state = UUDecoderState.B;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.B) {
					nsaved = *inptr++;
					if (nsaved != (byte) 'e') {
						state = UUDecoderState.ExpectBegin;
						continue;
					}

					state = UUDecoderState.Be;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.Be) {
					nsaved = *inptr++;
					if (nsaved != (byte) 'g') {
						state = UUDecoderState.ExpectBegin;
						continue;
					}

					state = UUDecoderState.Beg;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.Beg) {
					nsaved = *inptr++;
					if (nsaved != (byte) 'i') {
						state = UUDecoderState.ExpectBegin;
						continue;
					}

					state = UUDecoderState.Begi;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.Begi) {
					nsaved = *inptr++;
					if (nsaved != (byte) 'n') {
						state = UUDecoderState.ExpectBegin;
						continue;
					}

					state = UUDecoderState.Begin;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.Begin) {
					nsaved = *inptr++;
					if (nsaved != (byte) ' ') {
						state = UUDecoderState.ExpectBegin;
						continue;
					}

					state = UUDecoderState.ExpectPayload;
					if (inptr == inend)
						return inptr;
				}

				if (state == UUDecoderState.ExpectPayload) {
					while (inptr < inend && *inptr != (byte) '\n')
						inptr++;

					if (inptr == inend)
						return inptr;

					state = UUDecoderState.Payload;
					nsaved = 0;

					return inptr + 1;
				}
			}

			return inptr;
		}
示例#5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MimeKit.Encodings.UUDecoder"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a new Unix-to-Unix decoder.
 /// </remarks>
 /// <param name="payloadOnly">
 /// If <c>true</c>, decoding begins immediately rather than after finding a begin-line.
 /// </param>
 public UUDecoder(bool payloadOnly)
 {
     initial = payloadOnly ? UUDecoderState.Payload : UUDecoderState.ExpectBegin;
     Reset();
 }
示例#6
0
        /// <summary>
        /// Decodes the specified input into the output buffer.
        /// </summary>
        /// <remarks>
        /// <para>Decodes the specified input into the output buffer.</para>
        /// <para>The output buffer should be large enough to hold all of the
        /// decoded input. For estimating the size needed for the output buffer,
        /// see <see cref="EstimateOutputLength"/>.</para>
        /// </remarks>
        /// <returns>The number of bytes written to the output buffer.</returns>
        /// <param name="input">A pointer to the beginning of the input buffer.</param>
        /// <param name="length">The length of the input buffer.</param>
        /// <param name="output">A pointer to the beginning of the output buffer.</param>
        public unsafe int Decode(byte *input, int length, byte *output)
        {
            if (state == UUDecoderState.Ended)
            {
                return(0);
            }

            bool  last_was_eoln = uulen == 0;
            byte *inend         = input + length;
            byte *outptr        = output;
            byte *inptr         = input;
            byte  c;

            if (state < UUDecoderState.Payload)
            {
                if ((inptr = ScanBeginMarker(inptr, inend)) == inend)
                {
                    return(0);
                }
            }

            while (inptr < inend)
            {
                if (*inptr == (byte)'\r')
                {
                    inptr++;
                    continue;
                }

                if (*inptr == (byte)'\n')
                {
                    last_was_eoln = true;
                    inptr++;
                    continue;
                }

                if (uulen == 0 || last_was_eoln)
                {
                    // first octet on a line is the uulen octet
                    uulen         = uudecode_rank[*inptr];
                    last_was_eoln = false;
                    if (uulen == 0)
                    {
                        state = UUDecoderState.Ended;
                        break;
                    }

                    inptr++;
                    continue;
                }

                c = *inptr++;

                if (uulen > 0)
                {
                    // save the byte
                    saved = (saved << 8) | c;
                    nsaved++;

                    if (nsaved == 4)
                    {
                        byte b0 = (byte)((saved >> 24) & 0xFF);
                        byte b1 = (byte)((saved >> 16) & 0xFF);
                        byte b2 = (byte)((saved >> 8) & 0xFF);
                        byte b3 = (byte)(saved & 0xFF);

                        if (uulen >= 3)
                        {
                            *outptr++ = (byte)(uudecode_rank[b0] << 2 | uudecode_rank[b1] >> 4);
                            *outptr++ = (byte)(uudecode_rank[b1] << 4 | uudecode_rank[b2] >> 2);
                            *outptr++ = (byte)(uudecode_rank[b2] << 6 | uudecode_rank[b3]);
                            uulen -= 3;
                        }
                        else
                        {
                            if (uulen >= 1)
                            {
                                *outptr++ = (byte)(uudecode_rank[b0] << 2 | uudecode_rank[b1] >> 4);
                                uulen--;
                            }

                            if (uulen >= 1)
                            {
                                *outptr++ = (byte)(uudecode_rank[b1] << 4 | uudecode_rank[b2] >> 2);
                                uulen--;
                            }
                        }

                        nsaved = 0;
                        saved  = 0;
                    }
                }
                else
                {
                    break;
                }
            }

            return((int)(outptr - output));
        }
示例#7
0
        unsafe byte *ScanBeginMarker(byte *inptr, byte *inend)
        {
            while (inptr < inend)
            {
                if (state == UUDecoderState.ExpectBegin)
                {
                    if (nsaved != 0 && nsaved != (byte)'\n')
                    {
                        while (inptr < inend && *inptr != (byte)'\n')
                        {
                            inptr++;
                        }

                        if (inptr == inend)
                        {
                            nsaved = *(inptr - 1);
                            return(inptr);
                        }

                        nsaved = *inptr++;
                        if (inptr == inend)
                        {
                            return(inptr);
                        }
                    }

                    nsaved = *inptr++;
                    if (nsaved != (byte)'b')
                    {
                        continue;
                    }

                    state = UUDecoderState.B;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.B)
                {
                    nsaved = *inptr++;
                    if (nsaved != (byte)'e')
                    {
                        state = UUDecoderState.ExpectBegin;
                        continue;
                    }

                    state = UUDecoderState.Be;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.Be)
                {
                    nsaved = *inptr++;
                    if (nsaved != (byte)'g')
                    {
                        state = UUDecoderState.ExpectBegin;
                        continue;
                    }

                    state = UUDecoderState.Beg;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.Beg)
                {
                    nsaved = *inptr++;
                    if (nsaved != (byte)'i')
                    {
                        state = UUDecoderState.ExpectBegin;
                        continue;
                    }

                    state = UUDecoderState.Begi;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.Begi)
                {
                    nsaved = *inptr++;
                    if (nsaved != (byte)'n')
                    {
                        state = UUDecoderState.ExpectBegin;
                        continue;
                    }

                    state = UUDecoderState.Begin;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.Begin)
                {
                    nsaved = *inptr++;
                    if (nsaved != (byte)' ')
                    {
                        state = UUDecoderState.ExpectBegin;
                        continue;
                    }

                    state = UUDecoderState.ExpectPayload;
                    if (inptr == inend)
                    {
                        return(inptr);
                    }
                }

                if (state == UUDecoderState.ExpectPayload)
                {
                    while (inptr < inend && *inptr != (byte)'\n')
                    {
                        inptr++;
                    }

                    if (inptr == inend)
                    {
                        return(inptr);
                    }

                    state  = UUDecoderState.Payload;
                    nsaved = 0;

                    return(inptr + 1);
                }
            }

            return(inptr);
        }