示例#1
0
Brn XmlParserBasic::Find(const Brx& aTag, const Brx& aDocument, Brn& aRemaining)
{
    EParserState state = eSearchOpen;
    TInt ignoreClose = 0;
    Brn namesp;
    Brn name;
    Brn attributes;
    Brn ns;
    TUint index;
    Brn doc(Ascii::Trim(aDocument));
    Brn remaining(Ascii::Trim(aDocument));
    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)(doc.Ptr() - retStart.Ptr()) + index;
                        Brn ret(retStart.Ptr(), retBytes);
                        return ret;
                    }
                    ignoreClose--;
                }
            }
        }
        if (remaining.Bytes() == 0) {
            THROW(XmlError);
        }
        doc.Set(remaining);
    }
}
示例#2
0
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);
    }
}
示例#3
0
文件: Stream.cpp 项目: SiMet/ohNet
Brn ReaderUntil::ReadProtocol(TUint aBytes)
{
    ASSERT(aBytes <= iMaxBytes);
    TByte* start = Ptr() + iOffset;
    TByte* p = start;
    if (aBytes <= iBytes - iOffset) {
        iOffset += aBytes;
        if (iOffset == iBytes) {
            iBytes = 0;
            iOffset = 0;
        }
        return Brn(start, aBytes);
    }
    if (iBytes > 0) {
        iBytes -= iOffset;
        start = Ptr();
        (void)memmove(start, start + iOffset, iBytes);
        p = start + iBytes;
        iOffset = 0;
        aBytes -= iBytes;
    }
    TUint remaining = aBytes;
    while (remaining > 0) {
        Brn buf = iReader.Read(remaining);
        (void)memcpy(p, buf.Ptr(), buf.Bytes());
        p += buf.Bytes();
    }
    iBytes = 0;
    iOffset = 0;
    return Brn(start, (TUint)(p - start));
}
示例#4
0
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);
        }
    }
}
示例#5
0
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);
}
示例#6
0
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;
    }
}
示例#7
0
文件: Shell.cpp 项目: broonie/ohNet
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();
}
示例#8
0
void WriterRingBuffer::Write(const Brx& aBuffer)
{
    const Brn tail = Tail(aBuffer, iBytes); // tail.Bytes() <= iBytes
    const TByte* ptr = tail.Ptr();
    const TUint bytes = tail.Bytes();
    const TUint bytesToEnd = iBytes - iCursor;

    if (bytes <= bytesToEnd)
    {
        // single write
        memcpy(&(iData[iCursor]), ptr, bytes);

        iCursor += bytes;

        if (iCursor == iBytes)
        {
            iCursor = 0;
            iWrapped = true;
        }
    }
    else
    {
        // double write
        memcpy(
            &(iData[iCursor]),
            ptr,
            bytesToEnd);

        memcpy(
            &(iData[0]),
            ptr + bytesToEnd,
            bytes - bytesToEnd);

        iCursor = bytes - bytesToEnd;
        iWrapped = true;
    }
}
示例#9
0
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");
        }
    }
}
示例#10
0
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;
    }
}