StringInstance.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System.Collections.Generic;
  2. using Jint.Native.Object;
  3. using Jint.Runtime;
  4. using Jint.Runtime.Descriptors;
  5. namespace Jint.Native.String
  6. {
  7. public class StringInstance : ObjectInstance, IPrimitiveInstance
  8. {
  9. internal PropertyDescriptor _length;
  10. public StringInstance(Engine engine)
  11. : base(engine, objectClass: "String")
  12. {
  13. }
  14. Types IPrimitiveInstance.Type => Types.String;
  15. JsValue IPrimitiveInstance.PrimitiveValue => PrimitiveValue;
  16. public JsString PrimitiveValue { get; set; }
  17. private static bool IsInt32(double d)
  18. {
  19. return d >= int.MinValue && d <= int.MaxValue && ((int) d) == d;
  20. }
  21. public override PropertyDescriptor GetOwnProperty(in Key propertyName)
  22. {
  23. if (propertyName == KnownKeys.Infinity)
  24. {
  25. return PropertyDescriptor.Undefined;
  26. }
  27. if (propertyName == KnownKeys.Length)
  28. {
  29. return _length ?? PropertyDescriptor.Undefined;
  30. }
  31. var desc = base.GetOwnProperty(propertyName);
  32. if (desc != PropertyDescriptor.Undefined)
  33. {
  34. return desc;
  35. }
  36. if (!TypeConverter.CanBeIndex(propertyName))
  37. {
  38. return PropertyDescriptor.Undefined;
  39. }
  40. var number = TypeConverter.ToNumber(propertyName.Name);
  41. if (!IsInt32(number))
  42. {
  43. return PropertyDescriptor.Undefined;
  44. }
  45. var index = (int) number;
  46. var str = PrimitiveValue.AsStringWithoutTypeCheck();
  47. if (index < 0 || str.Length <= index)
  48. {
  49. return PropertyDescriptor.Undefined;
  50. }
  51. return new PropertyDescriptor(str[index], PropertyFlag.OnlyEnumerable);
  52. }
  53. public override IEnumerable<KeyValuePair<Key, PropertyDescriptor>> GetOwnProperties()
  54. {
  55. if (_length != null)
  56. {
  57. yield return new KeyValuePair<Key, PropertyDescriptor>(KnownKeys.Length, _length);
  58. }
  59. foreach (var entry in base.GetOwnProperties())
  60. {
  61. yield return entry;
  62. }
  63. }
  64. protected internal override void SetOwnProperty(in Key propertyName, PropertyDescriptor desc)
  65. {
  66. if (propertyName == KnownKeys.Length)
  67. {
  68. _length = desc;
  69. }
  70. else
  71. {
  72. base.SetOwnProperty(propertyName, desc);
  73. }
  74. }
  75. public override bool HasOwnProperty(in Key propertyName)
  76. {
  77. if (propertyName == KnownKeys.Length)
  78. {
  79. return _length != null;
  80. }
  81. return base.HasOwnProperty(propertyName);
  82. }
  83. public override void RemoveOwnProperty(in Key propertyName)
  84. {
  85. if (propertyName == KnownKeys.Length)
  86. {
  87. _length = null;
  88. }
  89. base.RemoveOwnProperty(propertyName);
  90. }
  91. }
  92. }