00001 #ifndef __J2K__JString_Data_HPP__ 00002 #define __J2K__JString_Data_HPP__ 00003 00004 #include <j2k/Fred/Basic.hpp> 00005 #include <j2k/Fred/Boolean.hpp> 00006 #include <j2k/Fred/StdTypes.hpp> 00007 00008 //////////////////////////////////////////////////////////////////////////// 00009 /// always allocate one extra character for '\0' termination assumes /// 00010 /// [optimistically] that data length will equal allocation length /// 00011 //////////////////////////////////////////////////////////////////////////// 00012 /// Something like 4 GigaBytes... /// 00013 //////////////////////////////////////////////////////////////////////////// 00014 #define JString_MAX ( sizeof(size_t) ) 00015 00016 /** ANDREA *************************************************** 00017 00018 What do you think sizeof(size_t) will return ? Fortunately 00019 you never used that #defined symbol anywhere. 00020 00021 This is for portability, some system might use long or long long or ... 00022 00023 *************************************************************/ 00024 00025 class JStringData { 00026 public: 00027 size_t bufferSize; // Allocated Buffer Size 00028 size_t length; // Length of Data 00029 long nbRefs; // Reference Counter 00030 int lock; // Lock, if direct access (CJString compatibility) 00031 char* data; 00032 00033 /* Kept public for easy access by JString 00034 A more secure Friend Class definition might do it better. */ 00035 00036 //////////////////////////////////////////////////////////////////////////// 00037 /// Constructor, Copy Constructor and Destructor /// 00038 //////////////////////////////////////////////////////////////////////////// 00039 inline JStringData(); 00040 inline JStringData( const char* s ); 00041 inline JStringData( const char* s, size_t nBuffer ); 00042 inline JStringData( const JStringData& sd ); 00043 inline JStringData( size_t nBuffer ); 00044 inline JStringData( char fill, size_t nRepeat ); 00045 inline JStringData( char fill, size_t nRepeat, size_t nBuffer ); 00046 inline virtual ~JStringData(); 00047 00048 //////////////////////////////////////////////////////////////////////////// 00049 /// Utility functions /// 00050 //////////////////////////////////////////////////////////////////////////// 00051 inline void Dec(); // NOTICE: Dec() is a Suicidal function ! 00052 inline void Inc(); 00053 00054 // Might become private... 00055 void Init( const char* s, size_t nBuffer ); 00056 void InitBuffer( size_t nBuffer, char fill ); 00057 void Clear( char fill ); 00058 00059 private: 00060 // Might become public ? 00061 const JStringData& operator=(const JStringData& sd); 00062 00063 public: 00064 // Global Null JStringData Object 00065 // I hate this, but it's the only optimize way of doing this ! 00066 // I tried without and the testing of pdata == NULL are awful ! 00067 static JStringData* strNull() 00068 { 00069 static JStringData s; 00070 return &s; 00071 } 00072 }; 00073 00074 #define strNull JStringData::strNull() 00075 00076 // Global Null JStringData Object 00077 // I hate this, but it's the only optimize way of doing this ! 00078 // I tried without and the testing of pdata == NULL are awful ! 00079 // JStringData strNull; 00080 00081 /** ANDREA *************************************************** 00082 00083 You are defining this global variable in an include file. 00084 This means that every compilation unit using the library 00085 will have its own strNull object and, if you're lucky, 00086 the linker will complain. 00087 Can you handle several different strNull objects lying 00088 around ? 00089 00090 That was a problem, that's why String.cpp is included inorder 00091 else we get many JStringData 00092 00093 There are several solution for this problem, the simplest 00094 being using a static member function 00095 00096 static JStringData *strNull() 00097 { 00098 static JStringData s; 00099 return &s; 00100 } 00101 00102 Well, that's an implementation I saw in a String class on Linux, 00103 in the 1st place, I didn't have that global variable, 00104 but I had to check for NULL so often that it was too messy. 00105 With this one, it's much more easier and faster ! 00106 00107 I will probably used "extern" keyword, so it doesn't screw up. 00108 00109 October 2000: 00110 00111 I used your trick, it's seems to be a good idea, 00112 to avoid headache ! Thanks! 00113 00114 Fred 00115 00116 *************************************************************/ 00117 00118 #endif