using System; using System.IO; using System.Text.Json; using ReFuel.Gltf.IO; namespace ReFuel.Gltf { public class GltfBuffer : GltfIdObject { public override GltfObjectKind Kind => GltfObjectKind.Buffer; public Uri? Uri { get; set; } public long ByteLength { get; set; } public string? Name { get; set; } public GltfBuffer(GltfDocument document) : base(document) { } public Stream Open(string? pwd = null, IGltfStreamProvider? provider = null) { if (Uri == null) { return ((StreamWrapper)Document.BinaryStreams[Id]).Fork(keepOpen: true); } switch (Uri.IsAbsoluteUri ? Uri.Scheme : "file") // Assume relative URIs are files. { case "file": if (provider != null) { return provider.OpenFile(pwd, Uri) ?? throw new FileNotFoundException(Uri.ToString()); } else { string path = Path.Combine(pwd ?? string.Empty, Uri.LocalPath); return File.OpenRead(path); } case "data": return DataUriStream.FromUri(Uri.OriginalString); default: if (provider != null) return provider.OpenFile(pwd, Uri) ?? throw new FileNotFoundException(Uri.ToString()); break; } throw new Exception("Unrecognized URI scheme."); } internal override void Deserialize(JsonElement element) { if (element.ValueKind != JsonValueKind.Object) throw new Exception("Expected an object."); if (element.TryGetProperty("byteLength", out JsonElement lengthElement)) { if (!lengthElement.TryGetInt64(out long length)) throw new Exception("Length is not an integer."); ByteLength = length; } else { throw new Exception("Byte length is required."); } if (element.TryGetProperty("name", out JsonElement nameElement)) { Name = nameElement.GetString(); } if (element.TryGetProperty("uri", out JsonElement uriElement)) { if (!Uri.TryCreate(uriElement.GetString(), UriKind.RelativeOrAbsolute, out Uri? uri)) throw new Exception("Malformed URI."); Uri = uri; } DeserializeCommon(element); } internal override void Serialize(Utf8JsonWriter writer) { throw new NotImplementedException(); } } }