Beispiel #1
0
IFDE_CSSSelector* CFDE_CSSSelector::FromString(IFX_MEMAllocator* pStaticStore,
                                               const FX_WCHAR* psz,
                                               int32_t iLen) {
  FXSYS_assert(pStaticStore != NULL && psz != NULL && iLen > 0);
  const FX_WCHAR* pStart = psz;
  const FX_WCHAR* pEnd = psz + iLen;
  for (; psz < pEnd; ++psz) {
    switch (*psz) {
      case '>':
      case '[':
      case '+':
        return NULL;
    }
  }
  CFDE_CSSSelector *pFirst = NULL, *pLast = NULL;
  CFDE_CSSSelector *pPersudoFirst = NULL, *pPersudoLast = NULL;
  for (psz = pStart; psz < pEnd;) {
    FX_WCHAR wch = *psz;
    if (wch == '.' || wch == '#') {
      if (psz == pStart || psz[-1] == ' ') {
        CFDE_CSSSelector* p = FDE_NewWith(pStaticStore)
            CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, L"*", 1, TRUE);
        if (p == NULL) {
          return NULL;
        }
        if (pFirst != NULL) {
          pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
          p->SetNext(pFirst);
        }
        pFirst = pLast = p;
      }
      FXSYS_assert(pLast != NULL);
      int32_t iNameLen = FDE_GetCSSNameLen(++psz, pEnd);
      if (iNameLen == 0) {
        return NULL;
      }
      FDE_CSSSELECTORTYPE eType =
          wch == '.' ? FDE_CSSSELECTORTYPE_Class : FDE_CSSSELECTORTYPE_ID;
      CFDE_CSSSelector* p = FDE_NewWith(pStaticStore)
          CFDE_CSSSelector(eType, psz, iNameLen, FALSE);
      if (p == NULL) {
        return NULL;
      }
      p->SetNext(pLast->GetNextSelector());
      pLast->SetNext(p);
      pLast = p;
      psz += iNameLen;
    } else if (FDE_IsCSSChar(wch) || wch == '*') {
      int32_t iNameLen = wch == '*' ? 1 : FDE_GetCSSNameLen(psz, pEnd);
      if (iNameLen == 0) {
        return NULL;
      }
      CFDE_CSSSelector* p = FDE_NewWith(pStaticStore)
          CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, psz, iNameLen, TRUE);
      if (p == NULL) {
        return NULL;
      }
      if (pFirst == NULL) {
        pFirst = pLast = p;
      } else {
        pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
        p->SetNext(pFirst);
        pFirst = pLast = p;
      }
      psz += iNameLen;
    } else if (wch == ':') {
      int32_t iNameLen = FDE_GetCSSPersudoLen(psz, pEnd);
      if (iNameLen == 0) {
        return NULL;
      }
      CFDE_CSSSelector* p = FDE_NewWith(pStaticStore)
          CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Persudo, psz, iNameLen, TRUE);
      if (p == NULL) {
        return NULL;
      }
      if (pPersudoFirst == NULL) {
        pPersudoFirst = pPersudoLast = p;
      } else {
        pPersudoLast->SetNext(p);
        pPersudoLast = p;
      }
      psz += iNameLen;
    } else if (wch == ' ') {
      psz++;
    } else {
      return NULL;
    }
  }
  if (pPersudoFirst == NULL) {
    return pFirst;
  } else {
    pPersudoLast->SetNext(pFirst);
    return pPersudoFirst;
  }
}
CFDE_CSSSelector* CFDE_CSSSelector::FromString(
    IFX_MemoryAllocator* pStaticStore,
    const FX_WCHAR* psz,
    int32_t iLen) {
  ASSERT(pStaticStore && psz && iLen > 0);

  const FX_WCHAR* pStart = psz;
  const FX_WCHAR* pEnd = psz + iLen;
  for (; psz < pEnd; ++psz) {
    switch (*psz) {
      case '>':
      case '[':
      case '+':
        return nullptr;
    }
  }
  CFDE_CSSSelector* pFirst = nullptr;
  CFDE_CSSSelector* pLast = nullptr;
  CFDE_CSSSelector* pPersudoFirst = nullptr;
  CFDE_CSSSelector* pPersudoLast = nullptr;
  for (psz = pStart; psz < pEnd;) {
    FX_WCHAR wch = *psz;
    if (wch == '.' || wch == '#') {
      if (psz == pStart || psz[-1] == ' ') {
        CFDE_CSSSelector* p = FXTARGET_NewWith(pStaticStore)
            CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, L"*", 1, true);
        if (!p)
          return nullptr;

        if (pFirst) {
          pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
          p->SetNext(pFirst);
        }
        pFirst = pLast = p;
      }
      ASSERT(pLast);
      int32_t iNameLen = FDE_GetCSSNameLen(++psz, pEnd);
      if (iNameLen == 0) {
        return nullptr;
      }
      FDE_CSSSELECTORTYPE eType =
          wch == '.' ? FDE_CSSSELECTORTYPE_Class : FDE_CSSSELECTORTYPE_ID;
      CFDE_CSSSelector* p = FXTARGET_NewWith(pStaticStore)
          CFDE_CSSSelector(eType, psz, iNameLen, false);
      if (!p)
        return nullptr;

      p->SetNext(pLast->GetNextSelector());
      pLast->SetNext(p);
      pLast = p;
      psz += iNameLen;
    } else if (FDE_IsCSSChar(wch) || wch == '*') {
      int32_t iNameLen = wch == '*' ? 1 : FDE_GetCSSNameLen(psz, pEnd);
      if (iNameLen == 0) {
        return nullptr;
      }
      CFDE_CSSSelector* p = FXTARGET_NewWith(pStaticStore)
          CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, psz, iNameLen, true);
      if (!p)
        return nullptr;

      if (pFirst) {
        pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
        p->SetNext(pFirst);
      }
      pFirst = p;
      pLast = p;
      psz += iNameLen;
    } else if (wch == ':') {
      int32_t iNameLen = FDE_GetCSSPersudoLen(psz, pEnd);
      if (iNameLen == 0) {
        return nullptr;
      }
      CFDE_CSSSelector* p = FXTARGET_NewWith(pStaticStore)
          CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Persudo, psz, iNameLen, true);
      if (!p)
        return nullptr;

      if (pPersudoFirst)
        pPersudoLast->SetNext(p);
      else
        pPersudoFirst = p;
      pPersudoLast = p;
      psz += iNameLen;
    } else if (wch == ' ') {
      psz++;
    } else {
      return nullptr;
    }
  }
  if (!pPersudoFirst)
    return pFirst;

  pPersudoLast->SetNext(pFirst);
  return pPersudoFirst;
}