void SEPtrDict::insert(const SEString& key, const void* new_value) { if (key.isNull()) return; detach(); if (0 == d) { d = new Data(); d->ref = 1; for (size_t n = 0; n < SIZE; n++) d->dict[n] = 0; } d->dirty = true; unsigned int h = key.hash(SIZE); Element** e = &(d->dict[h]); while (*e) e = &((*e)->next); *e = new Element(key, new_value); }
SEIntList SEIntList::split(const SEString& str, char sep, char esc) { SEIntList ret; size_t from = 0; size_t cur = 0; size_t len = str.length(); // skip trailing separators while (str[cur] == sep) { from++; cur++; } cur++; while (cur <= len) { // the case when we go out of bounds is when we have escaped separator // before end of the string if (cur == len) { ret.append(str.substr(from, cur - 1).toInt()); break; } if (str[cur] == sep) { // here we may go out of bounds (handled above) if (esc && (str[cur - 1] == esc)) { cur++; continue; } ret.append(str.substr(from, cur - 1).toInt()); while ((str[cur] == sep) && (cur < len)) cur++; if (cur >= (len - 1)) break; from = cur++; continue; } if (cur == (len - 1)) { ret.append(str.substr(from, cur).toInt()); break; } cur++; } return ret; }
void SkypeContact::OnChange(int prop) { /* Here is the place where you can capture all property changes when they * happen. It's important to know that this method will receive ALL changes * from ALL properties, which means that it's necessary to create a nice and * robust filter inside this method to handle each type of property, * otherwise it can fail by acting incorrectly or even lose some events. * * Another interesting thing is that this method does not receive the new * value of the changed property. It's necessary to get the value from the * Contact class itself, because once this method is called the property is * already changed in the class. */ /* For our Contact class we will ony watch for the following * properties: * * - Contact::P_AVAILABILITY : Changes when the online status is set. * - Contact::P_DISPLAYNAME : Changes when a new Display Name is set. * - Contact::P_SKYPENAME : Changes when the skypename is updated. */ if (prop == Contact::P_AVAILABILITY || prop == Contact::P_DISPLAYNAME || prop == Contact::P_SKYPENAME) { // Let's log that it has changed! SEString skypeName; GetPropSkypename(skypeName); printf("%s: Contact's property changed.\n", skypeName.data()); /* And then notify the other interested objects that some of these * properties have changed. */ ContactRef ref = this->ref(); contactChanged(this, ref); } }
const Poco::SharedPtr<ContactData> Util::dataFromAccount(const AccountRef &account) { Poco::SharedPtr<ContactData> data(0); data = Poco::SharedPtr<ContactData>(new ContactData); SEString value; // Get the Skype Name from the account. account->GetPropSkypename(value); data->skypeName = value.data(); // Get the Display Name from the account. account->GetPropFullname(value); data->displayName = value; /* Get the availability from the Account and translate it to a readable * string. */ Contact::AVAILABILITY availability; account->GetPropAvailability(availability); std::pair<ContactAvailability, std::string> ret = convertAvailability(availability); data->status = ret.first; data->availability = ret.second; //Get the contact Avatar. SEBinary rawData; if (account->GetPropAvatarImage(rawData) && rawData.size() > 0) data->avatar.assignRaw(rawData.data(), rawData.size()); return data; }
Poco::SharedPtr<MessageData> Util::dataFromMessage(const MessageRef &message) { int messageType = message->GetProp(Message::P_TYPE).toInt(); SEString author; SEString authorName; SEString bodyXmlString; unsigned int timeStamp; message->GetPropAuthor(author); message->GetPropAuthorDisplayname(authorName); message->GetPropBodyXml(bodyXmlString); message->GetPropTimestamp(timeStamp); Poco::SharedPtr<MessageData> data = new MessageData; data->author = author.data(); data->authorDisplayname = authorName.data(); data->body = bodyXmlString.data(); data->timestamp = timeStamp; data->isEmote = (messageType == Message::POSTED_EMOTE); return data; }
void ConvManagerService::setParticipants( const std::vector<std::string> &participantSkypeNames) { // Get the new participants. unsigned int newSkypeNamesSize = participantSkypeNames.size(); std::vector<std::string> newSkypeNames = participantSkypeNames; // Get the current participants. ParticipantRefs currentSkypeNames; m_conversation->GetParticipants(currentSkypeNames, Conversation::OTHER_CONSUMERS); unsigned int currentSkypeNamesSize = currentSkypeNames.size(); // Check which participant needs to be added to the conversation. SEStringList addSkypeNames; for (unsigned int i = 0; i < newSkypeNamesSize; ++i) { bool contain = false; for (unsigned int j = 0; j < currentSkypeNamesSize; ++j) { SEString oid; currentSkypeNames[j]->GetPropIdentity(oid); if (newSkypeNames[i] == oid.data()) { if (m_conversationMode == Call) currentSkypeNames[j]->Ring(); contain = true; break; } } if (!contain) addSkypeNames.append(SEString(newSkypeNames[i].c_str())); } // Check which participant needs to be removed from the conversation. ParticipantRefs remSkypeNames; for (unsigned int i = 0; i < currentSkypeNamesSize; ++i) { bool contain = false; for (unsigned int j = 0; j < newSkypeNamesSize; ++j) { SEString oid; currentSkypeNames[i]->GetPropIdentity(oid); if (oid.data() == newSkypeNames[j]) { contain = true; break; } } if (!contain) remSkypeNames.append(currentSkypeNames[i]); } SkypeConversation::Ref newConversation; Conversation::TYPE type; m_conversation->GetPropType(type); // Pass the skypename string into addConsumers if (type == Conversation::DIALOG) { if (m_conversation->SpawnConference(addSkypeNames, newConversation)) printf("spawned conference from conversation\n"); else printf("error spawning conference from conversation\n"); } else { // Add new participants to the conference. if (m_conversation->AddConsumers(addSkypeNames)) printf("added participants to conversation\n"); else printf("error adding participants to conversation\n"); // Remove old participants from the conference. unsigned int remSize = remSkypeNames.size(); for (unsigned int i = 0; i < remSize; ++i) { SEString oid; remSkypeNames[i]->GetPropIdentity(oid); if (m_conversationMode == Chat) { if (!remSkypeNames[i]->Retire()) printf("error retiring participant form conversation\n"); } else { if (!remSkypeNames[i]->Hangup()) printf("error removing participant form conversation\n"); } } } }
std::string ConvManagerState::id() const { SEString identity; m_conversation->GetPropIdentity(identity); return std::string("ConvManagerState_") + identity.data(); }
Poco::SharedPtr<ContactData> Util::dataFromContact(const ContactRef &contact) { /* As we are only interested in some data about the Contact, let's fill * a small structure with everything we need and then return. */ Poco::SharedPtr<ContactData> newData = Poco::SharedPtr<ContactData>(new ContactData); newData->canSMS = false; SEString value; // Get the Skype Name from the Contact. Contact::TYPE type; contact->GetPropType(type); switch (type) { case Contact::SKYPE: contact->GetPropSkypename(value); break; case Contact::PSTN: contact->GetPropPstnnumber(value); newData->canSMS = true; break; default: value = "Unrecognized"; } newData->skypeName = value; // Get the Display Name from the Contact. contact->GetPropDisplayname(value); newData->displayName = value; if (!newData->canSMS) { // See if the contact has a mobile number set. contact->GetPropPhoneMobile(value); if (value.length() > 0) newData->canSMS = true; } /* Get the availability from the Contact and translate it to a readable * string. */ Contact::AVAILABILITY availability; contact->GetPropAvailability(availability); std::pair<ContactAvailability, std::string> ret = convertAvailability(availability); newData->status = ret.first; newData->availability = ret.second; //Get the contact Avatar. bool hasAvatar = false; SEBinary rawData; contact->GetAvatar(hasAvatar, rawData); // Check if the contact has an avatar and then extract the data from it. if (hasAvatar) newData->avatar.assignRaw(rawData.data(), rawData.size()); // Get the contact capabilities. contact->HasCapability(Contact::CAPABILITY_TEXT, newData->canIM); newData->canCall = (newData->status != Offline); newData->canFT = (newData->status != Offline && type == Contact::SKYPE); return newData; }
SEStringList SEStringList::split(const SEString& str, char sep, char esc) { SEStringList ret; size_t from = 0; size_t cur = 0; const size_t len = str.length(); if (len == 0) return ret; // skip leading separators // .bwc. Repeated code, but easier to understand this way I think. // The compiler may optimize this away. while (str[cur] == sep) { cur++; } // .bwc. At this point, cur is not pointing at a separator; // we will not end up in the code block that appends below // until we have incremented at least once. from = cur; bool in_escape=false; bool in_quotes=false; while (cur < len) { if (str[cur] == sep) { if (!in_escape && !in_quotes) { ret.append(str.substr(from, cur - 1)); while (str[cur] == sep) cur++; // Not pointing at a separator; will not append // again until we have incremented at least // once. from = cur; continue; } } else if (esc && str[cur] == '\"' && !in_escape) { // !bwc! We check esc because that is what we've always // done. Once I hear back from the guys that // implemented this about whether this is the intended // behavior, this component might be removed. in_quotes = !in_quotes; } in_escape = esc && str[cur] == esc && !in_escape; cur++; } // .bwc. cur == from can happen when we have a trailing separator. // (both are pointing at the null terminator in this case) if(cur != from) { ret.append(str.substr(from, cur)); } return ret; }
void MyTransfer::OnChange(int prop) { // Uncomment the following section to see ALL the Transfer class property changes /** SEString value; value = this->GetProp(prop); SEStringList dbg = this->getPropDebug(prop, value); printf("%s %s -> %s\n", (const char*)dbg[0], (const char*)dbg[1], (const char*)dbg[2]); **/ if (prop == Transfer::P_STATUS) { // Transfer::P_STATUS debug output.. Transfer::STATUS transferStatus; GetPropStatus(transferStatus); printf("%s\n", (const char*)tostring(transferStatus)); // Here we handle the case when an incoming FT was created with PLACEHOLDER status. // In that case we could not accept it immediately, and had to wait until the // status changed to NEW. Which is this place here. if (transferStatus == NEW) { Transfer::TYPE transferType; this->GetPropType(transferType); if (transferType == Transfer::INCOMING) this->AutoAccept(); }; // Is the transfer done yet? if ( (transferStatus == CANCELLED) || (transferStatus == COMPLETED) || (transferStatus == FAILED) || (transferStatus == CANCELLED_BY_REMOTE) ) { printf("Removing Transfer from Conversation transfers list\n"); if ( globalTransferList->contains(this->ref()) ) { globalTransferList->remove_val(this->ref()); } if (globalTransferList->size() == 0) { printf("All pending file transfers are complete.\nPress ENTER to quit."); isDoneSending = true; }; }; }; // Transfer progress output. if (prop == Transfer::P_BYTESTRANSFERRED) { SEString transferProgressStr; this->GetPropBytestransferred(transferProgressStr); uint transferProgress = transferProgressStr.toUInt(); SEString fileSizeStr; this->GetPropFilesize(fileSizeStr); // fileSize is float here, to avoid trouble with // files lessthan 100 bytes in size. float fileSize = fileSizeStr.toUInt(); float progress = transferProgress / (fileSize / 100); uint transferRate; this->GetPropBytespersecond(transferRate); float transferRateInKb = transferRate / 1024; printf("Progress: %3.0f%% (%1.0f KB/s)\n", progress, transferRateInKb); }; };