FF8String.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. using System;
  2. using System.Collections;
  3. using System.Linq;
  4. namespace OpenVIII
  5. {
  6. /// <summary>
  7. /// This holds the encoded bytes and provides implict casts to string and byte[]
  8. /// </summary>
  9. public class FF8String : IEnumerator, IEnumerable
  10. {
  11. #region Fields
  12. protected byte[] value;
  13. private static Encoding.FF8TextEncoding encoding = new Encoding.FF8TextEncoding(Encoding.FF8TextEncodingCodepage.Create());
  14. private int position = 0;
  15. #endregion Fields
  16. #region Constructors
  17. public FF8String()
  18. {
  19. }
  20. public FF8String(byte[] @value) => this.value = @value;
  21. public FF8String(string @value) => this.value = @value != null ? encoding.GetBytes(@value) : null;
  22. #endregion Constructors
  23. #region Properties
  24. public object Current => Value[position - 1];
  25. public virtual byte[] Value { get => value; set => this.value = value; }
  26. /// <summary>
  27. /// This is incorrect as null can be in the beginning of strings as a marker or tag.
  28. /// But I can't figure out how to make his code leave null as null.
  29. /// </summary>
  30. public string Value_str => encoding.GetString(Value??new byte[]{ }).TrimEnd('\0').Replace("{End}","");
  31. public virtual int Length => value == null ? 0 : value.Length;
  32. #endregion Properties
  33. #region Indexers
  34. public byte this[int index] => value[index];
  35. #endregion Indexers
  36. #region Methods
  37. public static FF8String Combine(FF8String start, FF8String end)
  38. {
  39. if (end != null && end.Length > 0)
  40. {
  41. byte[] combine = new byte[start.Length + end.Length];
  42. Array.Copy(start, 0, combine, 0, start.Length);
  43. Array.Copy(end, 0, combine, start.Length, end.Length);
  44. return combine;
  45. }
  46. else
  47. return start;
  48. }
  49. public static implicit operator byte[] (FF8String input) => input?.Value;
  50. public static implicit operator FF8String(string input) => new FF8String(input);
  51. public static implicit operator FF8String(byte[] input) => new FF8String(input);
  52. public static implicit operator string(FF8String input) => input?.Value_str;
  53. public static FF8String operator +(FF8String a, FF8String b)
  54. {
  55. FF8String s = a.Clone();
  56. return s.Append(b);
  57. }
  58. public static FF8String operator +(FF8String a, string b)
  59. {
  60. FF8String s = a.Clone();
  61. return s.Append(b);
  62. }
  63. public static FF8String operator +(string a, FF8String b)
  64. {
  65. FF8String s = new FF8String(a);
  66. return s.Append(b);
  67. }
  68. public FF8String Append(FF8String end)
  69. {
  70. if (Value != null && Value.Length > 0)
  71. {
  72. if (end != null && end.Length > 0)
  73. {
  74. Array.Resize(ref value, Length + end.Length);
  75. Array.Copy(end.Value, 0, value, Length - end.Length, end.Length);
  76. }
  77. }
  78. else
  79. {
  80. if (end != null && end.Length > 0)
  81. {
  82. Value = end;
  83. }
  84. }
  85. return this;
  86. }
  87. public FF8String Clone()
  88. {
  89. if (Length > 0)
  90. return new FF8String
  91. {
  92. value = (byte[])(value.Clone())
  93. };
  94. else return new FF8String();
  95. }
  96. public FF8String Replace(FF8String a,FF8String b)
  97. {
  98. if (Length > 0)
  99. {
  100. int i = 0;
  101. do
  102. {
  103. i = Array.FindIndex(value, i, Length - i, x => x == a[0]);
  104. if (i >= 0)
  105. {
  106. if (value.Skip(i).Take(a.Length).ToArray().SequenceEqual(a.Value))
  107. {
  108. byte[] end = value.Skip(a.Length + i).ToArray();
  109. Array.Resize(ref value, Length + b.Length - a.Length);
  110. Array.Copy(b, 0, value, i, b.Length);
  111. Array.Copy(end, 0, value, i + b.Length, end.Length);
  112. i += b.Length;
  113. }
  114. else
  115. {
  116. i++;
  117. }
  118. }
  119. else break;
  120. }
  121. while (i < Length);
  122. }
  123. return this;
  124. }
  125. public IEnumerator GetEnumerator()
  126. {
  127. if (Value != null && Value.Length > 0)
  128. return this;
  129. return null;
  130. }
  131. public bool MoveNext()
  132. {
  133. if (++position <= Length)
  134. return true;
  135. else
  136. {
  137. Reset();
  138. return false;
  139. }
  140. }
  141. public void Reset() => position = 0;
  142. public override string ToString() => Value_str;
  143. #endregion Methods
  144. }
  145. }