TextReturnReader.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // System.Web.Services.Protocols.TextReturnReader.cs
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. //
  10. using System;
  11. using System.Text.RegularExpressions;
  12. using System.Collections;
  13. using System.IO;
  14. using System.Reflection;
  15. using System.Net;
  16. namespace System.Web.Services.Protocols {
  17. public class TextReturnReader : MimeReturnReader {
  18. ReturnInfo info;
  19. #region Constructors
  20. public TextReturnReader ()
  21. {
  22. }
  23. #endregion // Constructors
  24. #region Methods
  25. public override object GetInitializer (LogicalMethodInfo methodInfo)
  26. {
  27. Type rt = methodInfo.ReturnType;
  28. FieldInfo[] fields = rt.GetFields ();
  29. ArrayList matchInfos = new ArrayList ();
  30. foreach (FieldInfo field in fields)
  31. {
  32. object[] ats = field.GetCustomAttributes (typeof(MatchAttribute), true);
  33. if (ats.Length == 0) continue;
  34. MatchInfo mi = new MatchInfo ();
  35. mi.Field = field;
  36. mi.Match = (MatchAttribute) ats[0];
  37. RegexOptions opts = RegexOptions.Multiline;
  38. if (mi.Match.IgnoreCase) opts |= RegexOptions.IgnoreCase;
  39. mi.Regex = new Regex (mi.Match.Pattern, opts);
  40. matchInfos.Add (mi);
  41. }
  42. ReturnInfo info = new ReturnInfo ();
  43. info.ReturnType = rt;
  44. info.MatchInfos = (MatchInfo[]) matchInfos.ToArray (typeof(MatchInfo));
  45. return info;
  46. }
  47. public override void Initialize (object o)
  48. {
  49. info = (ReturnInfo) o;
  50. }
  51. public override object Read (WebResponse response, Stream responseStream)
  52. {
  53. StreamReader sr = new StreamReader (responseStream);
  54. string text = sr.ReadToEnd ();
  55. object ob = Activator.CreateInstance (info.ReturnType);
  56. foreach (MatchInfo mi in info.MatchInfos)
  57. {
  58. MatchCollection matches = mi.Regex.Matches (text);
  59. object res = null;
  60. if (mi.Field.FieldType.IsArray)
  61. {
  62. int max = mi.Match.MaxRepeats;
  63. if (max == -1) max = matches.Count;
  64. Type elemType = mi.Field.FieldType.GetElementType();
  65. Array array = Array.CreateInstance (elemType, max);
  66. for (int n=0; n<max; n++)
  67. array.SetValue (mi.GetMatchValue (matches[n], elemType), n);
  68. res = array;
  69. }
  70. else if (matches.Count > 0)
  71. res = mi.GetMatchValue (matches[0], mi.Field.FieldType);
  72. mi.Field.SetValue (ob, res);
  73. }
  74. return ob;
  75. }
  76. #endregion // Methods
  77. }
  78. class ReturnInfo
  79. {
  80. public Type ReturnType;
  81. public MatchInfo[] MatchInfos;
  82. }
  83. class MatchInfo
  84. {
  85. public FieldInfo Field;
  86. public MatchAttribute Match;
  87. public Regex Regex;
  88. const string GroupError = "{0} is not a valid group index for match '{1}'. The highest valid group index for this match is {2}";
  89. const string CaptureError = "{0} is not a valid capture index for match '{1}'. The highest valid capture index for this match is {2}";
  90. public object GetMatchValue (Match match, Type castType)
  91. {
  92. if (Match.Group >= match.Groups.Count)
  93. throw new Exception (string.Format (GroupError, Match.Group, Field.Name, match.Groups.Count-1));
  94. Group group = match.Groups [Match.Group];
  95. if (Match.Capture >= group.Captures.Count)
  96. throw new Exception (string.Format (CaptureError, Match.Capture, Field.Name, group.Captures.Count-1));
  97. string val = group.Captures [Match.Capture].Value;
  98. return Convert.ChangeType (val, castType);
  99. }
  100. }
  101. }