Remove private BStringList implementation from mail. Tested it but however please be careful an review. This fixes bug #8174.

This commit is contained in:
czeidler
2011-12-15 19:45:07 +13:00
parent 779061f0cd
commit ed77847ca4
5 changed files with 33 additions and 452 deletions
@@ -1,73 +0,0 @@
#ifndef ZOIDBERG_STRING_LIST_H
#define ZOIDBERG_STRING_LIST_H
/* StringList - a string list implementation
**
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
*/
#include <Flattenable.h>
class BList;
class BStringList : public BFlattenable {
public:
BStringList();
BStringList(const BStringList&);
~BStringList(void);
BStringList &operator=(const BStringList &from);
/* Flattenable stuff */
virtual bool IsFixedSize() const; //--false for obvious reasons
virtual type_code TypeCode() const;
virtual ssize_t FlattenedSize() const;
virtual status_t Flatten(void *buffer, ssize_t size) const;
virtual bool AllowsTypeCode(type_code code) const;
virtual status_t Unflatten(type_code c, const void *buf, ssize_t size);
/* Adding and removing items. */
void AddItem(const char *item);
void AddList(const BStringList *newItems);
bool RemoveItem(const char *item);
void MakeEmpty();
/* Retrieving items. */
const char *ItemAt(int32) const;
int32 IndexOf(const char *) const;
/* Querying the list. */
bool HasItem(const char *item) const;
int32 CountItems() const;
bool IsEmpty() const;
/* Determining differences between lists */
void NotHere(BStringList &other_list, BStringList *results);
void NotThere(BStringList &other_list, BStringList *results);
/* Useful list logic operators */
BStringList &operator += (const char *item);
BStringList &operator += (BStringList &list);
BStringList &operator -= (const char *item);
BStringList &operator -= (BStringList &list);
BStringList operator | (BStringList &list);
BStringList &operator |= (BStringList &list);
BStringList operator ^ (BStringList &list);
BStringList &operator ^= (BStringList &list);
bool operator == (BStringList &list);
const char *operator [] (int32 index);
private:
void *_buckets[256];
int32 _items;
BList *_indexed;
uint32 _reserved[5];
};
#endif /* ZOIDBERG_STRING_LIST_H */
@@ -48,6 +48,16 @@
#define B_TRANSLATE_CONTEXT "pop3" #define B_TRANSLATE_CONTEXT "pop3"
static void NotHere(BStringList &that, BStringList &otherList,
BStringList *results)
{
for (int32 i = 0; i < otherList.CountStrings(); i++) {
if (!that.HasString(otherList.StringAt(i)))
results->Add(otherList.StringAt(i));
}
}
#define POP3_RETRIEVAL_TIMEOUT 60000000 #define POP3_RETRIEVAL_TIMEOUT 60000000
#define CRLF "\r\n" #define CRLF "\r\n"
@@ -159,9 +169,9 @@ POP3Protocol::SyncMessages()
} }
BStringList toDownload; BStringList toDownload;
fManifest.NotHere(fUniqueIDs, &toDownload); NotHere(fManifest, fUniqueIDs, &toDownload);
int32 numMessages = toDownload.CountItems(); int32 numMessages = toDownload.CountStrings();
if (numMessages == 0) { if (numMessages == 0) {
CheckForDeletedMessages(); CheckForDeletedMessages();
ResetProgress(); ResetProgress();
@@ -169,11 +179,11 @@ POP3Protocol::SyncMessages()
} }
ResetProgress(); ResetProgress();
SetTotalItems(toDownload.CountItems()); SetTotalItems(toDownload.CountStrings());
printf("POP3: Messages to download: %i\n", (int)toDownload.CountItems()); printf("POP3: Messages to download: %i\n", (int)toDownload.CountStrings());
for (int32 i = 0; i < toDownload.CountItems(); i++) { for (int32 i = 0; i < toDownload.CountStrings(); i++) {
const char* uid = toDownload.ItemAt(i); const char* uid = toDownload.StringAt(i);
int32 toRetrieve = fUniqueIDs.IndexOf(uid); int32 toRetrieve = fUniqueIDs.IndexOf(uid);
if (toRetrieve < 0) { if (toRetrieve < 0) {
@@ -236,7 +246,7 @@ POP3Protocol::SyncMessages()
file.WriteAttr("MAIL:size", B_INT32_TYPE, 0, &size, sizeof(int32)); file.WriteAttr("MAIL:size", B_INT32_TYPE, 0, &size, sizeof(int32));
// save manifest in case we get disturbed // save manifest in case we get disturbed
fManifest += uid; fManifest.Add(uid);
_WriteManifest(); _WriteManifest();
} }
@@ -560,17 +570,17 @@ POP3Protocol::CheckForDeletedMessages()
{ {
//---Delete things from the manifest no longer on the server //---Delete things from the manifest no longer on the server
BStringList temp; BStringList temp;
fManifest.NotThere(fUniqueIDs, &temp); NotHere(fUniqueIDs, fManifest, &temp);
fManifest -= temp; fManifest.Remove(temp);
} }
if (!fSettings.FindBool("delete_remote_when_local") if (!fSettings.FindBool("delete_remote_when_local")
|| fManifest.CountItems() == 0) || fManifest.CountStrings() == 0)
return; return;
BStringList to_delete; BStringList toDelete;
BStringList query_contents; BStringList queryContents;
BVolumeRoster volumes; BVolumeRoster volumes;
BVolume volume; BVolume volume;
@@ -588,20 +598,20 @@ POP3Protocol::CheckForDeletedMessages()
BString uid; BString uid;
while (fido.GetNextRef(&entry) == B_OK) { while (fido.GetNextRef(&entry) == B_OK) {
BNode(&entry).ReadAttrString("MAIL:unique_id", &uid); BNode(&entry).ReadAttrString("MAIL:unique_id", &uid);
query_contents.AddItem(uid.String()); queryContents.Add(uid);
} }
} }
query_contents.NotHere(fManifest, &to_delete); NotHere(queryContents, fManifest, &toDelete);
for (int32 i = 0; i < to_delete.CountItems(); i++) { for (int32 i = 0; i < toDelete.CountStrings(); i++) {
printf("delete mail on server uid %s\n", to_delete[i]); printf("delete mail on server uid %s\n", toDelete.StringAt(i).String());
Delete(fUniqueIDs.IndexOf(to_delete[i])); Delete(fUniqueIDs.IndexOf(toDelete.StringAt(i)));
} }
//*(unique_ids) -= to_delete; --- This line causes bad things to //*(unique_ids) -= to_delete; --- This line causes bad things to
// happen (POP3 client uses the wrong indices to retrieve // happen (POP3 client uses the wrong indices to retrieve
// messages). Without it, bad things don't happen. // messages). Without it, bad things don't happen.
fManifest -= to_delete; fManifest.Remove(toDelete);
} }
@@ -982,14 +992,14 @@ POP3Protocol::_UniqueIDs()
return ret; return ret;
BString result; BString result;
int32 uid_offset; int32 uidOffset;
while (ReceiveLine(result) > 0) { while (ReceiveLine(result) > 0) {
if (result.ByteAt(0) == '.') if (result.ByteAt(0) == '.')
break; break;
uid_offset = result.FindFirst(' ') + 1; uidOffset = result.FindFirst(' ') + 1;
result.Remove(0,uid_offset); result.Remove(0, uidOffset);
fUniqueIDs.AddItem(result.String()); fUniqueIDs.Add(result);
} }
if (SendCommand("LIST" CRLF) != B_OK) if (SendCommand("LIST" CRLF) != B_OK)
-1
View File
@@ -32,7 +32,6 @@ local sources =
numailkit.cpp numailkit.cpp
ProtocolConfigView.cpp ProtocolConfigView.cpp
ServerConnection.cpp ServerConnection.cpp
StringList.cpp
; ;
-355
View File
@@ -1,355 +0,0 @@
/* BStringList - a string list implementation
**
** Copyright 2001 Dr. Zoidberg Enterprises. All rights reserved.
*/
#include <List.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
class _EXPORT BStringList;
#include "StringList.h"
static uint8 string_hash(const char *string);
static uint8 string_hash(const char *string) {
uint8 hash = 0;
for (int i = 0; string[i] != 0; i++)
hash ^= string[i];
return hash;
}
struct string_bucket {
const char *string;
~string_bucket() {
if (string != NULL)
free ((void *)(string));
}
struct string_bucket *next;
};
BStringList::BStringList()
: BFlattenable(), _items(0), _indexed(new BList)
{
for (int32 i = 0; i < 256; i++)
_buckets[i] = NULL;
}
BStringList::BStringList(const BStringList& from)
: BFlattenable(), _items(0), _indexed(new BList)
{
for (int32 i = 0; i < 256; i++)
_buckets[i] = NULL;
AddList(&from);
}
BStringList &BStringList::operator=(const BStringList &from) {
MakeEmpty();
AddList(&from);
return *this;
}
bool BStringList::IsFixedSize() const {
return false;
}
type_code BStringList::TypeCode() const {
return 'STRL';
}
ssize_t BStringList::FlattenedSize() const {
ssize_t size = 0;
struct string_bucket *bkt;
for (int32 i = 0; i < 256; i++) {
bkt = (struct string_bucket *)(_buckets[i]);
while (bkt != NULL) {
size += (strlen(bkt->string) + 1);
bkt = bkt->next;
}
}
return size;
}
status_t BStringList::Flatten(void *buffer, ssize_t size) const {
if (size < FlattenedSize())
return B_NO_MEMORY;
for (int32 i = 0; i < CountItems(); i++) {
memcpy(buffer, ItemAt(i), strlen(ItemAt(i)) + 1);
buffer = (void *)((const char *)(buffer) + (strlen(ItemAt(i)) + 1));
}
return B_OK;
}
bool BStringList::AllowsTypeCode(type_code code) const {
return (code == 'STRL');
}
status_t BStringList::Unflatten(type_code c, const void *buf, ssize_t size) {
if (c != 'STRL')
return B_ERROR;
const char *string = (const char *)(buf);
for (off_t offset = 0; offset < size; offset ++) {
if (((int8 *)(buf))[offset] == 0) {
AddItem(string);
string = (const char *)buf + offset + 1;
}
}
return B_OK;
}
void BStringList::AddItem(const char *item) {
struct string_bucket *new_bkt;
new_bkt = (struct string_bucket *)_buckets[string_hash(item)];
if (new_bkt == NULL) {
new_bkt = new struct string_bucket;
new_bkt->string = strdup(item);
_indexed->AddItem((void *)(new_bkt->string));
new_bkt->next = NULL;
_buckets[string_hash(item)] = new_bkt;
_items++;
return;
}
while (new_bkt->next != NULL) new_bkt = new_bkt->next;
new_bkt->next = new struct string_bucket;
new_bkt = new_bkt->next;
new_bkt->string = strdup(item);
_indexed->AddItem((void *)(new_bkt->string));
new_bkt->next = NULL;
_items++;
}
void BStringList::AddList(const BStringList *newItems) {
for (int32 i = 0; i < newItems->CountItems(); i++)
AddItem((const char *)(newItems->ItemAt(i)));
/*struct string_bucket *bkt, *new_bkt;
for (int32 i = 0; i < 256; i++) {
bkt = (struct string_bucket *)(newItems->_buckets[i]);
while (bkt != NULL) {
new_bkt = (struct string_bucket *)_buckets[i];
if (new_bkt == NULL) {
new_bkt = new struct string_bucket;
new_bkt->string = strdup(bkt->string);
_indexed->Add
new_bkt->next = NULL;
_buckets[i] = new_bkt;
_items++;
continue;
}
while (new_bkt->next != NULL) new_bkt = new_bkt->next;
new_bkt->next = new struct string_bucket;
new_bkt = new_bkt->next;
new_bkt->string = strdup(bkt->string);
new_bkt->next = NULL;
_items++;
bkt = bkt->next;
}
}*/
}
bool BStringList::RemoveItem(const char *item) {
struct string_bucket *bkt = (struct string_bucket *)_buckets[string_hash(item)];
if (bkt == NULL)
return false;
if (strcmp(bkt->string,item) == 0) {
_indexed->RemoveItem(IndexOf(item));
_buckets[string_hash(item)] = bkt->next;
delete bkt;
_items--;
return true;
}
struct string_bucket *tmp_bkt;
while (bkt->next != NULL) {
if (strcmp(bkt->next->string,item) == 0) {
_indexed->RemoveItem(IndexOf(item));
tmp_bkt = bkt->next;
bkt->next = bkt->next->next;
delete tmp_bkt;
_items--;
return true;
}
bkt = bkt->next;
}
return false;
}
void BStringList::MakeEmpty() {
struct string_bucket *bkt, *next_bkt;
for (int i = 0; i < 256; i++) {
bkt = (struct string_bucket *)_buckets[i];
_buckets[i] = NULL;
while (bkt != NULL) {
next_bkt = bkt->next;
delete bkt;
bkt = next_bkt;
}
}
_indexed->MakeEmpty();
_items = 0;
}
const char *BStringList::ItemAt(int32 index) const {
return (const char *)(_indexed->ItemAt(index));
}
int32 BStringList::IndexOf(const char *item) const {
for (int32 i = 0; i < _indexed->CountItems(); i++) {
if (strcmp(item,(const char *)_indexed->ItemAt(i)) == 0)
return i;
}
return -1;
}
bool BStringList::HasItem(const char *item) const {
struct string_bucket *bkt = (struct string_bucket *)_buckets[string_hash(item)];
while (bkt != NULL) {
if (strcmp(bkt->string,item) == 0)
return true;
bkt = bkt->next;
}
return false;
}
int32 BStringList::CountItems() const {
return _items;
}
bool BStringList::IsEmpty() const {
return (_items == 0);
}
void BStringList::NotHere(BStringList &other_list, BStringList *results) {
#if DEBUG
assert(_items == _indexed->CountItems());
assert(other_list._items == other_list._indexed->CountItems());
#endif
for (int32 i = 0; i < other_list.CountItems(); i++) {
if (!HasItem(other_list[i]))
results->AddItem(other_list[i]);
}
}
void BStringList::NotThere(BStringList &other_list, BStringList *results) {
other_list.NotHere(*this,results);
}
BStringList &BStringList::operator += (const char *item) {
AddItem(item);
return *this;
}
BStringList &BStringList::operator += (BStringList &list) {
AddList(&list);
return *this;
}
BStringList &BStringList::operator -= (const char *item) {
RemoveItem(item);
return *this;
}
BStringList &BStringList::operator -= (BStringList &list) {
for (int32 i = 0; i < list.CountItems(); i++)
RemoveItem(list[i]);
return *this;
}
BStringList BStringList::operator | (BStringList &list2) {
BStringList list(*this);
for (int32 i = 0; i < list2.CountItems(); i++) {
if (!list.HasItem(list2.ItemAt(i)))
list += list2.ItemAt(i);
}
return list;
}
BStringList &BStringList::operator |= (BStringList &list2) {
for (int32 i = 0; i < list2.CountItems(); i++) {
if (!HasItem(list2.ItemAt(i)))
AddItem(list2.ItemAt(i));
}
return *this;
}
BStringList BStringList::operator ^ (BStringList &list2) {
BStringList list;
for (int32 i = 0; i < CountItems(); i++) {
if (!list2.HasItem(ItemAt(i)))
list += ItemAt(i);
}
for (int32 i = 0; i < list2.CountItems(); i++) {
if (!HasItem(list2.ItemAt(i)))
list += list2.ItemAt(i);
}
return list;
}
BStringList &BStringList::operator ^= (BStringList &list) {
return (*this = *this ^ list);
}
bool BStringList::operator == (BStringList &list) {
if (list.CountItems() != CountItems())
return false;
for (int32 i = 0; i < CountItems(); i++) {
if (strcmp(list.ItemAt(i),ItemAt(i)) != 0)
return false;
}
return true;
}
const char *BStringList::operator [] (int32 index) {
return ItemAt(index);
}
BStringList::~BStringList() {
MakeEmpty();
delete _indexed;
}
+1 -1
View File
@@ -379,7 +379,7 @@ BStringList::Unflatten(type_code code, const void* buffer, ssize_t size)
return B_ERROR; return B_ERROR;
const char* str = (const char*)buffer; const char* str = (const char*)buffer;
for (off_t offset = 0; offset < size; offset ++) { for (off_t offset = 0; offset < size; offset++) {
if (((int8*)buffer)[offset] == 0) { if (((int8*)buffer)[offset] == 0) {
Add(str); Add(str);
str = (const char*)buffer + offset + 1; str = (const char*)buffer + offset + 1;