#ifndef __tweb_util__ #define __tweb_util__ bool IsSameTextFile(const char *p, const char *q); String StringSample(const char *s, int limit); String FormatIP(dword _ip); String UrlEncode(String s); String UrlEncode(String s, const char *specials); String UrlDecode(String s); String GetRandomIdent(int length); String OtpEncode(String password, String otp_key); String EncryptString(String password, String otp_key); String BinHexEncode(const char *b, const char *e); inline String BinHexEncode(String data) { return BinHexEncode(data.Begin(), data.End()); } String BinHexDecode(const char *b, const char *e); inline String BinHexDecode(String data) { return BinHexDecode(data.Begin(), data.End()); } String Base64Encode(const char *b, const char *e); inline String Base64Encode(String data) { return Base64Encode(data.Begin(), data.End()); } String Base64Decode(const char *b, const char *e); inline String Base64Decode(String data) { return Base64Decode(data.Begin(), data.End()); } String ASCII85Encode(const byte *p, int length); inline String ASCII85Encode(String s) { return ASCII85Encode(s, s.GetLength()); } String ASCII85Decode(const byte *p, int length); inline String ASCII85Decode(String s) { return ASCII85Decode(s, s.GetLength()); } dword AddCRC(dword crc, const byte *data, int count); inline dword AddCRC(dword crc, String s) { return AddCRC(crc, s, s.GetLength()); } inline dword GetCRC(const byte *data, int count) { return AddCRC(0x80000000, data, count); } inline dword GetCRC(String s) { return AddCRC(0x80000000, s, s.GetLength()); } int LocateLine(String old_file, int old_line, String new_file); void AppVersion(const char *ver); String MD5Digest(const char *text, int length); inline String MD5Digest(String s) { return MD5Digest(s.Begin(), s.GetLength()); } #define WID(s) static const String COMBINE(WID_, s)(#s); class RefBase { public: RefBase() { refcount = 0; #ifdef REF_DEBUG allocindex = ++nextindex; #endif//REF_DEBUG } RefBase(const RefBase& rb) { refcount = 0; #ifdef REF_DEBUG allocindex = ++nextindex; #endif//REF_DEBUG } virtual ~RefBase() { ASSERT(refcount == 0); } void AddRef() const { if(this) AtomicInc(refcount); } int GetRefCount() const { return AtomicXAdd(refcount, 0); } void Release() const { if(this && !AtomicDec(refcount)) delete this; } #ifdef REF_DEBUG int GetAllocIndex() const { return allocindex; } #endif//REF_DEBUG private: mutable Atomic refcount; #ifdef REF_DEBUG int allocindex; static int nextindex; #endif//REF_DEBUG private: RefBase& operator = (const RefBase& rb) { NEVER(); return *this; } }; template class RefCon : Moveable< RefCon > { public: RefCon(const Nuller& = Null) : t(0) {} RefCon(const T *t); RefCon(const RefCon& rp); ~RefCon(); void Clear() { if(t) { t->Release(); t = NULL; } } bool IsNullInstance() const { return !t; } RefCon& operator = (const RefCon& rp); bool operator ! () const { return !t; } const T *Get() const { return t; } const T *operator ~ () const { return t; } const T *operator -> () const { ASSERT(t); return t; } const T& operator * () const { ASSERT(t); return *t; } String ToString() const { return t ? AsString(*t) : String("NULL"); } friend bool operator == (RefCon a, RefCon b) { return a.t == b.t; } friend bool operator != (RefCon a, RefCon b) { return a.t != b.t; } friend unsigned GetHashValue(RefCon r) { return GetHashValue(r.t); } protected: const T *t; }; template RefCon::RefCon(const T *t) : t(t) { t->AddRef(); #ifdef REF_DEBUG if(t && t->GetRefCount() == 1) RefMemStat::App().Add(typeid(*t).name(), t->GetAllocIndex()); #endif//REF_DEBUG } template RefCon::RefCon(const RefCon& rp) : t(rp.t) { t->AddRef(); } template RefCon::~RefCon() { #ifdef REF_DEBUG if(t && t->GetRefCount() == 1) RefMemStat::App().Remove(typeid(*t).name(), t->GetAllocIndex()); #endif//REF_DEBUG t->Release(); } template RefCon& RefCon::operator = (const RefCon& rp) { const T *old = t; t = rp.t; t->AddRef(); #ifdef REF_DEBUG if(old && old->GetRefCount() == 1) RefMemStat::App().Remove(typeid(*old).name(), old->GetAllocIndex()); #endif//REF_DEBUG old->Release(); return *this; } template class RefPtr : public RefCon, public Moveable< RefPtr > { public: RefPtr(const Nuller& = Null) {} RefPtr(T *t) : RefCon(t) {} RefPtr(const RefPtr& rp) : RefCon(rp) {} RefPtr& operator = (const RefPtr& rp) { RefCon::operator = (rp); return *this; } T *Get() const { return const_cast(this->t); } T *operator ~ () const { return Get(); } T *operator -> () const { ASSERT(this->t); return Get(); } T& operator * () const { ASSERT(this->t); return *Get(); } }; template class RefValueRep : public RawValueRep { public: RefValueRep(T v) : RawValueRep(v) {} virtual bool IsNull() const { return this->v == 0; } virtual unsigned GetHashValue() const { return (unsigned)~this->v; } virtual bool IsEqual(const Value::Void *p); virtual String AsString() { return !!this->v ? UPP::AsString(*this->v) : String(Null); } static const RawValueRep *Cast(const Value::Void *p) { ASSERT(dynamic_cast *>(p)); return (const RawValueRep *)p; } }; template bool RefValueRep::IsEqual(const Value::Void *p) { const RawValueRep *cast = dynamic_cast *>(p); return cast && cast->Get() == this->v; } template class RefPCValue : public Value { protected: typedef RefValueRep Rep; public: RefPCValue(T x) : Value(new Rep(x)) {} static T Get(const Value& v) { return UPP::IsNull(v) ? 0 : Rep::Cast(v.GetVoidPtr())->Get(); } static T Extract(const Value& v) { return UPP::IsNull(v) ? 0 : Rep::Cast(v.GetVoidPtr())->Get(); } }; template inline Value RefConToValue(RefCon p) { return RefPCValue< RefCon >(p); } template inline Value RefPtrToValue(RefPtr p) { return RefPCValue< RefPtr >(p); } class HttpQuery { private: class Data : public RefBase { public: Data() {} Data(const Data& d) : map(d.map, 0) {} VectorMap map; }; public: HttpQuery(const Nuller& = Null) : data(Empty()) {} explicit HttpQuery(String url) { data = Empty(); SetURL(url); } void Serialize(Stream& stream); String GetHidden() const; String GetQuery(bool empty = false) const; String GetQuery(HttpQuery patch, bool empty = false) const; void Clear() { data = Empty(); } bool IsEmpty() const { return data -> map.IsEmpty(); } bool IsEmpty(String key) const; int GetCount() const { return data -> map.GetCount(); } int Find(String key) const { return data -> map.Find(key); } String GetKey(int i) const { return data -> map.GetKey(i); } String GetValue(int i) const { return data -> map[i]; } bool IsInternal(int i) const; void Get(String key, Ref p1) const; HttpQuery& SetValue(String key, Value v); HttpQuery& Set(String key, String value); HttpQuery& SetRaw(String key, String value); bool GetBool(String key) const; bool GetBool(String key, bool dflt) const; HttpQuery& SetBool(String key, bool b); int GetInt(String key) const; int GetInt(String key, int min, int max, int dflt = 0) const; HttpQuery& SetInt(String key, int i); double GetDouble(String key) const; double GetDouble(String key, double min, double max, double dflt = Null) const; HttpQuery& SetDouble(String key, double f); String GetString(String key) const; String GetString(String key, String dflt) const; HttpQuery& SetString(String key, String s) { return Set(key, s); } Date GetDate(String key) const; Date GetDate(String key, Date dflt) const { return Nvl(GetDate(key), dflt); } HttpQuery& SetDate(String key, Date d); Time GetTime(String key) const; Time GetTime(String key, Time dflt) const { return Nvl(GetTime(key), dflt); } HttpQuery& SetTime(String key, Time t); Color GetColor(String key) const; Color GetColor(String key, Color dflt) const { return Nvl(GetColor(key), dflt); } HttpQuery& SetColor(String key, Color c); HttpQuery& Set(HttpQuery query); HttpQuery& SetURL(String url); HttpQuery& Remove(String key); HttpQuery& Remove(const Vector& keys); HttpQuery& Remove(const Vector& keys); String ToString() const; private: static RefPtr Empty(); void Clone() { if(data -> GetRefCount() > 1) data = new Data(*data); } private: RefPtr data; }; #endif//__tweb_util__