示例#1
0
        /// <summary>
        /// Resets the decoder.
        /// </summary>
        /// <remarks>
        /// Resets the state of the decoder.
        /// </remarks>
        public void Reset()
        {
            octet   = (byte)'\n';
            state   = initial;
            escaped = false;
            eoln    = true;

            crc.Reset();
        }
示例#2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MimeKit.Encodings.YDecoder"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a new yEnc decoder.
 /// </remarks>
 /// <param name="payloadOnly">
 /// If <c>true</c>, decoding begins immediately rather than after finding an =ybegin line.
 /// </param>
 public YDecoder(bool payloadOnly)
 {
     initial = payloadOnly ? YDecoderState.Payload : YDecoderState.ExpectYBegin;
     crc     = new Crc32(-1);
     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)
        {
            byte *inend  = input + length;
            byte *outptr = output;
            byte *inptr  = input;

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

                eoln = true;
            }

            if (state == YDecoderState.Ended)
            {
                return(0);
            }

            while (inptr < inend)
            {
                octet = *inptr++;

                if (octet == (byte)'\r')
                {
                    escaped = false;
                    continue;
                }

                if (octet == (byte)'\n')
                {
                    escaped = false;
                    eoln    = true;
                    continue;
                }

                if (escaped)
                {
                    if (eoln && octet == (byte)'y')
                    {
                        // this can only be =yend
                        state = YDecoderState.Ended;
                        break;
                    }

                    escaped = false;
                    eoln    = false;
                    octet  -= 64;
                }
                else if (octet == (byte)'=')
                {
                    escaped = true;
                    continue;
                }
                else
                {
                    eoln = false;
                }

                octet -= 42;

                crc.Update(octet);
                *outptr++ = octet;
            }

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

                        if (inptr == inend)
                        {
                            octet = *(inptr - 1);
                            break;
                        }

                        octet = *inptr++;
                        if (inptr == inend)
                        {
                            break;
                        }
                    }

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

                    state = YDecoderState.YBeginEqual;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqual)
                {
                    octet = *inptr++;
                    if (octet != (byte)'y')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualY;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualY)
                {
                    octet = *inptr++;
                    if (octet != (byte)'b')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualYB;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualYB)
                {
                    octet = *inptr++;
                    if (octet != (byte)'e')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualYBe;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualYBe)
                {
                    octet = *inptr++;
                    if (octet != (byte)'g')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualYBeg;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualYBeg)
                {
                    octet = *inptr++;
                    if (octet != (byte)'i')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualYBegi;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualYBegi)
                {
                    octet = *inptr++;
                    if (octet != (byte)'n')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.YBeginEqualYBegin;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

                if (state == YDecoderState.YBeginEqualYBegin)
                {
                    octet = *inptr++;
                    if (octet != (byte)' ')
                    {
                        state = YDecoderState.ExpectYBegin;
                        continue;
                    }

                    state = YDecoderState.ExpectYBeginNewLine;
                    if (inptr == inend)
                    {
                        break;
                    }
                }

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

                    if (inptr == inend)
                    {
                        octet = *(inptr - 1);
                        break;
                    }

                    state = YDecoderState.ExpectYPartOrPayload;
                    octet = *inptr++;
                    break;
                }

                if (state == YDecoderState.ExpectYPartOrPayload)
                {
                    if (*inptr != (byte)'=')
                    {
                        state = YDecoderState.Payload;
                        break;
                    }

                    state   = YDecoderState.YPartEqual;
                    octet   = *inptr++;
                    escaped = true;

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

                if (state == YDecoderState.YPartEqual)
                {
                    if (*inptr != (byte)'y')
                    {
                        state = YDecoderState.Payload;
                        return(inptr);
                    }

                    state = YDecoderState.YPartEqualY;
                    octet = *inptr++;

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

                if (state == YDecoderState.YPartEqualY)
                {
                    if (*inptr == (byte)'e')
                    {
                        // we got an "=ye" which can only be an "=yend"
                        state = YDecoderState.Ended;
                        return(inptr);
                    }

                    if (*inptr != (byte)'p')
                    {
                        state = YDecoderState.ExpectYBeginNewLine;
                        continue;
                    }

                    state = YDecoderState.YPartEqualYP;
                    octet = *inptr++;

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

                if (state == YDecoderState.YPartEqualYP)
                {
                    if (*inptr != (byte)'a')
                    {
                        state = YDecoderState.ExpectYBeginNewLine;
                        continue;
                    }

                    state = YDecoderState.YPartEqualYPa;
                    octet = *inptr++;

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

                if (state == YDecoderState.YPartEqualYPa)
                {
                    if (*inptr != (byte)'r')
                    {
                        state = YDecoderState.ExpectYBeginNewLine;
                        continue;
                    }

                    state = YDecoderState.YPartEqualYPar;
                    octet = *inptr++;

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

                if (state == YDecoderState.YPartEqualYPar)
                {
                    if (*inptr != (byte)'t')
                    {
                        state = YDecoderState.ExpectYBeginNewLine;
                        continue;
                    }

                    state = YDecoderState.YPartEqualYPart;
                    octet = *inptr++;

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

                if (state == YDecoderState.YPartEqualYPart)
                {
                    if (*inptr != (byte)' ')
                    {
                        state = YDecoderState.ExpectYBeginNewLine;
                        continue;
                    }

                    state = YDecoderState.ExpectYPartNewLine;
                    octet = *inptr++;

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

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

                    if (inptr == inend)
                    {
                        octet = *(inptr - 1);
                        break;
                    }

                    state = YDecoderState.Payload;
                    octet = *inptr++;
                    break;
                }
            }

            return(inptr);
        }
示例#5
0
		/// <summary>
		/// Initializes a new instance of the <see cref="MimeKit.Encodings.YDecoder"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new yEnc decoder.
		/// </remarks>
		/// <param name="payloadOnly">
		/// If <c>true</c>, decoding begins immediately rather than after finding an =ybegin line.
		/// </param>
		public YDecoder (bool payloadOnly)
		{
			initial = payloadOnly ? YDecoderState.Payload : YDecoderState.ExpectYBegin;
			crc = new Crc32 (-1);
			Reset ();
		}
示例#6
0
		/// <summary>
		/// Resets the decoder.
		/// </summary>
		/// <remarks>
		/// Resets the state of the decoder.
		/// </remarks>
		public void Reset ()
		{
			octet = (byte) '\n';
			state = initial;
			escaped = false;
			eoln = true;

			crc.Reset ();
		}
示例#7
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)
		{
			byte* inend = input + length;
			byte* outptr = output;
			byte* inptr = input;

			if (state < YDecoderState.Payload) {
				if ((inptr = ScanYBeginMarker (inptr, inend)) == inend)
					return 0;

				eoln = true;
			}

			if (state == YDecoderState.Ended)
				return 0;

			while (inptr < inend) {
				octet = *inptr++;

				if (octet == (byte) '\r') {
					escaped = false;
					continue;
				}

				if (octet == (byte) '\n') {
					escaped = false;
					eoln = true;
					continue;
				}

				if (escaped) {
					if (eoln && octet == (byte) 'y') {
						// this can only be =yend
						state = YDecoderState.Ended;
						break;
					}

					escaped = false;
					eoln = false;
					octet -= 64;
				} else if (octet == (byte) '=') {
					escaped = true;
					continue;
				} else {
					eoln = false;
				}

				octet -= 42;

				crc.Update (octet);
				*outptr++ = octet;
			}

			return (int) (outptr - output);
		}
示例#8
0
		unsafe byte* ScanYBeginMarker (byte* inptr, byte* inend)
		{
			while (inptr < inend) {
				if (state == YDecoderState.ExpectYBegin) {
					if (octet != (byte) '\n') {
						while (inptr < inend && *inptr != (byte) '\n')
							inptr++;

						if (inptr == inend) {
							octet = *(inptr - 1);
							break;
						}

						octet = *inptr++;
						if (inptr == inend)
							break;
					}

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

					state = YDecoderState.YBeginEqual;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqual) {
					octet = *inptr++;
					if (octet != (byte) 'y') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualY;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualY) {
					octet = *inptr++;
					if (octet != (byte) 'b') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualYB;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualYB) {
					octet = *inptr++;
					if (octet != (byte) 'e') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualYBe;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualYBe) {
					octet = *inptr++;
					if (octet != (byte) 'g') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualYBeg;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualYBeg) {
					octet = *inptr++;
					if (octet != (byte) 'i') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualYBegi;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualYBegi) {
					octet = *inptr++;
					if (octet != (byte) 'n') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.YBeginEqualYBegin;
					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YBeginEqualYBegin) {
					octet = *inptr++;
					if (octet != (byte) ' ') {
						state = YDecoderState.ExpectYBegin;
						continue;
					}

					state = YDecoderState.ExpectYBeginNewLine;
					if (inptr == inend)
						break;
				}

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

					if (inptr == inend) {
						octet = *(inptr - 1);
						break;
					}

					state = YDecoderState.ExpectYPartOrPayload;
					octet = *inptr++;
					break;
				}

				if (state == YDecoderState.ExpectYPartOrPayload) {
					if (*inptr != (byte) '=') {
						state = YDecoderState.Payload;
						break;
					}

					state = YDecoderState.YPartEqual;
					octet = *inptr++;
					escaped = true;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqual) {
					if (*inptr != (byte) 'y') {
						state = YDecoderState.Payload;
						return inptr;
					}

					state = YDecoderState.YPartEqualY;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqualY) {
					if (*inptr == (byte) 'e') {
						// we got an "=ye" which can only be an "=yend"
						state = YDecoderState.Ended;
						return inptr;
					}

					if (*inptr != (byte) 'p') {
						state = YDecoderState.ExpectYBeginNewLine;
						continue;
					}

					state = YDecoderState.YPartEqualYP;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqualYP) {
					if (*inptr != (byte) 'a') {
						state = YDecoderState.ExpectYBeginNewLine;
						continue;
					}

					state = YDecoderState.YPartEqualYPa;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqualYPa) {
					if (*inptr != (byte) 'r') {
						state = YDecoderState.ExpectYBeginNewLine;
						continue;
					}

					state = YDecoderState.YPartEqualYPar;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqualYPar) {
					if (*inptr != (byte) 't') {
						state = YDecoderState.ExpectYBeginNewLine;
						continue;
					}

					state = YDecoderState.YPartEqualYPart;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

				if (state == YDecoderState.YPartEqualYPart) {
					if (*inptr != (byte) ' ') {
						state = YDecoderState.ExpectYBeginNewLine;
						continue;
					}

					state = YDecoderState.ExpectYPartNewLine;
					octet = *inptr++;

					if (inptr == inend)
						break;
				}

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

					if (inptr == inend) {
						octet = *(inptr - 1);
						break;
					}

					state = YDecoderState.Payload;
					octet = *inptr++;
					break;
				}
			}

			return inptr;
		}