int CJabberProto::AddFeatures(LPCTSTR szFeatures) { if (!szFeatures) return false; mir_cslockfull lck(m_csLists); BOOL ret = true; LPCTSTR szFeat = szFeatures; while (szFeat[0]) { JabberFeatCapPairDynamic *fcp = FindFeature(szFeat); // if someone is trying to add one of core features, RegisterFeature() will return false, so we don't have to perform this check here if (!fcp) { // if the feature is not registered yet if (!RegisterFeature(szFeat, NULL)) ret = false; else fcp = FindFeature(szFeat); // update fcp after RegisterFeature() } if (fcp) m_uEnabledFeatCapsDynamic |= fcp->jcbCap; else ret = false; szFeat += lstrlen(szFeat) + 1; } lck.unlock(); if (m_bJabberOnline) SendPresence(m_iStatus, true); return ret; }
feature_t SetFeature (const StrBuf* Key) /* Find the feature and set the corresponding flag if the feature is known. * In any case, return the feature found. An invalid Key will return * FEAT_UNKNOWN. */ { /* Map the string to an enum value */ feature_t Feature = FindFeature (Key); /* Set the flags */ switch (Feature) { case FEAT_DOLLAR_IS_PC: DollarIsPC = 1; break; case FEAT_LABELS_WITHOUT_COLONS: NoColonLabels = 1; break; case FEAT_LOOSE_STRING_TERM: LooseStringTerm = 1; break; case FEAT_LOOSE_CHAR_TERM: LooseCharTerm = 1; break; case FEAT_AT_IN_IDENTIFIERS: AtInIdents = 1; break; case FEAT_DOLLAR_IN_IDENTIFIERS: DollarInIdents = 1; break; case FEAT_LEADING_DOT_IN_IDENTIFIERS: LeadingDotInIdents= 1; break; case FEAT_ORG_PER_SEG: OrgPerSeg = 1; break; case FEAT_PC_ASSIGNMENT: PCAssignment = 1; break; case FEAT_MISSING_CHAR_TERM: MissingCharTerm = 1; break; case FEAT_UBIQUITOUS_IDENTS: UbiquitousIdents = 1; break; case FEAT_C_COMMENTS: CComments = 1; break; case FEAT_FORCE_RANGE: ForceRange = 1; break; case FEAT_UNDERLINE_IN_NUMBERS: UnderlineInNumbers= 1; break; default: /* Keep gcc silent */ break; } /* Return the value found */ return Feature; }
int CJabberProto::RegisterFeature(LPCTSTR szFeature, LPCTSTR szDescription) { if (!szFeature) return false; // check for this feature in core features, and return false if it's present, to prevent re-registering a core feature int i; for (i=0; g_JabberFeatCapPairs[i].szFeature; i++) if (!lstrcmp(g_JabberFeatCapPairs[i].szFeature, szFeature)) return false; mir_cslock lck(m_csLists); JabberFeatCapPairDynamic *fcp = FindFeature(szFeature); if (!fcp) { // if the feature is not registered yet, allocate new bit for it JabberCapsBits jcb = JABBER_CAPS_OTHER_SPECIAL; // set all bits not included in g_JabberFeatCapPairs // set all bits occupied by g_JabberFeatCapPairs for (i=0; g_JabberFeatCapPairs[i].szFeature; i++) jcb |= g_JabberFeatCapPairs[i].jcbCap; // set all bits already occupied by external plugins for (i=0; i < m_lstJabberFeatCapPairsDynamic.getCount(); i++) jcb |= m_lstJabberFeatCapPairsDynamic[i]->jcbCap; // Now get first zero bit. The line below is a fast way to do it. If there are no zero bits, it returns 0. jcb = (~jcb) & (JabberCapsBits)(-(__int64)(~jcb)); // no more free bits if (!jcb) return false; // remove unnecessary symbols from szFeature to make the string shorter, and use it as szExt LPTSTR szExt = mir_tstrdup(szFeature); LPTSTR pSrc, pDst; for (pSrc = szExt, pDst = szExt; *pSrc; pSrc++) if (_tcschr(_T("bcdfghjklmnpqrstvwxz0123456789"), *pSrc)) *pDst++ = *pSrc; *pDst = 0; m_clientCapsManager.SetClientCaps(JABBER_CAPS_MIRANDA_NODE, szExt, jcb); fcp = new JabberFeatCapPairDynamic(); fcp->szExt = szExt; // will be deallocated along with other values of JabberFeatCapPairDynamic in CJabberProto destructor fcp->szFeature = mir_tstrdup(szFeature); fcp->szDescription = szDescription ? mir_tstrdup(szDescription) : NULL; fcp->jcbCap = jcb; m_lstJabberFeatCapPairsDynamic.insert(fcp); } else if (szDescription) { // update description if (fcp->szDescription) mir_free(fcp->szDescription); fcp->szDescription = mir_tstrdup(szDescription); } return true; }
int CJabberProto::RemoveFeatures(LPCTSTR szFeatures) { if (!szFeatures) return false; mir_cslockfull lck(m_csLists); BOOL ret = true; LPCTSTR szFeat = szFeatures; while (szFeat[0]) { JabberFeatCapPairDynamic *fcp = FindFeature(szFeat); if (fcp) m_uEnabledFeatCapsDynamic &= ~fcp->jcbCap; else ret = false; // indicate that there was an error removing at least one of the specified features szFeat += lstrlen(szFeat) + 1; } lck.unlock(); if (m_bJabberOnline) SendPresence(m_iStatus, true); return ret; }