using System; using System.Collections; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Linq; namespace UniJSON { public interface IUtf8String: IEnumerable { int ByteLength { get; } } /// /// Immutable short utf8 string /// [StructLayout(LayoutKind.Explicit)] public struct Utf8String4 : IEquatable, IUtf8String { [FieldOffset(0)] uint _value; [FieldOffset(0)] byte _byte0; [FieldOffset(1)] byte _byte1; [FieldOffset(2)] byte _byte2; [FieldOffset(3)] byte _byte3; public int ByteLength { get { if (_byte0 == 0) return 0; if (_byte1 == 0) return 1; if (_byte2 == 0) return 2; if (_byte3 == 0) return 3; return 4; } } static Utf8String4 Create(uint value) { return new Utf8String4 { _value = value }; } public static Utf8String4 Create(IEnumerable bytes) { var u = new Utf8String4(); var it = bytes.GetEnumerator(); if (!it.MoveNext()) return u; u._byte0 = it.Current; if (!it.MoveNext()) return u; u._byte1 = it.Current; if (!it.MoveNext()) return u; u._byte2 = it.Current; if (!it.MoveNext()) return u; u._byte3 = it.Current; if (!it.MoveNext()) { throw new ArgumentOutOfRangeException(); } return u; } public static Utf8String4 Create(string src) { return Create(Utf8String.Encoding.GetBytes(src)); } public bool Equals(Utf8String4 other) { return _value == other._value; } public override bool Equals(object obj) { if (obj == null) return false; if (obj is Utf8String4) { return Equals((Utf8String4)obj); } { var s = obj as string; if (s != null) { return ToString() == s; } } return false; } public override int GetHashCode() { return _value.GetHashCode(); } public override string ToString() { return Utf8String.Encoding.GetString(this.ToArray()); } public IEnumerator GetEnumerator() { if (_byte0 == 0) yield break; yield return _byte0; if (_byte1 == 0) yield break; yield return _byte1; if (_byte2 == 0) yield break; yield return _byte2; if (_byte3 == 0) yield break; yield return _byte3; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }