void HttpHeaderContentType::Process(const Brx& aValue) { Parser parser(aValue); try { Brn type = parser.Next(';'); Parser parser2(type); // get first word of the type iType.Replace(parser2.Next()); SetReceived(); } catch (BufferOverflow&) { return; } Brn key; Brn value; for (;;) { key.Set(parser.Next('=')); if (key.Bytes() == 0) { return; } value.Set(parser.Next()); Process(key, value); } }
Brn XmlParserBasic::Element(const Brx& aTag, const Brx& aDocument, Brn& aRemaining) { EParserState state = eSearchOpen; TInt ignoreClose = 0; Brn namesp; Brn name; Brn attributes; Brn ns; TUint index; TUint startIndex = 0; Brn docTrimmed(Ascii::Trim(aDocument)); Brn doc(docTrimmed); Brn remaining(docTrimmed); Brn retStart; ETagType tagType; for (;;) { NextTag(doc, name, attributes, ns, index, remaining, tagType); if (Ascii::CaseInsensitiveEquals(name, aTag)) { if (state == eSearchOpen) { if (tagType == eTagClose) { if (--ignoreClose < 0) THROW(XmlError); } else if (tagType == eTagOpenClose) { return Brn(Brx::Empty()); } namesp.Set(ns); retStart.Set(remaining); state = eSearchClose; } else { // eSearchClose if (tagType == eTagOpen) { ++ignoreClose; } else if (tagType == eTagClose) { if (ignoreClose == 0) { if (namesp != ns) { THROW(XmlError); } aRemaining.Set(remaining); const TUint retBytes = (TUint)(aRemaining.Ptr() - docTrimmed.Ptr()) - startIndex; Brn ret(docTrimmed.Split(startIndex, retBytes)); return ret; } ignoreClose--; } } } if (remaining.Bytes() == 0) { THROW(XmlError); } if (state != eSearchClose) { startIndex += (TUint)(remaining.Ptr()-doc.Ptr()); } doc.Set(remaining); } }
void DviProtocolUpnp::WriteResource(const Brx& aUriTail, TIpAddress aAdapter, std::vector<char*>& aLanguageList, IResourceWriter& aResourceWriter) { if (aUriTail == kDeviceXmlName) { Brh xml; Brn xmlBuf; AutoMutex _(iLock); const TInt index = FindListenerForInterface(aAdapter); if (index == -1) { return; } if (iDevice.IsRoot()) { const Brx& cachedXml = iAdapters[index]->DeviceXml(); if (cachedXml.Bytes() > 0) { xmlBuf.Set(cachedXml); } } if (xmlBuf.Bytes() == 0) { GetDeviceXml(xml, aAdapter); if (iDevice.IsRoot()) { iAdapters[index]->SetDeviceXml(xml); xmlBuf.Set(iAdapters[index]->DeviceXml()); } else { xmlBuf.Set(xml); } } aResourceWriter.WriteResourceBegin(xmlBuf.Bytes(), kOhNetMimeTypeXml); aResourceWriter.WriteResource(xmlBuf.Ptr(), xmlBuf.Bytes()); aResourceWriter.WriteResourceEnd(); } else { Parser parser(aUriTail); Brn buf = parser.Next('/'); Brn rem = parser.Remaining(); if (buf == DviDevice::kResourceDir) { IResourceManager* resMgr = iDevice.ResourceManager(); if (resMgr != NULL) { resMgr->WriteResource(rem, aAdapter, aLanguageList, aResourceWriter); } } else if (rem == kServiceXmlName) { iLock.Wait(); DviService* service = 0; const TUint count = iDevice.ServiceCount(); for (TUint i=0; i<count; i++) { DviService& s = iDevice.Service(i); if (s.ServiceType().PathUpnp() == buf) { service = &s; break; } } iLock.Signal(); if (service == 0) { THROW(ReaderError); } DviProtocolUpnpServiceXmlWriter::Write(*service, *this, aResourceWriter); } } }
void DeviceBasic::WriteResource(const Brx& aUriTail, TIpAddress /*aInterface*/, std::vector<char*>& /*aLanguageList*/, IResourceWriter& aResourceWriter) { const Brn kIndexFile("index.html"); Bwh filePath(iConfigDir); Brn file; if (aUriTail.Bytes() == 0) { file.Set(kIndexFile); } else { file.Set(aUriTail); } const TByte sep = #ifdef _WIN32 '\\'; #else '/'; #endif filePath.Grow(filePath.Bytes() + 1 + file.Bytes()+1); filePath.Append(sep); filePath.Append(file); filePath.PtrZ(); const char* path = (const char*)filePath.Ptr(); FILE* fd = fopen(path, "rb"); if (fd == NULL) { return; } static const TUint kMaxReadSize = 4096; struct stat fileStats; (void)stat(path, &fileStats); TUint bytes = (TUint)fileStats.st_size; const char* mime = NULL; for (TUint i=filePath.Bytes()-1; i>0; i--) { if (filePath[i] == '/' || filePath[i] == '\\') { break; } if (filePath[i] == '.') { const char* ext = (const char*)filePath.Split(i+1, filePath.Bytes()-i-1).Ptr(); if (strcmp(ext, "html") == 0 || strcmp(ext, "htm") == 0) { mime = kOhNetMimeTypeHtml; } break; } } aResourceWriter.WriteResourceBegin(bytes, mime); do { TByte buf[kMaxReadSize]; TUint size = (bytes<kMaxReadSize? bytes : kMaxReadSize); size_t records_read = fread(buf, size, 1, fd); ASSERT(records_read == 1); aResourceWriter.WriteResource(buf, size); bytes -= size; } while (bytes > 0); aResourceWriter.WriteResourceEnd(); (void)fclose(fd); }
Brn ReaderText::ReadLine() { Brn line; try { line.Set(Ascii::Trim(ReadUntil(Ascii::kLf))); } catch (ReaderError&) { // treat any content following the last newline as a final line line.Set(Read(iMaxBytes)); if (line.Bytes() == 0) { throw; } } return line; }
void HeaderAcceptLanguage::Process(const Brx& aValue) { SetReceived(); ClearLanguageList(); iLanguages.Set(aValue); std::vector<PrioritisedLanguage> prioritisedList; Parser parser(iLanguages); while (parser.Remaining().Bytes() > 0) { Brn langBuf = parser.Next(','); Parser parser2(langBuf); Brn lang = parser2.Next(';'); parser2.Set(parser2.Remaining()); Brn qualityBuf = parser2.Next('='); if (qualityBuf.Bytes() > 0) { qualityBuf.Set(parser2.Remaining()); } TUint quality = ParseQualityValue(qualityBuf); PrioritisedLanguage prioritisedLang; prioritisedLang.iLanguage = (char*)malloc(lang.Bytes()+1); (void)memcpy(prioritisedLang.iLanguage, lang.Ptr(), lang.Bytes()); prioritisedLang.iLanguage[lang.Bytes()] = '\0'; prioritisedLang.iPriority = quality; AddPrioritisedLanguage(prioritisedList, prioritisedLang); } for (TUint i=0; i<(TUint)prioritisedList.size(); i++) { iLanguageList.push_back(prioritisedList[i].iLanguage); } }
TBool Ssdp::ParseUrn(const Brx& aUrn, const Brx& aType, Brn& aDomainName, Brn& aDeviceType, TUint& aVer) { Parser parser(aUrn); aDomainName.Set(parser.NextNoTrim(kUrnSeparator)); if (!aType.Equals(parser.NextNoTrim(kUrnSeparator))) { return false; } aDeviceType.Set(parser.NextNoTrim(kUrnSeparator)); Brn ver = parser.Remaining(); try { aVer = Ascii::Uint(ver); } catch(AsciiError&) { return false; } return true; }
TBool DviServerUpnp::RedirectUri(const Brx& aUri, Brn& aRedirectTo) { if (aUri == iRedirectUriRequested) { aRedirectTo.Set(iRedirectUriRedirectedTo); return true; } return false; }
Brn ReaderText::ReadLine(TUint& aBytesConsumed) { Brn line; try { Brn buf = ReadUntil(Ascii::kLf); aBytesConsumed = buf.Bytes() + 1; // +1 for Ascii::kLf line.Set(Ascii::Trim(buf)); } catch (ReaderError&) { // treat any content following the last newline as a final line Brn buf = Read(iMaxBytes); aBytesConsumed = buf.Bytes() + 1; // +1 for Ascii::kLf line.Set(Ascii::Trim(buf)); if (line.Bytes() == 0) { throw; } } return line; }
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType) { Brn root = XmlParserBasic::Find("root", iXml); Brn device = XmlParserBasic::Find("device", root); Brn udn = XmlParserBasic::Find("UDN", device); if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) { Brn deviceList = XmlParserBasic::Find("deviceList", device); do { Brn remaining; device.Set(XmlParserBasic::Find("device", deviceList, remaining)); udn.Set(XmlParserBasic::Find("UDN", device)); deviceList.Set(remaining); } while (!CpiDeviceUpnp::UdnMatches(udn, Udn())); } Brn serviceList = XmlParserBasic::Find("serviceList", device); Brn service; Brn serviceType; Brn devServiceTypeNoVer; const Brx& targServiceType = aServiceType.FullName(); // Must have backwards compatibility. Need to compare service type and version separately. Parser serviceParser = targServiceType; serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name Brn targServiceTypeNoVer(targServiceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) do { Brn remaining; service.Set(XmlParserBasic::Find("service", serviceList, remaining)); serviceType.Set(XmlParserBasic::Find("serviceType", service)); serviceList.Set(remaining); // Parse service type and version separately. serviceParser.Set(serviceType); serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name devServiceTypeNoVer.Set(serviceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) // MUST allow use of device with version >= target version } while (devServiceTypeNoVer != targServiceTypeNoVer); Brn path = XmlParserBasic::Find(aType, service); if (path.Bytes() == 0) { // no event url => service doesn't have any evented state variables THROW(XmlError); } // now create a uri using the scheme/host/port of the device xml location // plus the path we've just constructed Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx aUri.Replace(iLocation); base.Append(aUri.Scheme()); base.Append("://"); base.Append(aUri.Host()); base.Append(':'); Ascii::AppendDec(base, aUri.Port()); aUri.Replace(base, path); }
TUint CpiDeviceUpnp::Version(const TChar* aDomain, const TChar* aName, TUint /*aProxyVersion*/) const { ServiceType serviceType(iDevice->GetCpStack().Env(), aDomain, aName, 0); const Brx& targServiceType = serviceType.FullName(); // Must have backwards compatibility. Need to compare service type and version separately. Parser serviceParser = targServiceType; serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name Brn targServiceTypeNoVer(targServiceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) try { Brn root = XmlParserBasic::Find("root", iXml); Brn device = XmlParserBasic::Find("device", root); Brn udn = XmlParserBasic::Find("UDN", device); if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) { Brn deviceList = XmlParserBasic::Find("deviceList", device); do { Brn remaining; device.Set(XmlParserBasic::Find("device", deviceList, remaining)); udn.Set(XmlParserBasic::Find("UDN", device)); deviceList.Set(remaining); } while (!CpiDeviceUpnp::UdnMatches(udn, Udn())); } Brn serviceList = XmlParserBasic::Find("serviceList", device); Brn service; Brn serviceType; Brn devServiceTypeNoVer; for (;;) { Brn remaining; service.Set(XmlParserBasic::Find("service", serviceList, remaining)); serviceType.Set(XmlParserBasic::Find("serviceType", service)); serviceList.Set(remaining); // Parse service type and version separately. serviceParser.Set(serviceType); serviceParser.Next(':'); // urn serviceParser.Next(':'); // schema url serviceParser.Next(':'); // service serviceParser.Next(':'); // name devServiceTypeNoVer.Set(serviceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version) if (devServiceTypeNoVer == targServiceTypeNoVer) { Brn devVersionBuf = serviceParser.NextToEnd(); // version try { return Ascii::Uint(devVersionBuf); } catch (AsciiError&) { THROW(XmlError); } } } } catch (XmlError&) { return 0; } }
void WsProtocol76::Read(Brn& aData, TBool& aClosed) { aData.Set(NULL, 0); aClosed = false; Brn data = iReadBuffer.ReadUntil(kMsgEnd); if (data.Bytes() == 1 && data[0] == kFrameCloseStart) { Brn msg = iReadBuffer.Read(1); if (msg[0] != kMsgCloseEnd) { THROW(WebSocketError); } LOG(kDvWebSocket, "WS: Received close cmd from browser\n"); Close(); aClosed = true; return; } if (data[0] != kFrameMsgStart) { LOG2(kDvWebSocket, kError, "WS: Unexpected leading byte - %u\n", data[0]); THROW(WebSocketError); } aData.Set(data.Split(1, data.Bytes()-1)); }
TBool CpiDeviceUpnp::GetAttribute(const char* aKey, Brh& aValue) const { Brn key(aKey); Parser parser(key); if (parser.Next('.') == Brn("Upnp")) { Brn property = parser.Remaining(); if (property == Brn("Location")) { aValue.Set(iLocation); return (true); } if (property == Brn("DeviceXml")) { aValue.Set(iXml); return (true); } const DeviceXml* device = iDeviceXml; if (parser.Next('.') == Brn("Root")) { device = &iDeviceXmlDocument->Root(); property.Set(parser.Remaining()); } try { if (property == Brn("FriendlyName")) { device->GetFriendlyName(aValue); return (true); } if (property == Brn("PresentationUrl")) { device->GetPresentationUrl(aValue); return (true); } Parser parser(property); Brn token = parser.Next('.'); if (token == Brn("Service")) { aValue.Set(device->ServiceVersion(parser.Remaining())); return (true); } } catch (XmlError&) { } } return (false); }
void ReaderHttpRequest::Read(TUint aTimeoutMs) { TUint count = 0; iMethod = 0; ResetHeaders(); for (;;) { Brn line; { Timer timer(MakeFunctor(*this, &ReaderHttpRequest::ReadTimeout)); if (aTimeoutMs > 0) { timer.FireIn(aTimeoutMs); } line.Set(Ascii::Trim(iReader.ReadUntil(Ascii::kLf))); timer.Cancel(); } // LOG(kHttp, "HTTP Read Request "); // LOG(kHttp, line); // LOG(kHttp, "\n"); TUint bytes = line.Bytes(); if (!bytes) { if (count == 0) { continue; // a blank line before first header - ignore (RFC 2616 section 4.1) } if (iMethod == 0) { THROW(HttpError); } return; } if (Ascii::IsWhitespace(line[0])) { continue; // a line starting with spaces is a continuation line } Parser parser(line); if (count == 0) { // method Brn method = parser.Next(); Brn uri = parser.Next(); Brn version = Ascii::Trim(parser.Remaining()); ProcessMethod(method, uri, version); } else { // header Brn field = parser.Next(':'); Brn value = Ascii::Trim(parser.Remaining()); ProcessHeader(field, value); } count++; } }
void EventSessionUpnp::ProcessNotification(IEventProcessor& aEventProcessor, const Brx& aEntity) { aEventProcessor.EventUpdateStart(); OutputProcessorUpnp outputProcessor; Brn propertySet = XmlParserBasic::Find("propertyset", aEntity); Brn prop; Brn remaining; try { for (;;) { prop.Set(XmlParserBasic::Find("property", propertySet, remaining)); prop.Set(Ascii::Trim(prop)); if (prop.Bytes() < 8 || prop[0] != '<' || prop[1] == '/') { THROW(XmlError); } Parser parser(prop); (void)parser.Next('<'); Brn tagName = parser.Next('>'); Brn val = parser.Next('<'); Brn closingTag = parser.Next('/'); closingTag.Set(parser.Next('>')); if (tagName != closingTag) { THROW(XmlError); } try { aEventProcessor.EventUpdate(tagName, val, outputProcessor); } catch(AsciiError&) { THROW(XmlError); } propertySet.Set(remaining); } } catch(XmlError&) {} aEventProcessor.EventUpdateEnd(); }
void ReaderHttpResponse::Read(TUint aTimeoutMs) { iReader.ReadFlush(); ResetHeaders(); TUint count = 0; for (;;) { Brn line; { Timer timer(MakeFunctor(*this, &ReaderHttpResponse::ReadTimeout)); if (aTimeoutMs > 0) { timer.FireIn(aTimeoutMs); } line.Set(Ascii::Trim(iReader.ReadUntil(Ascii::kLf))); timer.Cancel(); } LOG(kHttp, "HTTP Read Response "); LOG(kHttp, line); LOG(kHttp, "\n"); TUint bytes = line.Bytes(); if (!bytes) { if (count == 0) { continue; // a blank line before first header - ignore (RFC 2616 section 4.1) } return; } if (Ascii::IsWhitespace(line[0])) { continue; // a line starting with spaces is a continuation line } Parser parser(line); if (count == 0) { // status // LOG(kHttp, " status "); Brn version = parser.Next(' '); Brn code = parser.Next(' '); Brn description = Ascii::Trim(parser.Remaining()); ProcessStatus(version, code, description); } else { // header // LOG(kHttp, " header "); Brn field = parser.Next(':'); Brn value = Ascii::Trim(parser.Remaining()); ProcessHeader(field, value); } count++; } }
void ShellSession::Run() { FunctorMsg logger = MakeFunctorMsg(*this, &OpenHome::Net::ShellSession::Log); FunctorMsg oldLogger = Log::SwapOutput(logger); iShutdownSem.Wait(); for (;;) { try { Brn buf = iReadBuffer->ReadUntil('\n'); TUint bytes = buf.Bytes(); if (bytes > 0 && buf[bytes - 1] == '\r') { // strip any trailing LF buf.Set(buf.Ptr(), bytes-1); } Parser parser(buf); Brn command = parser.Next(' '); if (command == kCmdExit) { break; } std::vector<Brn> args; for (;;) { Brn arg = parser.Next(' '); if (arg.Bytes() == 0) { break; } args.push_back(arg); } iCommandHandler.HandleShellCommand(command, args, *iWriterResponse); } catch (ReaderError&) { break; } catch (WriterError&) { break; } catch (Exception& e) { Log::Print("Unexpected exception: %s from %s:%u\n", e.Message(), e.File(), e.Line()); break; } } (void)Log::SwapOutput(oldLogger); iShutdownSem.Signal(); }
void WsProtocol80::Read(Brn& aData, TBool& aClosed) { aData.Set(NULL, 0); aClosed = false; static const TByte kBitMaskFinalFragment = 1<<7; static const TByte kBitMaskRsv123 = 0x70; static const TByte kBitMaskOpcode = 0xf; static const TByte kBitMaskPayloadMask = 1<<7; static const TByte kBitMaskPayloadLen = 0x7f; // validate framing Bws<2> ctrl; ctrl.Append(iReadBuffer.Read(2)); const TByte& byte0 = ctrl.At(0); const TByte& byte1 = ctrl.At(1); const TBool fragment = ((byte0 & kBitMaskFinalFragment) == 0); if (byte0 & kBitMaskRsv123) { LOG2(kDvWebSocket, kError, "WS: RSV bit(s) set - %u - but no extension negotiated\n", (byte0 & kBitMaskRsv123) >> 4); Close(kCloseProtocolError); aClosed = true; return; }
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType) { Brn root = XmlParserBasic::Find("root", iXml); Brn device = XmlParserBasic::Find("device", root); Brn udn = XmlParserBasic::Find("UDN", device); if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) { Brn deviceList = XmlParserBasic::Find("deviceList", device); do { Brn remaining; device.Set(XmlParserBasic::Find("device", deviceList, remaining)); udn.Set(XmlParserBasic::Find("UDN", device)); deviceList.Set(remaining); } while (!CpiDeviceUpnp::UdnMatches(udn, Udn())); } Brn serviceList = XmlParserBasic::Find("serviceList", device); Brn service; Brn serviceType; const Brx& targServiceType = aServiceType.FullName(); do { Brn remaining; service.Set(XmlParserBasic::Find("service", serviceList, remaining)); serviceType.Set(XmlParserBasic::Find("serviceType", service)); serviceList.Set(remaining); } while (serviceType != targServiceType); Brn path = XmlParserBasic::Find(aType, service); if (path.Bytes() == 0) { // no event url => service doesn't have any evented state variables THROW(XmlError); } // now create a uri using the scheme/host/port of the device xml location // plus the path we've just constructed Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx aUri.Replace(iLocation); base.Append(aUri.Scheme()); base.Append("://"); base.Append(aUri.Host()); base.Append(':'); Ascii::AppendDec(base, aUri.Port()); aUri.Replace(base, path); }
void EventSessionUpnp::ProcessNotification(IEventProcessor& aEventProcessor, const Brx& aEntity) { aEventProcessor.EventUpdateStart(); OutputProcessorUpnp outputProcessor; Brn propertySet = XmlParserBasic::Find("propertyset", aEntity); Brn prop; Brn remaining; try { for (;;) { try { prop.Set(XmlParserBasic::Find("property", propertySet, remaining)); } catch (XmlError&) { // we've successfully processed all <property> tags from aEntity break; } prop.Set(Ascii::Trim(prop)); if (prop.Bytes() < 8 || prop[0] != '<' || prop[1] == '/') { THROW(XmlError); } Parser parser(prop); (void)parser.Next('<'); Brn tagNameFull = parser.Next('>'); Brn tagName = tagNameFull; TUint bytes = tagNameFull.Bytes(); TUint i; for (i = 0; i < bytes; i++) { if (Ascii::IsWhitespace(tagNameFull[i])) { break; } } if (i < bytes) { tagName.Set(tagNameFull.Split(0, i)); } Brn val; if (bytes > 0 && tagNameFull[bytes-1] == '/') { // empty element tag val.Set(Brx::Empty()); if (i == bytes) { // no white space before '/' tagName.Set(tagName.Split(0, bytes-1)); } } else { val.Set(parser.Next('<')); Brn closingTag = parser.Next('/'); closingTag.Set(parser.Next('>')); if (tagName != closingTag) { THROW(XmlError); } } try { aEventProcessor.EventUpdate(tagName, val, outputProcessor); } catch(AsciiError&) { THROW(XmlError); } propertySet.Set(remaining); } aEventProcessor.EventUpdateEnd(); } catch(XmlError&) { aEventProcessor.EventUpdateError(); } }
void XmlParserBasic::NextTag(const Brx& aDocument, Brn& aName, Brn& aAttributes, Brn& aNamespace, TUint& aIndex, Brn& aRemaining, ETagType& aType) { aName.Set(Brx::Empty()); aAttributes.Set(Brx::Empty()); aNamespace.Set(Brx::Empty()); aRemaining.Set(Brx::Empty()); Parser parser(aDocument); for (;;) { Brn item = parser.Next('>'); TUint bytes = item.Bytes(); if (bytes > 0 && item[0] != '<') { Parser valueParser(item); Brn value = valueParser.Next('<'); bytes -= value.Bytes(); item.Set(item.Split(value.Bytes(), bytes)); item.Set(Ascii::Trim(item)); bytes = item.Bytes(); } if (bytes < 2 || item[0] != '<') { THROW(XmlError); } aIndex = (TUint)(item.Ptr() - aDocument.Ptr()); if (item[1] == '?') { if (bytes < 3) { // catch special case of <?> THROW(XmlError); } if (item[bytes - 1] == '?') { // processing instruction continue; } THROW(XmlError); } aRemaining.Set(parser.Remaining()); TUint start = 1; // skip opening '<' TUint len = bytes-1; if (item[1] == '/') { aType = eTagClose; start++; len--; } else if (item[bytes-1] == '/') { aType = eTagOpenClose; len--; } else { aType = eTagOpen; } parser.Set(item.Split(start, len)); aName.Set(parser.NextWhiteSpace()); aAttributes.Set(parser.Remaining()); if (Ascii::Contains(aName, ':')) { // collect the namespace parser.Set(aName); aNamespace.Set(parser.Next(':')); if (!aNamespace.Bytes()) { THROW(XmlError); } aName.Set(parser.Remaining()); } else { aNamespace.Set(Brx::Empty()); } if (!aName.Bytes()) { THROW(XmlError); } return; } }
void ProviderPlaylist::ReadList(Net::IDvInvocation& aResponse, const Brx& aIdList, Net::IDvInvocationResponseString& aTrackList) { Log::Print("ProviderPlaylist::ReadList\n"); uint32_t tracksMax; GetPropertyTracksMax(tracksMax); vector<uint32_t> v; v.reserve(tracksMax); try { Parser parser(aIdList); Brn id; id.Set(parser.Next(' ')); for( ; id != Brx::Empty(); id.Set(parser.Next(' ')) ) { v.push_back(Ascii::Uint(id)); if(v.size() > tracksMax) { THROW(AsciiError); } } } catch(AsciiError) { aResponse.Error(kInvalidRequest, kInvalidRequestMsg); } Brn entryStart("<Entry>"); Brn entryEnd("</Entry>"); Brn idStart("<Id>"); Brn idEnd("</Id>"); Brn uriStart("<Uri>"); Brn uriEnd("</Uri>"); Brn metaStart("<Metadata>"); Brn metaEnd("</Metadata>"); aResponse.StartResponse(); aTrackList.Write(Brn("<TrackList>")); for( vector<uint32_t>::const_iterator id=v.begin(); id!= v.end(); id++) { const Track* track = 0; iMutex.Wait(); list<Track*>::const_iterator i = find_if(iList.begin(), iList.end(), bind2nd(mem_fun(&Track::IsId),*id)); if(i != iList.end()) { track = *i; track->IncRef(); } iMutex.Signal(); if(track) { aTrackList.Write(entryStart); aTrackList.Write(idStart); Ascii::StreamWriteUint(aTrackList, *id); aTrackList.Write(idEnd); aTrackList.Write(uriStart); Converter::ToXmlEscaped(aTrackList, track->Uri()); aTrackList.Write(uriEnd); aTrackList.Write(metaStart); Converter::ToXmlEscaped(aTrackList, track->Metadata()); aTrackList.Write(metaEnd); aTrackList.Write(entryEnd); track->DecRef(); } } aTrackList.Write(Brn("</TrackList>")); aTrackList.WriteFlush(); aResponse.EndResponse(); }
void CpiDeviceLpec::LpecThread() { try { iSocket.Open(iCpStack.Env()); iSocket.Connect(iLocation, iCpStack.Env().InitParams()->TcpConnectTimeoutMs()); TBool starting = true; for (;;) { Brn line = iReadBuffer->ReadUntil(Ascii::kLf); if (line.Bytes() > 0 && line[line.Bytes()-1] == Ascii::kCr) { line.Set(line.Ptr(), line.Bytes()-1); } Parser parser(line); Brn method = parser.Next(' '); if (starting) { if (method != Lpec::kMethodAlive) { LOG2(kLpec, kError, "LPEC: unable to find device "); LOG2(kLpec, kError, iLpecName); LOG2(kLpec, kError, ", exiting thread\n"); if (iStateChanged) { iStateChanged(); } THROW(ReaderError); } Brn name = parser.Next(' '); if (name == iLpecName) { starting = false; Brn udn = parser.Remaining(); iDevice = new CpiDevice(iCpStack, udn, *this, *this, NULL); iConnected = true; if (iStateChanged) { iStateChanged(); } } } if (method == Lpec::kMethodAlive) { LOG(kLpec, "LPEC: Alive - "); LOG(kLpec, parser.Remaining()); LOG(kLpec, "\n"); } else if (method == Lpec::kMethodByeBye) { Brn name = parser.Next(' '); if (name == iLpecName) { iConnected = false; { if (iStateChanged) { iStateChanged(); } } iExiting = true; THROW(ReaderError); } } else if (method == Lpec::kMethodEvent) { HandleEventedUpdate(parser.Remaining()); } else if (iResponseHandler == NULL || !iResponseHandler->HandleLpecResponse(method, parser.Remaining())) { LOG2(kLpec, kError, "Unexpected LPEC message: "); LOG2(kLpec, kError, line); LOG2(kLpec, kError, "\n"); } } } catch (NetworkError&) { LogError("NetworkError"); } catch (NetworkTimeout&) { LogError("NetworkTimeout"); } catch (WriterError&) { LogError("WriterError"); } catch (ReaderError&) { if (!iExiting) { LogError("ReaderError"); } } }