version 1.3.16.2, 2007/09/12 20:35:20
|
version 1.4, 2008/11/12 21:23:23
|
|
|
#include <Pegasus/Common/InternalException.h> | #include <Pegasus/Common/InternalException.h> |
#include <Pegasus/Common/AutoPtr.h> | #include <Pegasus/Common/AutoPtr.h> |
#include <Pegasus/Common/ArrayInternal.h> | #include <Pegasus/Common/ArrayInternal.h> |
|
#include <Pegasus/Common/Pair.h> |
#if defined(PEGASUS_OS_VXWORKS) |
|
# include <math.h> |
|
#endif |
|
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
////////////////////////////////////////////////////////////// |
typedef Pair<LanguageTag, Real32> AcceptLanguagePair; |
// |
typedef Array<AcceptLanguagePair> AcceptLanguageArray; |
// AcceptLanguageListRep |
|
// |
|
////////////////////////////////////////////////////////////// |
|
| |
class AcceptLanguageListRep |
#define PEGASUS_ARRAY_T AcceptLanguagePair |
{ |
# include <Pegasus/Common/ArrayInter.h> |
public: |
# include "ArrayImpl.h" |
Array<LanguageTag> languageTags; |
#undef PEGASUS_ARRAY_T |
Array<Real32> qualityValues; |
|
}; |
|
| |
////////////////////////////////////////////////////////////// |
|
// | // |
// AcceptLanguageList |
// Implementation Notes: |
|
// ===================== |
|
// |
|
// The internal representation member (_rep) is a pointer to an |
|
// AcceptLanguageListRep object. We could define a class with this name |
|
// as follows: |
|
// |
|
// class AcceptLanguageListRep |
|
// { |
|
// AcceptLanguageArray array; |
|
// }; |
|
// |
|
// But this requires separate heap object to hold the array. Instead we use |
|
// the following fact to eliminate the extra heap object: |
|
// |
|
// sizeof(AcceptLanguageArray) == sizeof(AcceptLanguageListRep*) |
|
// |
|
// We know this since all arrays contain a single pointer to a representation |
|
// object. Take for example the following structure: |
|
// |
|
// class MyClass |
|
// { |
|
// void* rep; |
|
// }; |
|
// |
|
// Clearly, sizeof(MyClass) == sizeof(void*). We eliminate the extra heap object |
|
// by overlaying the AcceptLanguageList::_rep pointer with the array base. So |
|
// AcceptLanguageList::_rep in fact refers to the Array<T>::_rep. |
// | // |
////////////////////////////////////////////////////////////// |
|
| |
AcceptLanguageList::AcceptLanguageList() | AcceptLanguageList::AcceptLanguageList() |
{ | { |
_rep = new AcceptLanguageListRep(); |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
new (&self) AcceptLanguageArray; |
} | } |
| |
AcceptLanguageList::AcceptLanguageList( |
AcceptLanguageList::AcceptLanguageList(const AcceptLanguageList& x) |
const AcceptLanguageList& acceptLanguages) |
|
{ | { |
_rep = new AcceptLanguageListRep(); |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
AutoPtr<AcceptLanguageListRep> rep(_rep); |
AcceptLanguageArray& other = *((AcceptLanguageArray*)&x); |
|
new (&self) AcceptLanguageArray(other); |
_rep->languageTags = acceptLanguages._rep->languageTags; |
|
_rep->qualityValues = acceptLanguages._rep->qualityValues; |
|
|
|
rep.release(); |
|
} | } |
| |
AcceptLanguageList::~AcceptLanguageList() | AcceptLanguageList::~AcceptLanguageList() |
{ | { |
delete _rep; |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
self.~AcceptLanguageArray(); |
} | } |
| |
AcceptLanguageList& AcceptLanguageList::operator=( |
AcceptLanguageList& AcceptLanguageList::operator=(const AcceptLanguageList& x) |
const AcceptLanguageList& acceptLanguages) |
|
{ |
|
if (&acceptLanguages != this) |
|
{ | { |
_rep->languageTags = acceptLanguages._rep->languageTags; |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
_rep->qualityValues = acceptLanguages._rep->qualityValues; |
AcceptLanguageArray& other = *((AcceptLanguageArray*)&x); |
} |
|
|
if (&self != &other) |
|
self = other; |
return *this; | return *this; |
} | } |
| |
Uint32 AcceptLanguageList::size() const | Uint32 AcceptLanguageList::size() const |
{ | { |
return _rep->languageTags.size(); |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
return self.size(); |
} | } |
| |
LanguageTag AcceptLanguageList::getLanguageTag(Uint32 index) const | LanguageTag AcceptLanguageList::getLanguageTag(Uint32 index) const |
{ | { |
return _rep->languageTags[index]; |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
return self[index].first; |
} | } |
| |
Real32 AcceptLanguageList::getQualityValue(Uint32 index) const |
Real32 AcceptLanguageList::getQualityValue(Uint32 i) const |
{ | { |
return _rep->qualityValues[index]; |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
return self[i].second; |
} | } |
| |
void AcceptLanguageList::insert( | void AcceptLanguageList::insert( |
|
|
{ | { |
LanguageParser::validateQualityValue(qualityValue); | LanguageParser::validateQualityValue(qualityValue); |
| |
// Insert in order of descending quality value |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
Uint32 i; |
|
Uint32 n = self.size(); |
| |
Uint32 index; |
for (i = 0; i < n; i++) |
const Uint32 maxIndex = _rep->languageTags.size(); |
|
|
|
for (index = 0; index < maxIndex; index++) |
|
{ | { |
if (_rep->qualityValues[index] < qualityValue) |
if (self[i].second < qualityValue) |
{ | { |
// Insert the new element before the element at this index | // Insert the new element before the element at this index |
break; | break; |
} | } |
} | } |
| |
_rep->languageTags.insert(index, languageTag); |
self.insert(i, AcceptLanguagePair(languageTag, qualityValue)); |
_rep->qualityValues.insert(index, qualityValue); |
|
} | } |
| |
void AcceptLanguageList::remove(Uint32 index) |
void AcceptLanguageList::remove(Uint32 i) |
{ | { |
_rep->languageTags.remove(index); |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
_rep->qualityValues.remove(index); |
self.remove(i); |
} | } |
| |
Uint32 AcceptLanguageList::find(const LanguageTag& languageTag) const | Uint32 AcceptLanguageList::find(const LanguageTag& languageTag) const |
{ | { |
for (Uint32 i = 0; i < _rep->languageTags.size(); i++) |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
{ |
Uint32 n = self.size(); |
if (languageTag == _rep->languageTags[i]) |
|
|
for (Uint32 i = 0; i < n; i++) |
{ | { |
|
if (languageTag == self[i].first) |
return i; | return i; |
} | } |
} |
|
return PEG_NOT_FOUND; | return PEG_NOT_FOUND; |
} | } |
| |
void AcceptLanguageList::clear() | void AcceptLanguageList::clear() |
{ | { |
_rep->languageTags.clear(); |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
_rep->qualityValues.clear(); |
self.clear(); |
} | } |
| |
static inline bool _equal(Real32 x, Real32 y) |
Boolean AcceptLanguageList::operator==(const AcceptLanguageList& x) const |
{ | { |
#if defined(PEGASUS_OS_VXWORKS) |
AcceptLanguageArray& self = *((AcceptLanguageArray*)this); |
|
AcceptLanguageArray& other = *((AcceptLanguageArray*)&x); |
| |
{ |
Uint32 n = self.size(); |
float tmp = 1.5; |
|
assert(tmp == 1.5); |
|
printf("e1[%f]\n", tmp); |
|
} |
|
| |
{ |
if (n != other.size()) |
float tmp = 1.0; |
return false; |
assert(tmp == 1.0); |
|
printf("e2[%f]\n", tmp); |
|
} |
|
|
|
return fabs(double(x) - double(y)) < 0.00001; |
|
#else |
|
return x == y; |
|
#endif |
|
} |
|
| |
Boolean AcceptLanguageList::operator==( |
for (Uint32 i = 0; i < n; i++) |
const AcceptLanguageList& acceptLanguages) const |
|
{ | { |
if (_rep->languageTags.size() != acceptLanguages._rep->languageTags.size()) |
if (self[i].first != other[i].first || |
|
self[i].second != other[i].second) |
{ | { |
return false; | return false; |
} | } |
|
|
for (Uint32 i = 0; i < _rep->languageTags.size(); i++) |
|
{ |
|
if ((_rep->languageTags[i] != acceptLanguages._rep->languageTags[i])) |
|
return false; |
|
|
|
Real32 x1 = _rep->qualityValues[i]; |
|
Real32 x2 = acceptLanguages._rep->qualityValues[i]; |
|
|
|
if (!_equal(x1, x2)) |
|
return false; |
|
} | } |
|
|
return true; | return true; |
} | } |
| |
Boolean AcceptLanguageList::operator!=( |
Boolean AcceptLanguageList::operator!=(const AcceptLanguageList& x) const |
const AcceptLanguageList& acceptLanguages) const |
|
{ | { |
return !(*this == acceptLanguages); |
return !operator==(x); |
} | } |
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |