Beispiel #1
0
    public static string EncodeComment(string str, int index, int endIndex) {
      // NOTE: Assumes that the comment is syntactically valid
#if DEBUG
      if (str == null) {
        throw new ArgumentNullException("str");
      }
      if (index < 0) {
        throw new ArgumentException("index (" + index + ") is less than " +
            "0");
      }
      if (index > str.Length) {
        throw new ArgumentException("index (" + index + ") is more than " +
          str.Length);
      }
      if (endIndex < 0) {
        throw new ArgumentException("endIndex (" + endIndex +
            ") is less than " + "0");
      }
      if (endIndex > str.Length) {
        throw new ArgumentException("endIndex (" + endIndex +
          ") is more than " + str.Length);
      }
#endif
      int length = endIndex - index;
      if (length < 2 || str[index] != '(' || str[endIndex - 1] != ')') {
        return str.Substring(index, length);
      }
      EncodedWordEncoder encoder;
      int nextComment = str.IndexOf('(', index + 1);
      int nextBackslash = str.IndexOf('\\', index + 1);
      // don't count comments or backslashes beyond
      // the desired portion
      if (nextComment >= endIndex) {
        nextComment = -1;
      }
      if (nextBackslash >= endIndex) {
        nextBackslash = -1;
      }
      bool haveEscape = nextBackslash >= 0;
      if (!haveEscape) {
        // Check for possible folding whitespace
        nextBackslash = str.IndexOf('\n', index + 1);
        if (nextBackslash >= endIndex) {
          nextBackslash = -1;
        }
        haveEscape = nextBackslash >= 0;
      }
      if (nextComment < 0 && nextBackslash < 0) {
        // No escapes or nested comments, so it's relatively easy
        if (length == 2) {
          return "()";
        }
        encoder = new EncodedWordEncoder();
        encoder.AddPrefix("(");
        encoder.AddString(str, index + 1, length - 2);
        encoder.FinalizeEncoding(")");
        return encoder.ToString();
      }
      if (nextBackslash < 0) {
        // No escapes; just look for '(' and ')'
        encoder = new EncodedWordEncoder();
        while (true) {
          int parenStart = index;
          // Get the next run of parentheses
          while (index < endIndex) {
            if (str[index] == '(' || str[index] == ')') {
              ++index;
            } else {
              break;
            }
          }
          // Get the next run of non-parentheses
          int parenEnd = index;
          while (index < endIndex) {
            if (str[index] == '(' || str[index] == ')') {
              break;
            }
            ++index;
          }
          if (parenEnd == index) {
            encoder.FinalizeEncoding(
        str.Substring(
        parenStart,
        parenEnd - parenStart));
            break;
          }
          encoder.AddPrefix(str.Substring(parenStart, parenEnd - parenStart));
          encoder.AddString(str, parenEnd, index - parenEnd);
        }
        return encoder.ToString();
      }
      var builder = new StringBuilder();
      // escapes, but no nested comments
      if (nextComment < 0) {
        // skip the first parenthesis
        ++index;
        while (index < endIndex) {
          if (str[index] == ')') {
            // End of the comment
            break;
          }
          if (str[index] == '\r' && index + 2 < endIndex &&
str[index + 1] == '\n' && (str[index + 2] == 0x20 || str[index + 2] ==
                    0x09)) {
            // Folding whitespace
            builder.Append(str[index + 2]);
            index += 3;
          } else if (str[index] == '\\' && index + 1 < endIndex) {
            // Quoted pair
            int cp = DataUtilities.CodePointAt(str, index + 1);
            if (cp <= 0xffff) {
              {
                builder.Append((char)cp);
              }
            } else if (cp <= 0x10ffff) {
              builder.Append((char)((((cp - 0x10000) >> 10) & 0x3ff) + 0xd800));
              builder.Append((char)(((cp - 0x10000) & 0x3ff) + 0xdc00));
            }
            index += 1 + (cp >= 0x10000 ? 2 : 1);
          } else {
            // Other comment text
            builder.Append(str[index]);
            ++index;
          }
        }
        if (builder.Length == 0) {
          return "()";
        }
        encoder = new EncodedWordEncoder();
        encoder.AddPrefix("(");
        encoder.AddString(builder.ToString());
        encoder.FinalizeEncoding(")");
        return encoder.ToString();
      }
      // escapes and nested comments
      encoder = new EncodedWordEncoder();
      while (true) {
        int parenStart = index;
        // Get the next run of parentheses
        while (index < endIndex) {
          if (str[index] == '(' || str[index] == ')') {
            ++index;
          } else {
            break;
          }
        }
        // Get the next run of non-parentheses
        int parenEnd = index;
        builder.Remove(0, builder.Length);
        while (index < endIndex) {
          if (str[index] == '(' || str[index] == ')') {
            break;
          }
          if (str[index] == '\r' && index + 2 < endIndex &&
str[index + 1] == '\n' && (str[index + 2] == 0x20 || str[index + 2] ==
                0x09)) {
            // Folding whitespace
            builder.Append(str[index + 2]);
            index += 3;
          } else if (str[index] == '\\' && index + 1 < endIndex) {
            // Quoted pair
            int cp = DataUtilities.CodePointAt(str, index + 1);
            if (cp <= 0xffff) {
              builder.Append((char)cp);
            } else if (cp <= 0x10ffff) {
              builder.Append((char)((((cp - 0x10000) >> 10) & 0x3ff) + 0xd800));
              builder.Append((char)(((cp - 0x10000) & 0x3ff) + 0xdc00));
            }
            index += 1 + (cp >= 0x10000 ? 2 : 1);
          } else {
            // Other comment text
            builder.Append(str[index]);
            ++index;
          }
        }
        if (builder.Length == 0) {
          encoder.FinalizeEncoding(
      str.Substring(
      parenStart,
      parenEnd - parenStart));
          break;
        }
        encoder.AddPrefix(str.Substring(parenStart, parenEnd - parenStart));
        encoder.AddString(builder.ToString());
      }
      return encoder.ToString();
    }
Beispiel #2
0
    private static void EncodePhraseTextInternal(
      string str,
 int index,
      int endIndex,
 IList<int[]> tokens,
      StringBuilder builder) {
      // Assumes the value matches the production "phrase"
      // and that there are no comments in the value
      if (index == endIndex) {
        return;  // Empty, so nothing to do
      }
      int index2 = HeaderParser.ParseCFWS(str, index, endIndex, null);
      if (index2 == endIndex) {
        // Just linear whitespace
        builder.Append(str.Substring(index, endIndex - index));
        return;
      }
      if (!PrecededByStartOrLinearWhitespace(str, index2)) {
        // Append a space before the encoded words
        builder.Append(' ');
      } else {
        // Append the linear whitespace
        builder.Append(str.Substring(index, index2 - index));
      }
      var encoder = new EncodedWordEncoder();
      var builderPhrase = new StringBuilder();
      index = index2;
      while (index < endIndex) {
        if (str[index] == '"') {
          // Quoted string
          index = MediaType.skipQuotedString(
   str,
   index,
   endIndex,
   builderPhrase);
        } else {
          // Atom
          index2 = HeaderParser.ParsePhraseAtomOrDot(
  str,
  index,
  endIndex,
  null);
          builderPhrase.Append(str.Substring(index, index2 - index));
          index = index2;
        }
        index2 = HeaderParser.ParseFWS(str, index, endIndex, null);
        if (index2 == endIndex) {
          encoder.AddString(builderPhrase.ToString());
          encoder.FinalizeEncoding();
          builder.Append(encoder.ToString());
          if (index2 != index) {
            builder.Append(str.Substring(index, index2 - index));
          } else if (!FollowedByEndOrLinearWhitespace(
    str,
    endIndex,
    str.Length)) {
            // Add a space if no linear whitespace follows
            builder.Append(' ');
          }
          break;
        }
        if (index2 != index) {
          builderPhrase.Append(' ');
        }
        index = index2;
      }
    }
Beispiel #3
0
 private string SynthesizeField(string name) {
   string fullField = Implode(this.GetMultipleHeaders(name), ", ");
   string value = new EncodedWordEncoder().AddString(fullField)
     .FinalizeEncoding().ToString();
   if (value.Length > 0) {
     value += " <me@" + name + "address.invalid>";
   } else {
     value = "me@" + name + "-address.invalid";
   }
   return value;
 }