00001 /* 00002 * Copyright 1999-2004 The Apache Software Foundation. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #if !defined(XALANDOMSTRING_HEADER_GUARD_1357924680) 00017 #define XALANDOMSTRING_HEADER_GUARD_1357924680 00018 00019 00020 00021 #include <xalanc/XalanDOM/XalanDOMDefinitions.hpp> 00022 00023 00024 00025 #include <cassert> 00026 #include <vector> 00027 00028 00029 00030 #include <xalanc/XalanDOM/XalanDOMException.hpp> 00031 00032 00033 00034 XALAN_CPP_NAMESPACE_BEGIN 00035 00036 00037 00038 class XALAN_DOM_EXPORT XalanDOMString 00039 { 00040 public: 00041 00042 #if defined(XALAN_NO_STD_NAMESPACE) 00043 typedef vector<XalanDOMChar> XalanDOMCharVectorType; 00044 typedef vector<char> CharVectorType; 00045 typedef vector<wchar_t> WideCharVectorType; 00046 #else 00047 typedef std::vector<XalanDOMChar> XalanDOMCharVectorType; 00048 typedef std::vector<char> CharVectorType; 00049 typedef std::vector<wchar_t> WideCharVectorType; 00050 #endif 00051 00052 typedef XalanDOMChar value_type; 00053 typedef XalanDOMChar& reference; 00054 typedef const XalanDOMChar& const_reference; 00055 00056 typedef unsigned int size_type; 00057 00058 typedef XalanDOMCharVectorType::iterator iterator; 00059 typedef XalanDOMCharVectorType::const_iterator const_iterator; 00060 typedef XalanDOMCharVectorType::reverse_iterator reverse_iterator; 00061 typedef XalanDOMCharVectorType::const_reverse_iterator const_reverse_iterator; 00062 00063 #if defined(XALAN_INLINE_INITIALIZATION) 00064 static const size_type npos = ~0u; 00065 #else 00066 enum { npos = -1 }; 00067 #endif 00068 00069 explicit 00070 XalanDOMString(); 00071 00072 explicit 00073 XalanDOMString( 00074 const char* theString, 00075 size_type theCount = size_type(npos)); 00076 00077 XalanDOMString( 00078 const XalanDOMString& theSource, 00079 size_type theStartPosition = 0, 00080 size_type theCount = size_type(npos)); 00081 00082 explicit 00083 XalanDOMString( 00084 const XalanDOMChar* theString, 00085 size_type theCount = size_type(npos)); 00086 00087 XalanDOMString( 00088 size_type theCount, 00089 XalanDOMChar theChar); 00090 00091 ~XalanDOMString() 00092 { 00093 } 00094 00095 XalanDOMString& 00096 operator=(const XalanDOMString& theRHS) 00097 { 00098 return assign(theRHS); 00099 } 00100 00101 XalanDOMString& 00102 operator=(const XalanDOMChar* theRHS) 00103 { 00104 return assign(theRHS); 00105 } 00106 00107 XalanDOMString& 00108 operator=(const char* theRHS) 00109 { 00110 return assign(theRHS); 00111 } 00112 00113 XalanDOMString& 00114 operator=(XalanDOMChar theRHS) 00115 { 00116 return assign(1, theRHS); 00117 } 00118 00119 iterator 00120 begin() 00121 { 00122 invariants(); 00123 00124 return m_data.begin(); 00125 } 00126 00127 const_iterator 00128 begin() const 00129 { 00130 invariants(); 00131 00132 return m_data.begin(); 00133 } 00134 00135 iterator 00136 end() 00137 { 00138 invariants(); 00139 00140 return m_data.empty() == true ? m_data.end() : m_data.end() - 1; 00141 } 00142 00143 const_iterator 00144 end() const 00145 { 00146 invariants(); 00147 00148 return m_data.empty() == true ? m_data.end() : m_data.end() - 1; 00149 } 00150 00151 reverse_iterator 00152 rbegin() 00153 { 00154 invariants(); 00155 00156 reverse_iterator i = m_data.rbegin(); 00157 00158 if (m_data.empty() == false) 00159 { 00160 ++i; 00161 } 00162 00163 return i; 00164 } 00165 00166 const_reverse_iterator 00167 rbegin() const 00168 { 00169 invariants(); 00170 00171 const_reverse_iterator i = m_data.rbegin(); 00172 00173 if (m_data.empty() == false) 00174 { 00175 ++i; 00176 } 00177 00178 return i; 00179 } 00180 00181 reverse_iterator 00182 rend() 00183 { 00184 invariants(); 00185 00186 return m_data.rend(); 00187 } 00188 00189 const_reverse_iterator 00190 rend() const 00191 { 00192 invariants(); 00193 00194 return m_data.rend(); 00195 } 00196 00197 size_type 00198 size() const 00199 { 00200 invariants(); 00201 00202 return m_size; 00203 } 00204 00205 size_type 00206 length() const 00207 { 00208 invariants(); 00209 00210 return size(); 00211 } 00212 00213 size_type 00214 max_size() const 00215 { 00216 invariants(); 00217 00218 return ~size_type(0); 00219 } 00220 00221 void 00222 resize( 00223 size_type theCount, 00224 XalanDOMChar theChar); 00225 00226 void 00227 resize(size_type theCount) 00228 { 00229 invariants(); 00230 00231 resize(theCount, XalanDOMChar(0)); 00232 } 00233 00234 size_type 00235 capacity() const 00236 { 00237 invariants(); 00238 00239 return size_type(m_data.capacity()) - 1; 00240 } 00241 00242 void 00243 reserve(size_type theCount = 0) 00244 { 00245 invariants(); 00246 00247 m_data.reserve(theCount + 1); 00248 } 00249 00250 void 00251 clear() 00252 { 00253 invariants(); 00254 00255 m_data.erase(m_data.begin(), m_data.end()); 00256 00257 m_size = 0; 00258 00259 invariants(); 00260 } 00261 00262 void 00263 erase( 00264 size_type theStartPosition = 0, 00265 size_type theCount = size_type(npos)); 00266 00267 bool 00268 empty() const 00269 { 00270 invariants(); 00271 00272 return m_size == 0 ? true : false; 00273 } 00274 00275 const_reference 00276 operator[](size_type theIndex) const 00277 { 00278 invariants(); 00279 00280 return m_data[theIndex]; 00281 } 00282 00283 reference 00284 operator[](size_type theIndex) 00285 { 00286 invariants(); 00287 00288 return m_data[theIndex]; 00289 } 00290 00291 #if 0 00292 // $$$ ToDo: at() is not supported in the current version of GCC's vector<> 00293 // implementation. Eventually, it should be. 00294 const_reference 00295 at(size_type theIndex) const 00296 { 00297 invariants(); 00298 00299 return m_data.at(theIndex); 00300 } 00301 00302 reference 00303 at(size_type theIndex) 00304 { 00305 invariants(); 00306 00307 return m_data.at(theIndex); 00308 } 00309 #endif 00310 00311 const XalanDOMChar* 00312 c_str() const 00313 { 00314 invariants(); 00315 00316 return m_data.empty() == true ? &s_empty : &m_data[0]; 00317 } 00318 00319 const XalanDOMChar* 00320 data() const 00321 { 00322 invariants(); 00323 00324 return c_str(); 00325 } 00326 00327 void 00328 swap(XalanDOMString& theOther) 00329 { 00330 invariants(); 00331 00332 m_data.swap(theOther.m_data); 00333 00334 #if defined(XALAN_NO_STD_NAMESPACE) 00335 ::swap(m_size, theOther.m_size); 00336 #else 00337 std::swap(m_size, theOther.m_size); 00338 #endif 00339 } 00340 00341 XalanDOMString& 00342 operator+=(const XalanDOMString& theSource) 00343 { 00344 return append(theSource); 00345 } 00346 00347 XalanDOMString& 00348 operator+=(const XalanDOMChar* theString) 00349 { 00350 return append(theString); 00351 } 00352 00353 XalanDOMString& 00354 operator+=(XalanDOMChar theChar) 00355 { 00356 append(1, theChar); 00357 00358 return *this; 00359 } 00360 00361 XalanDOMString& 00362 assign(const XalanDOMChar* theSource) 00363 { 00364 invariants(); 00365 00366 erase(); 00367 00368 invariants(); 00369 00370 return append(theSource); 00371 } 00372 00373 XalanDOMString& 00374 assign( 00375 const XalanDOMChar* theSource, 00376 size_type theCount) 00377 { 00378 invariants(); 00379 00380 erase(); 00381 00382 invariants(); 00383 00384 return append(theSource, theCount); 00385 } 00386 00387 XalanDOMString& 00388 assign(const char* theSource) 00389 { 00390 invariants(); 00391 00392 erase(); 00393 00394 invariants(); 00395 00396 return append(theSource); 00397 } 00398 00399 XalanDOMString& 00400 assign( 00401 const char* theSource, 00402 size_type theCount) 00403 { 00404 invariants(); 00405 00406 erase(); 00407 00408 invariants(); 00409 00410 return append(theSource, theCount); 00411 } 00412 00413 XalanDOMString& 00414 assign( 00415 const XalanDOMString& theSource, 00416 size_type thePosition, 00417 size_type theCount); 00418 00419 XalanDOMString& 00420 assign(const XalanDOMString& theSource) 00421 { 00422 invariants(); 00423 00424 if (&theSource != this) 00425 { 00426 m_data = theSource.m_data; 00427 00428 m_size = theSource.m_size; 00429 } 00430 00431 invariants(); 00432 00433 return *this; 00434 } 00435 00436 XalanDOMString& 00437 assign( 00438 size_type theCount, 00439 XalanDOMChar theChar) 00440 { 00441 invariants(); 00442 00443 erase(); 00444 00445 invariants(); 00446 00447 return append(theCount, theChar); 00448 } 00449 00450 XalanDOMString& 00451 assign( 00452 const_iterator theFirstPosition, 00453 const_iterator theLastPosition); 00454 00455 XalanDOMString& 00456 append(const XalanDOMString& theSource) 00457 { 00458 return append(theSource.c_str(), theSource.length()); 00459 } 00460 00461 XalanDOMString& 00462 append( 00463 const XalanDOMString& theSource, 00464 size_type thePosition, 00465 size_type theCount) 00466 { 00467 assert(thePosition < theSource.length() && 00468 (theCount == size_type(npos) || thePosition + theCount <= theSource.length())); 00469 00470 return append(theSource.c_str() + thePosition, theCount); 00471 } 00472 00473 XalanDOMString& 00474 append( 00475 const XalanDOMChar* theString, 00476 size_type theCount); 00477 00478 XalanDOMString& 00479 append(const XalanDOMChar* theString) 00480 { 00481 return append(theString, length(theString)); 00482 } 00483 00484 XalanDOMString& 00485 append( 00486 const char* theString, 00487 size_type theCount); 00488 00489 XalanDOMString& 00490 append(const char* theString) 00491 { 00492 return append(theString, length(theString)); 00493 } 00494 00495 XalanDOMString& 00496 append( 00497 size_type theCount, 00498 XalanDOMChar theChar); 00499 00500 void 00501 push_back(XalanDOMChar theChar) 00502 { 00503 invariants(); 00504 00505 append(1, theChar); 00506 00507 invariants(); 00508 } 00509 00510 XalanDOMString& 00511 insert( 00512 size_type thePosition, 00513 const XalanDOMString& theString) 00514 { 00515 return insert(thePosition, theString.c_str(), theString.length()); 00516 } 00517 00518 XalanDOMString& 00519 insert( 00520 size_type thePosition1, 00521 const XalanDOMString& theString, 00522 size_type thePosition2, 00523 size_type theCount) 00524 { 00525 return insert(thePosition1, theString.c_str() + thePosition2, theCount); 00526 } 00527 00528 XalanDOMString& 00529 insert( 00530 size_type thePosition, 00531 const XalanDOMChar* theString, 00532 size_type theCount); 00533 00534 XalanDOMString& 00535 insert( 00536 size_type thePosition, 00537 const XalanDOMChar* theString) 00538 { 00539 return insert(thePosition, theString, length(theString)); 00540 } 00541 00542 XalanDOMString& 00543 insert( 00544 size_type thePosition, 00545 size_type theCount, 00546 XalanDOMChar theChar); 00547 00548 iterator 00549 insert( 00550 iterator thePosition, 00551 XalanDOMChar theChar); 00552 00553 void 00554 insert( 00555 iterator thePosition, 00556 size_type theCount, 00557 XalanDOMChar theChar); 00558 00559 void 00560 insert( 00561 iterator theInsertPosition, 00562 const_iterator theFirstPosition, 00563 const_iterator theLastPosition); 00564 00565 XalanDOMString 00566 substr( 00567 size_type thePosition = 0, 00568 size_type theCount = size_type(npos)) const 00569 { 00570 assert(theCount == size_type(npos) && thePosition < length() || 00571 thePosition + theCount <= length()); 00572 00573 invariants(); 00574 00575 return XalanDOMString(*this, thePosition, theCount); 00576 } 00577 00578 XalanDOMString& 00579 substr( 00580 XalanDOMString& theSubstring, 00581 size_type thePosition = 0, 00582 size_type theCount = size_type(npos)) const 00583 { 00584 assert(theCount == size_type(npos) && thePosition < length() || 00585 thePosition + theCount <= length()); 00586 00587 invariants(); 00588 00589 return theSubstring.assign(*this, thePosition, theCount); 00590 } 00591 00592 int 00593 compare(const XalanDOMString& theString) const 00594 { 00595 invariants(); 00596 00597 return compare(theString.c_str()); 00598 } 00599 00600 int 00601 compare( 00602 size_type thePosition1, 00603 size_type theCount1, 00604 const XalanDOMString& theString) const 00605 { 00606 invariants(); 00607 00608 return compare(thePosition1, theCount1, theString.c_str(), theString.length()); 00609 } 00610 00611 int 00612 compare( 00613 size_type thePosition1, 00614 size_type theCount1, 00615 const XalanDOMString& theString, 00616 size_type thePosition2, 00617 size_type theCount2) const 00618 { 00619 invariants(); 00620 00621 return compare(thePosition1, theCount1, theString.c_str() + thePosition2, theCount2); 00622 } 00623 00624 int 00625 compare(const XalanDOMChar* theString) const; 00626 00627 int 00628 compare( 00629 size_type thePosition1, 00630 size_type theCount1, 00631 const XalanDOMChar* theString, 00632 size_type theCount2 = size_type(npos)) const; 00633 00634 int 00635 compare(const char* theString) const 00636 { 00637 invariants(); 00638 00639 return compare(XalanDOMString(theString)); 00640 } 00641 00642 int 00643 compare( 00644 size_type thePosition1, 00645 size_type theCount1, 00646 const char* theString, 00647 size_type theCount2 = size_type(npos)) const 00648 { 00649 invariants(); 00650 00651 return compare(thePosition1, theCount1, XalanDOMString(theString, theCount2)); 00652 } 00653 00654 class TranscodingError : public XalanDOMException 00655 { 00656 public: 00657 00658 TranscodingError() : 00659 XalanDOMException(TRANSCODING_ERR) 00660 { 00661 } 00662 00663 virtual 00664 ~TranscodingError() 00665 { 00666 } 00667 }; 00668 00676 CharVectorType 00677 transcode() const; 00678 00686 void 00687 transcode(CharVectorType& theResult) const; 00688 00689 size_type 00690 hash() const 00691 { 00692 return hash(c_str(), size()); 00693 } 00694 00695 static bool 00696 equals( 00697 const XalanDOMChar* theLHS, 00698 size_type theLHSLength, 00699 const XalanDOMChar* theRHS, 00700 size_type theRHSLength); 00701 00702 static bool 00703 equals( 00704 const XalanDOMChar* theLHS, 00705 const XalanDOMChar* theRHS) 00706 { 00707 return equals(theLHS, length(theLHS), theRHS, length(theRHS)); 00708 } 00709 00710 static bool 00711 equals( 00712 const XalanDOMString& theLHS, 00713 const XalanDOMString& theRHS); 00714 00715 static bool 00716 equals( 00717 const XalanDOMString& theLHS, 00718 const XalanDOMChar* theRHS) 00719 { 00720 return equals(theLHS.c_str(), theRHS); 00721 } 00722 00723 static bool 00724 equals( 00725 const XalanDOMChar* theLHS, 00726 const XalanDOMString& theRHS) 00727 { 00728 return equals(theLHS, theRHS.c_str()); 00729 } 00730 00731 /* 00732 * Helper function to determine the length of a null- 00733 * terminated string. 00734 * 00735 * @theString The string 00736 * @return the length 00737 */ 00738 static size_type 00739 length(const XalanDOMChar* theString); 00740 00741 /* 00742 * Helper function to determine the length of a null- 00743 * terminated string. 00744 * 00745 * @theString The string 00746 * @return the length 00747 */ 00748 static size_type 00749 length(const char* theString); 00750 00751 static size_type 00752 hash( 00753 const XalanDOMChar* theString, 00754 size_type theLength); 00755 00756 protected: 00757 00758 /* 00759 * Function to assert invariant conditions for the class. 00760 * 00761 * @return the iterator 00762 */ 00763 void 00764 invariants() const 00765 { 00766 #if !defined(NDEBUG) 00767 assert((m_data.empty() == true && m_size == 0) || m_size == m_data.size() - 1); 00768 assert(m_data.empty() == true || m_data.back() == 0); 00769 #endif 00770 } 00771 00772 /* 00773 * Get an iterator to the position of the terminating null. 00774 * 00775 * @return the iterator 00776 */ 00777 iterator 00778 getBackInsertIterator() 00779 { 00780 invariants(); 00781 00782 return m_data.empty() == true ? m_data.end() : m_data.end() - 1; 00783 } 00784 00785 const_iterator 00786 getBackInsertIterator() const 00787 { 00788 invariants(); 00789 00790 return m_data.empty() == true ? m_data.end() : m_data.end() - 1; 00791 } 00792 00793 iterator 00794 getIteratorForPosition(size_type thePosition) 00795 { 00796 invariants(); 00797 00798 return m_data.begin() + thePosition; 00799 } 00800 00801 const_iterator 00802 getIteratorForPosition(size_type thePosition) const 00803 { 00804 invariants(); 00805 00806 return m_data.begin() + thePosition; 00807 } 00808 00809 private: 00810 00811 XalanDOMCharVectorType m_data; 00812 00813 size_type m_size; 00814 00815 static const XalanDOMChar s_empty; 00816 }; 00817 00818 00819 00820 inline bool 00821 operator==( 00822 const XalanDOMString& theLHS, 00823 const XalanDOMString& theRHS) 00824 { 00825 return XalanDOMString::equals(theLHS, theRHS); 00826 } 00827 00828 00829 00830 inline bool 00831 operator==( 00832 const XalanDOMString& theLHS, 00833 const XalanDOMChar* theRHS) 00834 { 00835 return XalanDOMString::equals(theLHS, theRHS); 00836 } 00837 00838 00839 00840 inline bool 00841 operator==( 00842 const XalanDOMChar* theLHS, 00843 const XalanDOMString& theRHS) 00844 { 00845 // Note reversing of operands... 00846 return XalanDOMString::equals(theLHS, theRHS); 00847 } 00848 00849 00850 00851 inline bool 00852 operator!=( 00853 const XalanDOMString& theLHS, 00854 const XalanDOMString& theRHS) 00855 { 00856 return !(theLHS == theRHS); 00857 } 00858 00859 00860 00861 inline bool 00862 operator!=( 00863 const XalanDOMChar* theLHS, 00864 const XalanDOMString& theRHS) 00865 { 00866 return !(theLHS == theRHS); 00867 } 00868 00869 00870 00871 inline bool 00872 operator!=( 00873 const XalanDOMString& theLHS, 00874 const XalanDOMChar* theRHS) 00875 { 00876 return !(theRHS == theLHS); 00877 } 00878 00879 00880 00881 inline XalanDOMString 00882 operator+( 00883 const XalanDOMString& theLHS, 00884 const XalanDOMString& theRHS) 00885 { 00886 XalanDOMString theTemp(theLHS); 00887 00888 return theTemp += theRHS; 00889 } 00890 00891 00892 00893 inline XalanDOMString 00894 operator+( 00895 const XalanDOMString& theLHS, 00896 const XalanDOMChar* theRHS) 00897 { 00898 XalanDOMString theTemp(theLHS); 00899 00900 return theTemp += theRHS; 00901 } 00902 00903 00904 00905 inline XalanDOMString 00906 operator+( 00907 const XalanDOMChar* theLHS, 00908 const XalanDOMString& theRHS) 00909 { 00910 XalanDOMString theTemp(theLHS); 00911 00912 return theTemp += theRHS; 00913 } 00914 00915 00916 00917 inline const XalanDOMString 00918 operator+( 00919 const char* theLHS, 00920 const XalanDOMString& theRHS) 00921 { 00922 return XalanDOMString(theLHS) + theRHS; 00923 } 00924 00925 00926 00927 inline const XalanDOMString 00928 operator+( 00929 const XalanDOMString& theLHS, 00930 const char* theRHS) 00931 { 00932 return theLHS + XalanDOMString(theRHS); 00933 } 00934 00935 00936 00937 // Standard vector of XalanDOMChars and chars 00938 #if defined(XALAN_NO_STD_NAMESPACE) 00939 typedef vector<XalanDOMChar> XalanDOMCharVectorType; 00940 00941 typedef vector<char> CharVectorType; 00942 #else 00943 typedef std::vector<XalanDOMChar> XalanDOMCharVectorType; 00944 00945 typedef std::vector<char> CharVectorType; 00946 #endif 00947 00948 00949 00961 XALAN_DOM_EXPORT_FUNCTION(bool) 00962 TranscodeToLocalCodePage( 00963 const XalanDOMChar* theSourceString, 00964 XalanDOMString::size_type theSourceStringLength, 00965 CharVectorType& targetVector, 00966 bool terminate = false); 00967 00968 00969 00980 XALAN_DOM_EXPORT_FUNCTION(bool) 00981 TranscodeToLocalCodePage( 00982 const XalanDOMChar* theSourceString, 00983 CharVectorType& targetVector, 00984 bool terminate = false); 00985 00986 00987 00996 inline const CharVectorType 00997 TranscodeToLocalCodePage(const XalanDOMChar* theSourceString) 00998 { 00999 CharVectorType theResult; 01000 01001 TranscodeToLocalCodePage(theSourceString, theResult, true); 01002 01003 return theResult; 01004 } 01005 01006 01007 01017 inline bool 01018 TranscodeToLocalCodePage( 01019 const XalanDOMString& theSourceString, 01020 CharVectorType& targetVector, 01021 bool terminate = false) 01022 { 01023 return TranscodeToLocalCodePage(theSourceString.c_str(), targetVector, terminate); 01024 } 01025 01026 01027 01036 inline const CharVectorType 01037 TranscodeToLocalCodePage(const XalanDOMString& theSourceString) 01038 { 01039 CharVectorType theResult; 01040 01041 TranscodeToLocalCodePage(theSourceString, theResult, true); 01042 01043 return theResult; 01044 } 01045 01046 01047 01056 inline const XalanDOMString 01057 TranscodeFromLocalCodePage( 01058 const char* theSourceString, 01059 XalanDOMString::size_type theSourceStringLength = XalanDOMString::npos) 01060 { 01061 return XalanDOMString(theSourceString, theSourceStringLength); 01062 } 01063 01064 01065 01077 XALAN_DOM_EXPORT_FUNCTION(bool) 01078 TranscodeFromLocalCodePage( 01079 const char* theSourceString, 01080 XalanDOMString::size_type theSourceStringLength, 01081 XalanDOMCharVectorType& theTargetVector, 01082 bool terminate = false); 01083 01084 01085 01096 XALAN_DOM_EXPORT_FUNCTION(bool) 01097 TranscodeFromLocalCodePage( 01098 const char* theSourceString, 01099 XalanDOMCharVectorType& theTargetVector, 01100 bool terminate = false); 01101 01102 01103 01111 XALAN_DOM_EXPORT_FUNCTION(const XalanDOMString) 01112 TranscodeFromLocalCodePage(const CharVectorType& theSourceString); 01113 01114 01115 01116 XALAN_CPP_NAMESPACE_END 01117 01118 01119 01120 #endif // !defined(XALANDOMSTRING_HEADER_GUARD_1357924680)
Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.
![]() |
Xalan-C++ XSLT Processor Version 1.8 |
|