async Task GetHttpStreamAsync() { do { try { using var streamHandler = await BaseStreamHandler.GetStreamHandler(Url, httpClient); await streamHandler.StartAsync(); { //get the position of metadata int metaInt = streamHandler.GetIceCastMetaInterval(); using MemoryStream metadataData = new MemoryStream(); byte[] buffer = null; int metadataLength = 0; int streamPosition = 0; int bufferPosition = 0; int readBytes = 0; OnStreamStart?.Invoke(this, new StreamStartEventArgs(streamHandler.GetCodec())); while (Running) { if (bufferPosition >= readBytes) { (readBytes, buffer) = await streamHandler.ReadAsync(); bufferPosition = 0; } if (readBytes <= 0) { Radio.Log("Stream over", this); break; } if (metadataLength == 0) { if (metaInt == 0 || streamPosition + readBytes - bufferPosition <= metaInt) { streamPosition += readBytes - bufferPosition; ProcessStreamData(buffer, ref bufferPosition, readBytes - bufferPosition); continue; } ProcessStreamData(buffer, ref bufferPosition, metaInt - streamPosition); metadataLength = Convert.ToInt32(buffer[bufferPosition++]) * 16; //check if there's any metadata, otherwise skip to next block if (metadataLength == 0) { streamPosition = Math.Min(readBytes - bufferPosition, metaInt); ProcessStreamData(buffer, ref bufferPosition, streamPosition); continue; } } //get the metadata and reset the position while (bufferPosition < readBytes) { metadataData.WriteByte(buffer[bufferPosition++]); metadataLength--; if (metadataLength == 0) { var metadataBuffer = metadataData.ToArray(); Metadata = Encoding.UTF8.GetString(metadataBuffer); metadataData.SetLength(0); streamPosition = Math.Min(readBytes - bufferPosition, metaInt); ProcessStreamData(buffer, ref bufferPosition, streamPosition); break; } } } } } catch (IOException ex) { Radio.Log(string.Format("Handled IOException, reconnecting. Details:\n{0}\n{1}", ex.Message, ex.StackTrace), this); OnStreamOver?.Invoke(this, new StreamOverEventArgs()); } catch (SocketException ex) { Radio.Log(string.Format("Handled SocketException, reconnecting. Details:\n{0}\n{1}", ex.Message, ex.StackTrace), this); OnStreamOver?.Invoke(this, new StreamOverEventArgs()); } catch (WebException ex) { Radio.Log(string.Format("Handled WebException, reconnecting. Details:\n{0}\n{1}", ex.Message, ex.StackTrace), this); OnStreamOver?.Invoke(this, new StreamOverEventArgs()); } catch (Exception ex) { Radio.Log(string.Format("Handled Exception, reconnecting. Details:\n{0}\n{1}", ex.Message, ex.StackTrace), this); OnStreamOver?.Invoke(this, new StreamOverEventArgs()); } } while (Running); }
private void StartTag(byte[] buf, int offset, ContentToken ct, TOK tok) { this.m_Depth++; int colon; string name; string prefix; var ht = new Hashtable(); this.m_ns.PushScope(); // if i have attributes if ((tok == TOK.START_TAG_WITH_ATTS) || (tok == TOK.EMPTY_ELEMENT_WITH_ATTS)) { int start; int end; string val; for (var i = 0; i < ct.getAttributeSpecifiedCount(); i++) { start = ct.getAttributeNameStart(i); end = ct.getAttributeNameEnd(i); name = utf.GetString(buf, start, end - start); start = ct.getAttributeValueStart(i); end = ct.getAttributeValueEnd(i); //val = utf.GetString(buf, start, end - start); val = this.NormalizeAttributeValue(buf, start, end - start); // <foo b='&'/> // <foo b='&amp;' // TODO: if val includes &, it gets double-escaped if (name.StartsWith("xmlns:")) { colon = name.IndexOf(':'); prefix = name.Substring(colon + 1); this.m_ns.AddNamespace(prefix, val); } else if (name == "xmlns") { this.m_ns.AddNamespace(string.Empty, val); } else { ht.Add(name, val); } } } name = utf.GetString(buf, offset + this.m_enc.MinBytesPerChar, ct.NameEnd - offset - this.m_enc.MinBytesPerChar); colon = name.IndexOf(':'); var ns = ""; prefix = null; if (colon > 0) { prefix = name.Substring(0, colon); name = name.Substring(colon + 1); ns = this.m_ns.LookupNamespace(prefix); } else { ns = this.m_ns.DefaultNamespace; } var newel = ElementFactory.GetElement(prefix, name, ns); foreach (string attrname in ht.Keys) { newel.SetAttribute(attrname, (string)ht[attrname]); } if (this.m_root == null) { this.m_root = newel; //FireOnDocumentStart(m_root); OnStreamStart?.Invoke(this, this.m_root); } else { if (this.current != null) { this.current.AddChild(newel); } this.current = newel; } }
private void StartTag(byte[] buf, int offset, ContentToken ct, Tokens tok) { depth++; int colon; string name; string prefix; var attributes = new Dictionary <string, string>(); nsStack.Push(); // if i have attributes if ((tok == Tokens.StartTagWithAtts) || (tok == Tokens.EmptyElementWithAtts)) { int start; int end; string val; for (int i = 0; i < ct.GetAttributeSpecifiedCount(); i++) { start = ct.GetAttributeNameStart(i); end = ct.GetAttributeNameEnd(i); name = utf.GetString(buf, start, end - start); start = ct.GetAttributeValueStart(i); end = ct.GetAttributeValueEnd(i); //val = _utf.GetString(buf, start, end - start); val = NormalizeAttributeValue(buf, start, end - start); // <foo b='&'/> // <foo b='&amp;' // TODO: if val includes &, it gets double-escaped if (name.StartsWith("xmlns:")) { // prefixed namespace declaration colon = name.IndexOf(':'); prefix = name.Substring(colon + 1); nsStack.AddNamespace(prefix, val); attributes.Add(name, val); } else if (name == "xmlns") { // namespace declaration nsStack.AddNamespace(string.Empty, val); attributes.Add(name, val); } else { // normal attribute attributes.Add(name, val); } } } name = utf.GetString(buf, offset + utf8Encoding.MinBytesPerChar, ct.NameEnd - offset - utf8Encoding.MinBytesPerChar); colon = name.IndexOf(':'); string ns; prefix = null; if (colon > 0) { prefix = name.Substring(0, colon); name = name.Substring(colon + 1); ns = nsStack.LookupNamespace(prefix); } else { ns = nsStack.DefaultNamespace; } XmppXElement newel = Factory.GetElement(prefix, name, ns); foreach (string attrname in attributes.Keys) { colon = attrname.IndexOf(':'); if (colon > 0) { prefix = attrname.Substring(0, colon); name = attrname.Substring(colon + 1); ns = nsStack.LookupNamespace(prefix); if (attrname.StartsWith("xmlns:")) { // Namespace Declaration newel.SetAttributeValue(XName.Get(name, ns), attributes[attrname]); } else { // prefixed attribute newel.SetAttributeValue("{" + ns + "}" + name, attributes[attrname]); } } else { newel.SetAttributeValue(XName.Get(attrname, string.Empty), attributes[attrname]); } } if (root == null) { root = newel; OnStreamStart?.Invoke(root); } else { current?.Add(newel); current = newel; } }