0027838: Foundation Classes - support wchar_t* input within TCollection_AsciiString... IR-2016-09-15
authorkgv <kgv@opencascade.com>
Sun, 4 Sep 2016 11:31:47 +0000 (14:31 +0300)
committerkgv <kgv@opencascade.com>
Thu, 15 Sep 2016 09:33:55 +0000 (12:33 +0300)
TCollection_ExtendedString/TCollection_AsciiString description
has been updated to reflect usage of this classes for Unicode strings.

TCollection_ExtendedString now defines constructor taking wchar_t* (all platforms)
and method ::ToWideString() returning wchar_t* (Windows only).
TCollection_AsciiString now defines constructor taking wchar_t*.

TCollection_ExtendedString/TCollection_AsciiString now defines
auxiliary methods ::StartsWith() and ::EndsWith().

TCollection_ExtendedString internals has been updated to eliminate
duplicated code for converting between UTF-16 and UTF-8.

Code has been cleaned up from redundant explicit conversions to wchar_t*.
Global method OSD_OpenStream()/OSD_OpenFileBuf() have been replaced
by C++ template to eliminate copy-paste for different STL collections.

OSD_SharedLibrary now uses wide-char system API call LoadLibraryExW()
on Windows for consistency.

New macro Standard_UNUSED has been added for marking possibly unused functions and variables
(to suppress gcc/clang compiler warnings).

33 files changed:
src/AIS/AIS_Dimension.cxx
src/AIS/AIS_TextLabel.cxx
src/BRepTools/BRepTools.cxx
src/BinTools/BinTools.cxx
src/Draw/Draw_VariableCommands.cxx
src/FSD/FSD_CmpFile.cxx
src/FSD/FSD_File.cxx
src/Graphic3d/Graphic3d_Group.cxx
src/Image/Image_AlienPixMap.cxx
src/NCollection/NCollection_UtfIterator.hxx
src/NCollection/NCollection_UtfIterator.lxx
src/NCollection/NCollection_UtfString.hxx
src/NCollection/NCollection_UtfString.lxx
src/OSD/OSD_Directory.cxx
src/OSD/OSD_DirectoryIterator.cxx
src/OSD/OSD_Disk.cxx
src/OSD/OSD_File.cxx
src/OSD/OSD_FileIterator.cxx
src/OSD/OSD_FileNode.cxx
src/OSD/OSD_OpenFile.cxx
src/OSD/OSD_OpenFile.hxx
src/OSD/OSD_Process.cxx
src/OSD/OSD_SharedLibrary.cxx
src/OpenGl/OpenGl_GraphicDriver.cxx
src/OpenGl/OpenGl_Text.cxx
src/Standard/Standard.cxx
src/Standard/Standard_Macro.hxx
src/TCollection/FILES
src/TCollection/TCollection_AsciiString.cxx
src/TCollection/TCollection_AsciiString.hxx
src/TCollection/TCollection_ExtendedString.cxx
src/TCollection/TCollection_ExtendedString.hxx
src/TCollection/TCollection_ExtendedString.lxx [deleted file]

index a9fd50d..dbf50de 100755 (executable)
@@ -294,7 +294,7 @@ TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidt
 
   // Get text style parameters
   Handle(Prs3d_TextAspect) aTextAspect = myDrawer->DimensionAspect()->TextAspect();
-  NCollection_Utf8String anUTFString = (Standard_Utf16Char* )aValueStr.ToExtString();
+  NCollection_Utf8String anUTFString (aValueStr.ToExtString());
 
   theWidth = 0.0;
 
@@ -408,7 +408,7 @@ void AIS_Dimension::drawText (const Handle(Prs3d_Presentation)& thePresentation,
     // creating TopoDS_Shape for text
     Font_BRepFont aFont (aTextAspect->Aspect()->Font().ToCString(),
                          aFontAspect, aFontHeight);
-    NCollection_Utf8String anUTFString = (Standard_Utf16Char* )theText.ToExtString();
+    NCollection_Utf8String anUTFString (theText.ToExtString());
 
     Font_BRepTextBuilder aBuilder;
     TopoDS_Shape aTextShape = aBuilder.Perform (aFont, anUTFString);
index 6033cc0..9066b18 100644 (file)
@@ -261,7 +261,7 @@ void AIS_TextLabel::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePr
                           anAsp->Aspect()->GetTextFontAspect(), (unsigned int)anAsp->Height(), aResolution))
           {
             isInit = Standard_True;
-            const NCollection_String aText ((Standard_Utf16Char* )myText.ToExtString());
+            const NCollection_String aText (myText.ToExtString());
             Font_Rect aBndBox = aFont.BoundingBox (aText, anAsp->HorizontalJustification(), anAsp->VerticalJustification());
             Standard_Real aWidth = Abs (aBndBox.Width());
             Standard_Real aHeight = Abs (aBndBox.Height());
index 96e83c0..ae2cb9d 100644 (file)
@@ -826,7 +826,7 @@ Standard_Boolean BRepTools::Read(TopoDS_Shape& Sh,
 {
   filebuf fic;
   istream in(&fic);
-  OSD_OpenFileBuf(fic,File,ios::in);
+  OSD_OpenStream (fic, File, ios::in);
   if(!fic.is_open()) return Standard_False;
   
   BRepTools_ShapeSet SS(B);
index 8a6ed5a..e44cf8f 100644 (file)
@@ -184,7 +184,7 @@ Standard_Boolean BinTools::Write (const TopoDS_Shape& theShape, const Standard_C
 Standard_Boolean BinTools::Read (TopoDS_Shape& theShape, const Standard_CString theFile)
 {
   filebuf aBuf;
-  OSD_OpenFileBuf (aBuf, theFile, ios::in | ios::binary);
+  OSD_OpenStream (aBuf, theFile, ios::in | ios::binary);
   if (!aBuf.is_open())
     return Standard_False;
 
index 59e01f7..2ae9437 100644 (file)
@@ -212,7 +212,7 @@ static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const
   
   filebuf fic;
   istream in(&fic);
-  OSD_OpenFileBuf(fic,fname,ios::in);
+  OSD_OpenStream (fic, fname, ios::in);
   if (!fic.is_open()) {
     di << "Cannot open file for reading : "<<fname;
     return 1;
index eb0fd57..1378512 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <FSD_CmpFile.hxx>
+
 #include <OSD.hxx>
+#include <OSD_OpenFile.hxx>
 #include <Standard_PCharacter.hxx>
 #include <Storage_BaseDriver.hxx>
 #include <Storage_StreamExtCharParityError.hxx>
@@ -79,40 +80,46 @@ Storage_Error FSD_CmpFile::Open(const TCollection_AsciiString& aName,const Stora
   SetName(aName);
 
   if (OpenMode() == Storage_VSNone) {
-
-#if defined(_WNT32)
-    TCollection_ExtendedString aWName(aName);
-    if (aMode == Storage_VSRead) {
-      myStream.open((const wchar_t*)aWName.ToExtString(),ios::in|ios::binary); // ios::nocreate is not portable
-    }
-    else if (aMode == Storage_VSWrite) {
-      myStream.open((const wchar_t*)aWName.ToExtString(),ios::out|ios::binary);
-    }
-    else if (aMode == Storage_VSReadWrite) {
-      myStream.open((const wchar_t*)aWName.ToExtString(),ios::in|ios::out|ios::binary);
-    }
-#elif !defined(IRIX) && !defined(DECOSF1)
-    if (aMode == Storage_VSRead) {
-      myStream.open(aName.ToCString(),ios::in|ios::binary); // ios::nocreate is not portable
+    std::ios_base::openmode anOpenMode = std::ios_base::openmode(0);
+    switch (aMode)
+    {
+      case Storage_VSNone:
+      {
+        break;
+      }
+      case Storage_VSRead:
+      {
+        // ios::nocreate is not portable
+      #if !defined(IRIX) && !defined(DECOSF1)
+        anOpenMode = ios::in | ios::binary;
+      #else
+        anOpenMode = ios::in;
+      #endif
+        break;
+      }
+      case Storage_VSWrite:
+      {
+      #if !defined(IRIX) && !defined(DECOSF1)
+        anOpenMode = ios::out | ios::binary;
+      #else
+        anOpenMode = ios::out;
+      #endif
+        break;
+      }
+      case Storage_VSReadWrite:
+      {
+      #if !defined(IRIX) && !defined(DECOSF1)
+        anOpenMode = ios::in | ios::out | ios::binary;
+      #else
+        anOpenMode = ios::in | ios::out;
+      #endif
+        break;
+      }
     }
-    else if (aMode == Storage_VSWrite) {
-      myStream.open(aName.ToCString(),ios::out|ios::binary);
+    if (anOpenMode != 0)
+    {
+      OSD_OpenStream (myStream, aName, anOpenMode);
     }
-    else if (aMode == Storage_VSReadWrite) {
-      myStream.open(aName.ToCString(),ios::in|ios::out|ios::binary);
-    }
-#else
-    if (aMode == Storage_VSRead) {
-      myStream.open(aName.ToCString(),ios::in); // ios::nocreate is not portable
-    }
-    else if (aMode == Storage_VSWrite) {
-      myStream.open(aName.ToCString(),ios::out);
-    }
-    else if (aMode == Storage_VSReadWrite) {
-      myStream.open(aName.ToCString(),ios::in|ios::out);
-    }
-#endif
-
     if (myStream.fail()) {
       result = Storage_VSOpenError;
     }
index 9fb391e..6a01450 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-
 #include <FSD_File.hxx>
+
 #include <OSD.hxx>
+#include <OSD_OpenFile.hxx>
 #include <Storage_BaseDriver.hxx>
 #include <Storage_StreamExtCharParityError.hxx>
 #include <Storage_StreamFormatError.hxx>
@@ -79,30 +80,36 @@ Storage_Error FSD_File::Open(const TCollection_AsciiString& aName,const Storage_
 
   SetName(aName);
 
-  if (OpenMode() == Storage_VSNone) {
-
-#if defined(_MSC_VER)
-    TCollection_ExtendedString aWName(aName);
-    if (aMode == Storage_VSRead) {
-      myStream.open( (const wchar_t*) aWName.ToExtString(),ios::in); // ios::nocreate is not portable
-    }
-    else if (aMode == Storage_VSWrite) {
-      myStream.open( (const wchar_t*) aWName.ToExtString(),ios::out);
-    }
-    else if (aMode == Storage_VSReadWrite) {
-      myStream.open( (const wchar_t*) aWName.ToExtString(),ios::in|ios::out);
-#else
-    if (aMode == Storage_VSRead) {
-      myStream.open(aName.ToCString(),ios::in); // ios::nocreate is not portable
-    }
-    else if (aMode == Storage_VSWrite) {
-      myStream.open(aName.ToCString(),ios::out);
+  if (OpenMode() == Storage_VSNone)
+  {
+    std::ios_base::openmode anOpenMode = std::ios_base::openmode(0);
+    switch (aMode)
+    {
+      case Storage_VSNone:
+      {
+        break;
+      }
+      case Storage_VSRead:
+      {
+        // ios::nocreate is not portable
+        anOpenMode = ios::in;
+        break;
+      }
+      case Storage_VSWrite:
+      {
+        anOpenMode = ios::out;
+        break;
+      }
+      case Storage_VSReadWrite:
+      {
+        anOpenMode = ios::in | ios::out;
+        break;
+      }
     }
-    else if (aMode == Storage_VSReadWrite) {
-      myStream.open(aName.ToCString(),ios::in|ios::out);
-#endif
+    if (anOpenMode != 0)
+    {
+      OSD_OpenStream (myStream, aName.ToCString(), anOpenMode);
     }
-    
     if (myStream.fail()) {
       result = Storage_VSOpenError;
     }
index 0bb8b1d..0eedb2d 100644 (file)
@@ -425,7 +425,7 @@ void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
                             const Graphic3d_VerticalTextAlignment   theVta,
                             const Standard_Boolean                  theToEvalMinMax)
 {
-  const NCollection_String aText ((Standard_Utf16Char* )theText.ToExtString());
+  const NCollection_String aText (theText.ToExtString());
   Text (aText.ToCString(), thePoint, theHeight, theAngle,
         theTp, theHta, theVta, theToEvalMinMax);
 }
@@ -444,7 +444,7 @@ void Graphic3d_Group::Text (const TCollection_ExtendedString&       theText,
                             const Standard_Boolean                  theToEvalMinMax,
                             const Standard_Boolean                  theHasOwnAnchor)
 {
-  const NCollection_String aText ((Standard_Utf16Char*)(theText.ToExtString()));
+  const NCollection_String aText (theText.ToExtString());
   Text (aText.ToCString(),
         theOrientation,
         theHeight,
@@ -495,7 +495,7 @@ void Graphic3d_Group::Text (const TCollection_ExtendedString& theText,
                             const Standard_Real               theHeight,
                             const Standard_Boolean            theToEvalMinMax)
 {
-  const NCollection_String aText ((Standard_Utf16Char* )theText.ToExtString());
+  const NCollection_String aText (theText.ToExtString());
   Text (aText.ToCString(), thePoint, theHeight, 0.0,
         Graphic3d_TP_RIGHT, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM, theToEvalMinMax);
 }
index 42c1c1d..ac0495f 100644 (file)
@@ -253,7 +253,7 @@ bool Image_AlienPixMap::Load (const TCollection_AsciiString& theImagePath)
 
 #ifdef _WIN32
   const TCollection_ExtendedString aFileNameW (theImagePath.ToCString(), Standard_True);
-  FREE_IMAGE_FORMAT aFIF = FreeImage_GetFileTypeU ((const wchar_t* )aFileNameW.ToExtString(), 0);
+  FREE_IMAGE_FORMAT aFIF = FreeImage_GetFileTypeU (aFileNameW.ToWideString(), 0);
 #else
   FREE_IMAGE_FORMAT aFIF = FreeImage_GetFileType (theImagePath.ToCString(), 0);
 #endif
@@ -284,7 +284,7 @@ bool Image_AlienPixMap::Load (const TCollection_AsciiString& theImagePath)
   }
 
 #ifdef _WIN32
-  FIBITMAP* anImage = FreeImage_LoadU (aFIF, (const wchar_t* )aFileNameW.ToExtString(), aLoadFlags);
+  FIBITMAP* anImage = FreeImage_LoadU (aFIF, aFileNameW.ToWideString(), aLoadFlags);
 #else
   FIBITMAP* anImage = FreeImage_Load  (aFIF, theImagePath.ToCString(), aLoadFlags);
 #endif
@@ -383,7 +383,7 @@ bool Image_AlienPixMap::Save (const TCollection_AsciiString& theFileName)
 
 #ifdef _WIN32
   const TCollection_ExtendedString aFileNameW (theFileName.ToCString(), Standard_True);
-  FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilenameU ((const wchar_t* )aFileNameW.ToExtString());
+  FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilenameU (aFileNameW.ToWideString());
 #else
   FREE_IMAGE_FORMAT anImageFormat = FreeImage_GetFIFFromFilename (theFileName.ToCString());
 #endif
@@ -519,7 +519,7 @@ bool Image_AlienPixMap::Save (const TCollection_AsciiString& theFileName)
   }
 
 #ifdef _WIN32
-  bool isSaved = (FreeImage_SaveU (anImageFormat, anImageToDump, (const wchar_t* )aFileNameW.ToExtString()) != FALSE);
+  bool isSaved = (FreeImage_SaveU (anImageFormat, anImageToDump, aFileNameW.ToWideString()) != FALSE);
 #else
   bool isSaved = (FreeImage_Save  (anImageFormat, anImageToDump, theFileName.ToCString()) != FALSE);
 #endif
index 1923e14..20ec3d6 100755 (executable)
@@ -88,6 +88,12 @@ public:
     return myPosition == theRight.myPosition;
   }
 
+  //! Return true if Unicode symbol is within valid range.
+  bool IsValid() const
+  {
+    return myCharUtf32 <= UTF32_MAX_LEGAL;
+  }
+
   //! Dereference operator.
   //! @return the UTF-32 codepoint of the character currently pointed by iterator.
   Standard_Utf32Char operator*() const
@@ -121,6 +127,12 @@ public:
   //! 4 bytes for surrogate pair.
   Standard_Integer AdvanceBytesUtf16() const;
 
+  //! @return the advance in bytes to store current symbol in UTF-16.
+  //! 0 means an invalid symbol;
+  //! 1 16-bit code unit is a general case;
+  //! 2 16-bit code units for surrogate pair.
+  Standard_Integer AdvanceCodeUnitsUtf16() const;
+
   //! @return the advance in bytes to store current symbol in UTF-32.
   //! Always 4 bytes (method for consistency).
   Standard_Integer AdvanceBytesUtf32() const
index 0bfc150..6cee87c 100755 (executable)
@@ -230,6 +230,16 @@ Standard_Utf8UChar* NCollection_UtfIterator<Type>::GetUtf8 (Standard_Utf8UChar*
 template<typename Type> inline
 Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf16() const
 {
+  return AdvanceCodeUnitsUtf16() * sizeof(Standard_Utf16Char);
+}
+
+// =======================================================================
+// function : AdvanceCodeUnitsUtf16
+// purpose  :
+// =======================================================================
+template<typename Type> inline
+Standard_Integer NCollection_UtfIterator<Type>::AdvanceCodeUnitsUtf16() const
+{
   if (myCharUtf32 <= UTF32_MAX_BMP) // target is a character <= 0xFFFF
   {
     // UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values
@@ -240,7 +250,7 @@ Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf16() const
     }
     else
     {
-      return Standard_Integer(sizeof(Standard_Utf16Char));
+      return 1;
     }
   }
   else if (myCharUtf32 > UTF32_MAX_LEGAL)
@@ -252,7 +262,7 @@ Standard_Integer NCollection_UtfIterator<Type>::AdvanceBytesUtf16() const
   {
     // target is a character in range 0xFFFF - 0x10FFFF
     // surrogate pair
-    return Standard_Integer(sizeof(Standard_Utf16Char) * 2);
+    return 2;
   }
 }
 
index f8cfa3f..57cd864 100755 (executable)
@@ -96,11 +96,15 @@ public:
   NCollection_UtfString (const Standard_Utf32Char* theCopyUtf32,
                          const Standard_Integer    theLength = -1);
 
+#if !defined(_WIN32) || defined(_NATIVE_WCHAR_T_DEFINED) || (defined(_MSC_VER) && _MSC_VER >= 1900)
   //! Copy constructor from NULL-terminated wide UTF string.
   //! @param theCopyUtfWide NULL-terminated wide UTF string to copy
   //! @param theLength      the length limit in Unicode symbols (NOT bytes!)
+  //!
+  //! This constructor is undefined if Standard_WideChar is the same type as Standard_Utf16Char.
   NCollection_UtfString (const Standard_WideChar* theCopyUtfWide,
                          const Standard_Integer   theLength = -1);
+#endif
 
   //! Copy from NULL-terminated Unicode string.
   //! @param theStringUtf NULL-terminated Unicode string
index 24b6bb0..ba602f5 100755 (executable)
@@ -179,6 +179,7 @@ NCollection_UtfString<Type>::NCollection_UtfString (const Standard_Utf32Char* th
   FromUnicode (theCopyUtf32, theLength);
 }
 
+#if !defined(_WIN32) || defined(_NATIVE_WCHAR_T_DEFINED) || (defined(_MSC_VER) && _MSC_VER >= 1900)
 // =======================================================================
 // function : NCollection_UtfString
 // purpose  :
@@ -192,6 +193,7 @@ NCollection_UtfString<Type>::NCollection_UtfString (const Standard_WideChar* the
 {
   FromUnicode (theCopyUtfWide, theLength);
 }
+#endif
 
 // =======================================================================
 // function : ~NCollection_UtfString
index 88e12b0..0439f28 100644 (file)
@@ -121,7 +121,8 @@ void OSD_Directory :: Build (const OSD_Protection& Protect) {
 
   Standard_ProgramError :: Raise ( "OSD_Directory :: Build (): incorrect call - no directory name");
  TCollection_ExtendedString dirNameW(dirName);
- if (Exists() || CreateDirectoryW((const wchar_t*)dirNameW.ToExtString(), NULL)) {
+ if (Exists() || CreateDirectoryW (dirNameW.ToWideString(), NULL))
+ {
 #ifndef OCCT_UWP
    SetProtection(Protect);
 #else
@@ -139,8 +140,7 @@ OSD_Directory OSD_Directory :: BuildTemporary () {
  OSD_Protection          prt;
 
  wchar_t* aName = _wtmpnam(NULL);
- NCollection_String aFolder(aName != NULL ? aName : L"");
- OSD_Path dirPath(aFolder.ToCString());
+ OSD_Path dirPath (TCollection_AsciiString (aName != NULL ? aName : L""));
 
  retVal.SetPath ( dirPath );
  retVal.Build ( prt );                            
index fdc7405..09f7b67 100644 (file)
@@ -239,7 +239,7 @@ Standard_Boolean OSD_DirectoryIterator :: More () {
 
   // make wchar_t string from UTF-8
   TCollection_ExtendedString wcW(wc);
-  myHandle = FindFirstFileExW ((const wchar_t*)wcW.ToExtString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
+  myHandle = FindFirstFileExW (wcW.ToWideString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
 
   if ( myHandle == INVALID_HANDLE_VALUE )
 
index b84a566..2298658 100644 (file)
@@ -180,8 +180,7 @@ OSD_Disk :: OSD_Disk () {
  if (aBuffLen > 3 && aBuff[0] != L'\\')
  {
    aBuff[3] = L'\0';
-   NCollection_String aFolder(aBuff);
-   DiskName = aFolder.ToCString();
+   DiskName = TCollection_AsciiString (aBuff);
    delete[] aBuff;
  }
  else
@@ -234,7 +233,7 @@ Standard_Integer OSD_Disk :: DiskSize () {
   ULARGE_INTEGER lpTotalNumberOfFreeBytes;// receives the free bytes on disk
 
   TCollection_ExtendedString DiskNameW(DiskName);
-  if (!GetDiskFreeSpaceExW ((const wchar_t*)DiskNameW.ToExtString(),
+  if (!GetDiskFreeSpaceExW (DiskNameW.ToWideString(),
                           &lpFreeBytesAvailableToCaller,
                           &lpTotalNumberOfBytes,
                           &lpTotalNumberOfFreeBytes))
@@ -272,7 +271,7 @@ Standard_Integer OSD_Disk :: DiskFree () {
 
   // if (   !GetDiskFreeSpace (  DiskName.ToCString (), &dwSpC, &dwBpS, &dwFC, &dwC  )   )
   TCollection_ExtendedString DiskNameW(DiskName);
-  if (!GetDiskFreeSpaceExW((const wchar_t*)DiskNameW.ToExtString(),
+  if (!GetDiskFreeSpaceExW (DiskNameW.ToWideString(),
                           &lpFreeBytesAvailableToCaller,
                           &lpTotalNumberOfBytes,
                           &lpTotalNumberOfFreeBytes))
index b7170a3..e17bc5a 100644 (file)
@@ -823,7 +823,7 @@ void OSD_File::Rewind() {
 
 void                            _osd_wnt_set_error        ( OSD_Error&, OSD_WhoAmI, ... );
 #ifndef OCCT_UWP
-PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, wchar_t* = NULL );
+PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
 BOOL                 __fastcall _osd_wnt_sd_to_protection (
                                  PSECURITY_DESCRIPTOR, OSD_Protection&, BOOL
                                 );
@@ -1653,7 +1653,7 @@ Standard_Boolean OSD_File :: IsOpen () const {
 
 #ifndef OCCT_UWP
 PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd (
-                                 const OSD_Protection& prot, BOOL fDir, wchar_t* fName
+                                 const OSD_Protection& prot, BOOL fDir, const wchar_t* fName
                                 ) {
 
  int                  i, j;
@@ -2289,7 +2289,7 @@ static HANDLE __fastcall _open_file (
  TCollection_ExtendedString fNameW(fName, Standard_True);
 #ifndef OCCT_UWP
  retVal = CreateFileW (
-           (const wchar_t*) fNameW.ToExtString(), dwDesiredAccess,
+           fNameW.ToWideString(), dwDesiredAccess,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
           );
@@ -2300,7 +2300,7 @@ static HANDLE __fastcall _open_file (
  pCreateExParams.lpSecurityAttributes = NULL;
  pCreateExParams.hTemplateFile = NULL;
  retVal = CreateFile2 (
-           (const wchar_t*) fNameW.ToExtString(), dwDesiredAccess,
+           fNameW.ToWideString(), dwDesiredAccess,
            FILE_SHARE_READ | FILE_SHARE_WRITE,
            dwCreationDistribution, &pCreateExParams
           );
@@ -2314,7 +2314,7 @@ static HANDLE __fastcall _open_file (
   dwCreationDistribution = CREATE_ALWAYS;
 #ifndef OCCT_UWP
   retVal = CreateFileW (
-            (const wchar_t*) fNameW.ToExtString(), dwDesiredAccess,
+            fNameW.ToWideString(), dwDesiredAccess,
             FILE_SHARE_READ | FILE_SHARE_WRITE,
             NULL, dwCreationDistribution, FILE_ATTRIBUTE_NORMAL, NULL
            );
@@ -2325,7 +2325,7 @@ static HANDLE __fastcall _open_file (
   pCreateExParams2.lpSecurityAttributes = NULL;
   pCreateExParams2.hTemplateFile = NULL;
   retVal = CreateFile2(
-    (const wchar_t*)fNameW.ToExtString(), dwDesiredAccess,
+    fNameW.ToWideString(), dwDesiredAccess,
     FILE_SHARE_READ | FILE_SHARE_WRITE,
     dwCreationDistribution, &pCreateExParams2
   );
@@ -2363,7 +2363,7 @@ Standard_Integer __fastcall _get_file_type (
    TCollection_ExtendedString fNameW(fName, Standard_True);
 
    WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
-   if (GetFileAttributesExW((const wchar_t*)fNameW.ToExtString(), GetFileExInfoStandard, &aFileInfo))
+   if (GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
 
     retVal = aFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FLAG_DIRECTORY : FLAG_FILE;
 
index 4699a3c..44b2f64 100644 (file)
@@ -317,7 +317,7 @@ Standard_Boolean OSD_FileIterator :: More () {
 
   // make wchar_t string from UTF-8
   TCollection_ExtendedString wcW(wc);
-  myHandle = FindFirstFileExW((const wchar_t*)wcW.ToExtString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
+  myHandle = FindFirstFileExW (wcW.ToWideString(), FindExInfoStandard, (PWIN32_FIND_DATAW)myData, FindExSearchNameMatch, NULL, 0);
 
   if (  myHandle == INVALID_HANDLE_VALUE  )
   
index c70994e..5933a26 100644 (file)
@@ -387,7 +387,7 @@ Standard_Integer OSD_FileNode::Error()const{
 
 #ifndef OCCT_UWP
 // None of the existing security APIs are supported in a UWP applications
-PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, wchar_t* = NULL );
+PSECURITY_DESCRIPTOR __fastcall _osd_wnt_protection_to_sd ( const OSD_Protection&, BOOL, const wchar_t* );
 BOOL                 __fastcall _osd_wnt_sd_to_protection (
                                  PSECURITY_DESCRIPTOR pSD, OSD_Protection& prot, BOOL
                                 );
@@ -396,7 +396,7 @@ Standard_Integer     __fastcall _get_file_type ( Standard_CString, HANDLE );
 
 void _osd_wnt_set_error ( OSD_Error&, OSD_WhoAmI, ... );
 
-static BOOL __fastcall _get_file_time ( Standard_ExtString, LPSYSTEMTIME, BOOL );
+static BOOL __fastcall _get_file_time (const wchar_t*, LPSYSTEMTIME, BOOL );
 static void __fastcall _test_raise ( TCollection_AsciiString, Standard_CString );
 
 //=======================================================================
@@ -460,14 +460,17 @@ Standard_Boolean OSD_FileNode::Exists () {
 
  WIN32_FILE_ATTRIBUTE_DATA aFileInfo;
 
- if ( !GetFileAttributesExW((const wchar_t*)fNameW.ToExtString(), GetFileExInfoStandard, &aFileInfo)) {
-
-  if (  GetLastError () != ERROR_FILE_NOT_FOUND  )
-    _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
-
- } else
-
+ if (!GetFileAttributesExW (fNameW.ToWideString(), GetFileExInfoStandard, &aFileInfo))
+ {
+  if (GetLastError() != ERROR_FILE_NOT_FOUND)
+  {
+    _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
+  }
+ }
+ else
+ {
   retVal = Standard_True;
+ }
 
  return retVal;
 
@@ -491,8 +494,8 @@ void OSD_FileNode::Remove () {
 
   case FLAG_FILE:
 
-   if (   !DeleteFileW (  (const wchar_t*) fNameW.ToExtString ()  )   )
-     _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
+   if (!DeleteFileW (fNameW.ToWideString()))
+     _osd_wnt_set_error (  myError, OSD_WFileNode, fNameW.ToWideString());
   break;
 
   case FLAG_DIRECTORY:
@@ -501,8 +504,8 @@ void OSD_FileNode::Remove () {
 // LD : Suppression de l'appel a DeleteDirectory pour 
 //      ne pas detruire un repertoire no vide.
 
-   if (   !RemoveDirectoryW ( (const wchar_t*) fNameW.ToExtString ()  )   )
-     _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
+   if (!RemoveDirectoryW (fNameW.ToWideString()))
+     _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
   break;
 
   default:
@@ -533,21 +536,16 @@ void OSD_FileNode::Move ( const OSD_Path& NewPath ) {
 
   case FLAG_FILE:
 
-   if (!MoveFileExW ((const wchar_t*)fNameW.ToExtString (),
-                     (const wchar_t*)fNameDstW.ToExtString (),
-                     MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED
-                     )
-       )
-     _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
+   if (!MoveFileExW (fNameW.ToWideString (),
+                     fNameDstW.ToWideString (),
+                     MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
+     _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
   break;
 
   case FLAG_DIRECTORY:
 
-   if (   !MoveDirectory (
-            (const wchar_t*) fNameW.ToExtString (), (const wchar_t*) fNameDstW.ToExtString ()
-           )
-   )
-   _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
+   if (!MoveDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
+   _osd_wnt_set_error(myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
   break;
 
   default:
@@ -578,23 +576,17 @@ void OSD_FileNode::Copy ( const OSD_Path& ToPath ) {
 
   case FLAG_FILE:
 #ifndef OCCT_UWP
-    if (!CopyFileW((const wchar_t*)fNameW.ToExtString(),
-      (const wchar_t*)fNameDstW.ToExtString(), FALSE))
+    if (!CopyFileW (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE))
 #else
-   if (CopyFile2((const wchar_t*)fNameW.ToExtString (),
-                 (const wchar_t*)fNameDstW.ToExtString (), FALSE ) != S_OK)
+   if (CopyFile2 (fNameW.ToWideString(), fNameDstW.ToWideString(), FALSE) != S_OK)
 #endif
-   _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
+   _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
   break;
 
   case FLAG_DIRECTORY:
 
-   if (   !CopyDirectory (
-            (const wchar_t*)fNameW.ToExtString (), (const wchar_t*)fNameDstW.ToExtString ()
-          )
-   )
-
-   _osd_wnt_set_error(myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString(), (const wchar_t*)fNameDstW.ToExtString());
+   if (!CopyDirectory (fNameW.ToWideString(), fNameDstW.ToWideString()))
+   _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString(), fNameDstW.ToWideString());
 
   break;
 
@@ -624,12 +616,8 @@ OSD_Protection OSD_FileNode::Protection () {
 
  TEST_RAISE(  "Protection"  );
 
- if (   (  pSD = GetFileSecurityEx (
-                  (const wchar_t*) fNameW.ToExtString (), DACL_SECURITY_INFORMATION |
-                  OWNER_SECURITY_INFORMATION
-                 )
-        ) == NULL ||
-        !_osd_wnt_sd_to_protection (
+ if ((pSD = GetFileSecurityEx (fNameW.ToWideString(), DACL_SECURITY_INFORMATION |OWNER_SECURITY_INFORMATION)) == NULL
+  || !_osd_wnt_sd_to_protection (
           pSD, retVal,
           _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY)
  )
@@ -659,18 +647,12 @@ void OSD_FileNode::SetProtection ( const OSD_Protection& Prot ) {
 
  TEST_RAISE(  "SetProtection"  );
 
- pSD = _osd_wnt_protection_to_sd (
-        Prot,
-        _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) ==
-        FLAG_DIRECTORY,
-        (wchar_t *)fNameW.ToExtString ()
-       );
+ pSD = _osd_wnt_protection_to_sd (Prot,
+        _get_file_type (fName.ToCString(), INVALID_HANDLE_VALUE) == FLAG_DIRECTORY,
+        fNameW.ToWideString());
  
- if ( pSD == NULL || !SetFileSecurityW (
-                       (const wchar_t*) fNameW.ToExtString (), DACL_SECURITY_INFORMATION, pSD
-                      )
- )
-  _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
+ if (pSD == NULL || !SetFileSecurityW (fNameW.ToWideString(), DACL_SECURITY_INFORMATION, pSD))
+  _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
 
  if ( pSD != NULL )
 
@@ -695,11 +677,11 @@ OSD_Protection OSD_FileNode::Protection ()
  TCollection_ExtendedString fNameW(fName);
 
  OSD_SingleProtection aProt = OSD_None;
- if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 6))
+ if (_waccess_s (fNameW.ToWideString(), 6))
    aProt = OSD_RW;
- else if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 2))
+ else if (_waccess_s (fNameW.ToWideString(), 2))
    aProt = OSD_W;
- else if (_waccess_s ((const wchar_t*)fNameW.ToExtString(), 4))
+ else if (_waccess_s (fNameW.ToWideString(), 4))
    aProt = OSD_R;
 
  // assume full access for system and none for everybody
@@ -735,9 +717,7 @@ Quantity_Date OSD_FileNode::AccessMoment () {
 
  TEST_RAISE(  "AccessMoment"  );
 
-// if (   _get_file_time (  fName.ToCString (), &stAccessMoment, TRUE  )   )
- if (   _get_file_time (  fNameW.ToExtString (), &stAccessSystemMoment, TRUE  ) )
-//POP
+ if (_get_file_time (fNameW.ToWideString(), &stAccessSystemMoment, TRUE))
 {
   SYSTEMTIME * aSysTime = &stAccessMoment;
   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL ,
@@ -752,7 +732,9 @@ Quantity_Date OSD_FileNode::AccessMoment () {
                     );
 }
  else
-  _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
+ {
+  _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
+ }
 
  return retVal;
 
@@ -775,9 +757,7 @@ Quantity_Date OSD_FileNode::CreationMoment () {
 
  TEST_RAISE(  "CreationMoment"  );
 
-// if (   _get_file_time (  fName.ToCString (), &stCreationMoment, FALSE  )   )
- if ( _get_file_time ( fNameW.ToExtString (), &stCreationSystemMoment, TRUE  )   ) 
-//POP 
+ if (_get_file_time (fNameW.ToWideString(), &stCreationSystemMoment, TRUE))
 {
   SYSTEMTIME * aSysTime = &stCreationMoment;
   BOOL aFlag = SystemTimeToTzSpecificLocalTime (NULL,
@@ -792,7 +772,9 @@ Quantity_Date OSD_FileNode::CreationMoment () {
                     );
 }
  else
-  _osd_wnt_set_error (  myError, OSD_WFileNode, (const wchar_t*)fNameW.ToExtString());
+ {
+  _osd_wnt_set_error (myError, OSD_WFileNode, fNameW.ToWideString());
+ }
 
  return retVal;
 
@@ -880,10 +862,8 @@ void _osd_wnt_set_error ( OSD_Error& err, OSD_WhoAmI who, ... ) {
 #define __leave return retVal
 #endif
 
-static BOOL __fastcall _get_file_time (
-                        Standard_ExtString fName, LPSYSTEMTIME lpSysTime, BOOL fAccess
-                       ) {
-
+static BOOL __fastcall _get_file_time (const wchar_t* fName, LPSYSTEMTIME lpSysTime, BOOL fAccess)
+{
  BOOL       retVal = FALSE;
  FILETIME   ftCreationTime;
  FILETIME   ftLastWriteTime;
@@ -892,7 +872,7 @@ static BOOL __fastcall _get_file_time (
 
  __try {
 #ifndef OCCT_UWP
-   if ((hFile = CreateFileW((const wchar_t*)fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
+   if ((hFile = CreateFileW (fName, 0, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)
      ) == INVALID_HANDLE_VALUE
      )
 #else
@@ -901,11 +881,7 @@ static BOOL __fastcall _get_file_time (
    pCreateExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
    pCreateExParams.lpSecurityAttributes = NULL;
    pCreateExParams.hTemplateFile = NULL;
-   if ((hFile = CreateFile2(
-     (const wchar_t*)fName, NULL, NULL,
-     OPEN_EXISTING, &pCreateExParams)
-     ) == INVALID_HANDLE_VALUE
-     )
+   if ((hFile = CreateFile2 (fName, NULL, NULL, OPEN_EXISTING, &pCreateExParams)) == INVALID_HANDLE_VALUE)
 #endif
     __leave;
 
index f99c9dc..12d6e7a 100644 (file)
@@ -16,8 +16,6 @@
 #endif
 
 #include <OSD_OpenFile.hxx>
-#include <TCollection_ExtendedString.hxx>
-#include <NCollection_UtfString.hxx>
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -34,8 +32,8 @@ FILE* OSD_OpenFile(const char* theName,
   // file name is treated as UTF-8 string and converted to UTF-16 one
   const TCollection_ExtendedString aFileNameW (theName, Standard_True);
   const TCollection_ExtendedString aFileModeW (theMode, Standard_True);
-  aFile = ::_wfopen ((const wchar_t* )aFileNameW.ToExtString(),
-                     (const wchar_t* )aFileModeW.ToExtString());
+  aFile = ::_wfopen (aFileNameW.ToWideString(),
+                     aFileModeW.ToWideString());
 #else
   aFile = ::fopen (theName, theMode);
 #endif
@@ -52,119 +50,17 @@ FILE* OSD_OpenFile(const TCollection_ExtendedString& theName,
   FILE* aFile = 0;
 #if defined(_WIN32)
   const TCollection_ExtendedString aFileModeW (theMode, Standard_True);
-  aFile = ::_wfopen ((const wchar_t* )theName.ToExtString(),
-                     (const wchar_t* )aFileModeW.ToExtString());
+  aFile = ::_wfopen (theName.ToWideString(),
+                     aFileModeW.ToWideString());
 #else
   // conversion in UTF-8 for linux
-  NCollection_Utf8String aString((const Standard_Utf16Char*)theName.ToExtString());
+  NCollection_Utf8String aString (theName.ToExtString());
   aFile = ::fopen (aString.ToCString(),theMode);
 #endif
   return aFile;
 }
 
 // ==============================================
-// function : OSD_OpenFileBuf
-// purpose : Opens file buffer
-// ==============================================
-void OSD_OpenFileBuf(std::filebuf& theBuff,
-                     const char* theName,
-                     const std::ios_base::openmode theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  // file name is treated as UTF-8 string and converted to UTF-16 one
-  const TCollection_ExtendedString aFileNameW (theName, Standard_True);
-  theBuff.open ((const wchar_t* )aFileNameW.ToExtString(), theMode);
-#else
-  theBuff.open (theName, theMode);
-#endif
-}
-
-// ==============================================
-// function : OSD_OpenFileBuf
-// purpose : Opens file buffer
-// ==============================================
-void OSD_OpenFileBuf(std::filebuf& theBuff,
-                     const TCollection_ExtendedString& theName,
-                     const std::ios_base::openmode theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  theBuff.open ((const wchar_t* )theName.ToExtString(), theMode);
-#else
-  // conversion in UTF-8 for linux
-  NCollection_Utf8String aString((const Standard_Utf16Char*)theName.ToExtString());
-  theBuff.open (aString.ToCString(),theMode);
-#endif
-}
-
-// ==============================================
-// function : OSD_OpenStream
-// purpose : Opens file stream
-// ==============================================
-void OSD_OpenStream(std::ofstream& theStream,
-                    const char* theName,
-                    const std::ios_base::openmode theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  // file name is treated as UTF-8 string and converted to UTF-16 one
-  const TCollection_ExtendedString aFileNameW (theName, Standard_True);
-  theStream.open ((const wchar_t* )aFileNameW.ToExtString(), theMode);
-#else
-  theStream.open (theName, theMode);
-#endif
-}
-
-// ==============================================
-// function : OSD_OpenStream
-// purpose : Opens file stream
-// ==============================================
-void OSD_OpenStream(std::ofstream& theStream,
-                    const TCollection_ExtendedString& theName,
-                    const std::ios_base::openmode theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  theStream.open ((const wchar_t* )theName.ToExtString(), theMode);
-#else
-  // conversion in UTF-8 for linux
-  NCollection_Utf8String aString((const Standard_Utf16Char*)theName.ToExtString());
-  theStream.open (aString.ToCString(),theMode);
-#endif
-}
-
-// ==============================================
-// function : OSD_OpenStream
-// purpose  : Opens file stream
-// ==============================================
-void OSD_OpenStream (std::ifstream&                theStream,
-                     const char*                   theName,
-                     const std::ios_base::openmode theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  // file name is treated as UTF-8 string and converted to UTF-16 one
-  const TCollection_ExtendedString aFileNameW (theName, Standard_True);
-  theStream.open ((const wchar_t*)aFileNameW.ToExtString(), theMode);
-#else
-  theStream.open (theName, theMode);
-#endif
-}
-
-// ==============================================
-// function : OSD_OpenStream
-// purpose  : Opens file stream
-// ==============================================
-void OSD_OpenStream (std::ifstream&                    theStream,
-                     const TCollection_ExtendedString& theName,
-                     const std::ios_base::openmode     theMode)
-{
-#if defined(_WIN32) && defined(_MSC_VER)
-  theStream.open ((const wchar_t*)theName.ToExtString(), theMode);
-#else
-  // conversion in UTF-8 for linux
-  NCollection_Utf8String aString ((const Standard_Utf16Char*)theName.ToExtString());
-  theStream.open (aString.ToCString(), theMode);
-#endif
-}
-
-// ==============================================
 // function : OSD_FileStatCTime
 // purpose :
 // ==============================================
@@ -175,7 +71,7 @@ Standard_Time OSD_FileStatCTime (const char* theName)
   // file name is treated as UTF-8 string and converted to UTF-16 one
   const TCollection_ExtendedString aFileNameW (theName, Standard_True);
   struct __stat64 aStat;
-  if (_wstat64 ((const wchar_t* )aFileNameW.ToExtString(), &aStat) == 0)
+  if (_wstat64 (aFileNameW.ToWideString(), &aStat) == 0)
   {
     aTime = (Standard_Time )aStat.st_ctime;
   }
index 2944c36..378951e 100644 (file)
 
 #include <fstream>
 #include <TCollection_ExtendedString.hxx>
+#include <NCollection_UtfString.hxx>
 
-//! Function opens the file stream.
-//! @param theStream stream to open
-//! @param theName name of file encoded in UTF-8
-//! @param theMode opening mode
-__Standard_API void OSD_OpenStream (std::ofstream& theStream,
-                                    const char* theName,
-                                    const std::ios_base::openmode theMode);
-
-//! Function opens the file stream.
-//! @param theStream stream to open
+//! Function opens the file.
 //! @param theName name of file encoded in UTF-16
 //! @param theMode opening mode
-__Standard_API void OSD_OpenStream (std::ofstream& theStream,
-                                    const TCollection_ExtendedString& theName,
-                                    const std::ios_base::openmode theMode);
+//! @return file handle of opened file
+__Standard_API FILE* OSD_OpenFile (const TCollection_ExtendedString& theName,
+                                   const char* theMode);
 
-//! Function opens the file stream.
-//! @param theStream stream to open
+//! Function retrieves file timestamp.
 //! @param theName name of file encoded in UTF-8
-//! @param theMode opening mode
-__Standard_API void OSD_OpenStream (std::ifstream&                theStream,
-                                    const char*                   theName,
-                                    const std::ios_base::openmode theMode);
+//! @return stat.st_ctime value
+__Standard_API Standard_Time OSD_FileStatCTime (const char* theName);
 
 //! Function opens the file stream.
 //! @param theStream stream to open
-//! @param theName name of file encoded in UTF-16
-//! @param theMode opening mode
-__Standard_API void OSD_OpenStream (std::ifstream&                    theStream,
-                                    const TCollection_ExtendedString& theName,
-                                    const std::ios_base::openmode     theMode);
-
-//! Function opens the file buffer.
-//! @param theBuff file buffer to open
 //! @param theName name of file encoded in UTF-8
 //! @param theMode opening mode
-__Standard_API void OSD_OpenFileBuf (std::filebuf& theBuff,
-                                     const char* theName,
-                                     const std::ios_base::openmode theMode);
-
-//! Function opens the file buffer.
-//! @param theBuff file buffer to open
-//! @param theName name of file encoded in UTF-16
-//! @param theMode opening mode
-__Standard_API void OSD_OpenFileBuf (std::filebuf& theBuff,
-                                     const TCollection_ExtendedString& theName,
-                                     const std::ios_base::openmode theMode);
-
+template <typename T>
+inline void OSD_OpenStream (T& theStream,
+                            const char* theName,
+                            const std::ios_base::openmode theMode)
+{
+#if defined(_WIN32) && defined(_MSC_VER)
+  // file name is treated as UTF-8 string and converted to UTF-16 one
+  const TCollection_ExtendedString aFileNameW (theName, Standard_True);
+  theStream.open (aFileNameW.ToWideString(), theMode);
+#else
+  theStream.open (theName, theMode);
+#endif
+}
 
-//! Function opens the file.
+//! Function opens the file stream.
+//! @param theStream stream to open
 //! @param theName name of file encoded in UTF-16
 //! @param theMode opening mode
-//! @return file handle of opened file
-__Standard_API FILE* OSD_OpenFile (const TCollection_ExtendedString& theName,
-                                   const char* theMode);
-
-//! Function retrieves file timestamp.
-//! @param theName name of file encoded in UTF-8
-//! @return stat.st_ctime value
-__Standard_API Standard_Time OSD_FileStatCTime (const char* theName);
+template <typename T>
+inline void OSD_OpenStream (T& theStream,
+                            const TCollection_ExtendedString& theName,
+                            const std::ios_base::openmode theMode)
+{
+#if defined(_WIN32) && defined(_MSC_VER)
+  theStream.open (theName.ToWideString(), theMode);
+#else
+  // conversion in UTF-8 for linux
+  NCollection_Utf8String aString (theName.ToExtString());
+  theStream.open (aString.ToCString(), theMode);
+#endif
+}
 
 extern "C" {
 #endif // __cplusplus
index 065ed73..17ed707 100644 (file)
@@ -353,10 +353,10 @@ OSD_Path OSD_Process :: CurrentDirectory () {
   DWORD dwSize = PATHLEN + 1;
   Standard_WideChar* pBuff = new wchar_t[dwSize];
 
-  if ( GetCurrentDirectoryW(dwSize, (wchar_t*)pBuff) > 0 )
+  if (GetCurrentDirectoryW (dwSize, pBuff) > 0)
   {
     // conversion to UTF-8 is performed inside
-    TCollection_AsciiString aPath(TCollection_ExtendedString((Standard_ExtString)pBuff));
+    TCollection_AsciiString aPath (pBuff);
     anCurrentDirectory = OSD_Path ( aPath );
   }
   else
@@ -374,7 +374,7 @@ void OSD_Process :: SetCurrentDirectory ( const OSD_Path& where ) {
  where.SystemName ( path );
  TCollection_ExtendedString pathW(path);
 
- if (   !::SetCurrentDirectoryW ( (const wchar_t*) pathW.ToExtString ()  )   )
+ if (!::SetCurrentDirectoryW (pathW.ToWideString()))
 
   _osd_wnt_set_error ( myError, OSD_WProcess );
 
index c39ef0c..b635baa 100644 (file)
@@ -226,11 +226,11 @@ void OSD_SharedLibrary :: SetName ( const Standard_CString aName ) {
  name = path.Name ();
  name.AssignCat (  path.Extension ()  );
 
+ TCollection_ExtendedString nameW (name);
 #ifndef OCCT_UWP
- myHandle = GetModuleHandle(name.ToCString());
+ myHandle = GetModuleHandleW (nameW.ToWideString());
 #else
- TCollection_ExtendedString nameW(name);
- myHandle = LoadPackagedLibrary ((const wchar_t*)nameW.ToExtString(), NULL  );
+ myHandle = LoadPackagedLibrary (nameW.ToWideString(), NULL);
  FreeLibrary ((HMODULE) myHandle);
 #endif
 
@@ -246,12 +246,13 @@ Standard_Boolean OSD_SharedLibrary :: DlOpen ( const OSD_LoadMode /*Mode*/ ) {
 
  Standard_Boolean retVal = Standard_True;
 
- if ( myHandle == NULL ) {
+ if (myHandle == NULL)
+ {
+  TCollection_ExtendedString myNameW (myName);
 #ifndef OCCT_UWP
-  myHandle = (HINSTANCE)LoadLibraryEx(myName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+  myHandle = (HINSTANCE)LoadLibraryExW (myNameW.ToWideString(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
 #else
-  TCollection_ExtendedString myNameW(myName);
-  myHandle = (HINSTANCE)LoadPackagedLibrary((const wchar_t*)myNameW.ToExtString(), NULL);
+  myHandle = (HINSTANCE)LoadPackagedLibrary (myNameW.ToWideString(), NULL);
 #endif
   if ( myHandle == NULL ) {
    lastDLLError = GetLastError ();
index 3664947..2b61a73 100644 (file)
@@ -486,7 +486,7 @@ void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
   OpenGl_AspectText aTextAspect;
   aTextAspect.Aspect()->SetSpace (0.3);
   TCollection_ExtendedString anExtText = theText;
-  NCollection_String aText = (Standard_Utf16Char* )anExtText.ToExtString();
+  NCollection_String aText (anExtText.ToExtString());
   OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aTextParam, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent);
 }
 
index 157be50..823665c 100644 (file)
@@ -286,7 +286,7 @@ void OpenGl_Text::Init (const Handle(OpenGl_Context)&     theCtx,
   myParams     = theParams;
   myPoint.xy() = thePoint;
   myPoint.z()  = 0.0f;
-  myString.FromUnicode ((Standard_Utf16Char* )theText.ToExtString());
+  myString.FromUnicode (theText.ToExtString());
 }
 
 // =======================================================================
index e151412..6d300ad 100644 (file)
@@ -93,6 +93,9 @@ Standard_MMgrFactory::Standard_MMgrFactory()
   Standard_STATIC_ASSERT(sizeof(short) == 2);
   Standard_STATIC_ASSERT(sizeof(Standard_Utf16Char) == 2);
   Standard_STATIC_ASSERT(sizeof(Standard_Utf32Char) == 4);
+#ifdef _WIN32
+  Standard_STATIC_ASSERT(sizeof(Standard_WideChar) == sizeof(Standard_Utf16Char));
+#endif
 
   char* aVar;
   aVar = getenv ("MMGT_OPT");
index c81ceec..a81da00 100644 (file)
   #define Standard_OVERRIDE
 #endif
 
+// Macro for marking variables / functions as possibly unused
+// so that compiler will not emit redundant "unused" warnings.
+#if defined(__GNUC__) || defined(__clang__)
+  #define Standard_UNUSED __attribute__((unused))
+#else
+  #define Standard_UNUSED
+#endif
+
 // Macro Standard_DEPRECATED("message") can be used to declare a method deprecated.
 // If OCCT_NO_DEPRECATED is defined, Standard_DEPRECATED is defined empty.
 #ifdef OCCT_NO_DEPRECATED
index 08da107..03bb64b 100755 (executable)
@@ -26,7 +26,6 @@ TCollection_DoubleMapNode.gxx
 TCollection_DoubleMapNode.lxx
 TCollection_ExtendedString.cxx
 TCollection_ExtendedString.hxx
-TCollection_ExtendedString.lxx
 TCollection_HArray1.gxx
 TCollection_HArray1.lxx
 TCollection_HArray2.gxx
index 43a8670..127b119 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <TCollection_AsciiString.hxx>
 
+#include <NCollection_UtfIterator.hxx>
 #include <Standard.hxx>
 #include <Standard_NegativeValue.hxx>
 #include <Standard_NullObject.hxx>
 #include <Standard_NumericError.hxx>
 #include <Standard_OutOfRange.hxx>
-#include <TCollection_AsciiString.hxx>
 #include <TCollection_ExtendedString.hxx>
 #include <TCollection_HAsciiString.hxx>
 
@@ -237,6 +238,27 @@ TCollection_AsciiString::TCollection_AsciiString(const TCollection_ExtendedStrin
   }
 }
 
+//---------------------------------------------------------------------------
+//  Create an TCollection_AsciiString from a Standard_WideChar
+//---------------------------------------------------------------------------
+TCollection_AsciiString::TCollection_AsciiString (const Standard_WideChar* theStringUtf)
+: mystring (NULL),
+  mylength (0)
+{
+  for (NCollection_UtfWideIter anIter (theStringUtf); *anIter != 0; ++anIter)
+  {
+    mylength += anIter.AdvanceBytesUtf8();
+  }
+
+  mystring = Allocate (mylength + 1);
+  mystring[mylength] = '\0';
+  NCollection_UtfWideIter anIterRead (theStringUtf);
+  for (Standard_Utf8Char* anIterWrite = mystring; *anIterRead != 0; ++anIterRead)
+  {
+    anIterWrite = anIterRead.GetUtf(anIterWrite);
+  }
+}
+
 // ----------------------------------------------------------------------------
 // AssignCat
 // ----------------------------------------------------------------------------
@@ -396,7 +418,7 @@ void TCollection_AsciiString::Copy(const TCollection_AsciiString& fromwhere)
 // ----------------------------------------------------------------------------
 // Destroy
 // ----------------------------------------------------------------------------
-void TCollection_AsciiString::Destroy()
+TCollection_AsciiString::~TCollection_AsciiString()
 {
   if (mystring) 
     Free (mystring);
@@ -599,14 +621,6 @@ Standard_Boolean TCollection_AsciiString::IsSameString (const TCollection_AsciiS
 }
 
 // ----------------------------------------------------------------------------
-// IsEmpty
-// ----------------------------------------------------------------------------
-Standard_Boolean TCollection_AsciiString::IsEmpty() const
-{
-  return (mylength == 0);
-}
-
-// ----------------------------------------------------------------------------
 // IsDifferent
 // ----------------------------------------------------------------------------
 Standard_Boolean TCollection_AsciiString::IsDifferent
@@ -678,6 +692,34 @@ Standard_Boolean TCollection_AsciiString::IsGreater
 }
 
 // ----------------------------------------------------------------------------
+// StartsWith
+// ----------------------------------------------------------------------------
+Standard_Boolean TCollection_AsciiString::StartsWith (const TCollection_AsciiString& theStartString) const
+{
+  if (this == &theStartString)
+  {
+    return true;
+  }
+
+  return mylength >= theStartString.mylength
+      && strncmp (theStartString.mystring, mystring, theStartString.mylength) == 0;
+}
+
+// ----------------------------------------------------------------------------
+// EndsWith
+// ----------------------------------------------------------------------------
+Standard_Boolean TCollection_AsciiString::EndsWith (const TCollection_AsciiString& theEndString) const
+{
+  if (this == &theEndString)
+  {
+    return true;
+  }
+
+  return mylength >= theEndString.mylength
+      && strncmp (theEndString.mystring, mystring + mylength - theEndString.mylength, theEndString.mylength) == 0;
+}
+
+// ----------------------------------------------------------------------------
 // IntegerValue
 // ----------------------------------------------------------------------------
 Standard_Integer TCollection_AsciiString::IntegerValue()const
index 89c6c45..bb39d47 100644 (file)
@@ -36,17 +36,19 @@ class Standard_NegativeValue;
 class TCollection_HAsciiString;
 class TCollection_ExtendedString;
 
-
-//! A variable-length sequence of ASCII characters
-//! (normal 8-bit character type). It provides editing
-//! operations with built-in memory management to
-//! make AsciiString objects easier to use than
-//! ordinary character arrays.
-//! AsciiString objects follow value semantics; in
-//! other words, they are the actual strings, not
-//! handles to strings, and are copied through
-//! assignment. You may use HAsciiString objects
-//! to get handles to strings.
+//! Class defines a variable-length sequence of 8-bit characters.
+//! Despite class name (kept for historical reasons), it is intended to store UTF-8 string, not just ASCII characters.
+//! However, multi-byte nature of UTF-8 is not considered by the following methods:
+//! - Method ::Length() return the number of bytes, not the number of Unicode symbols.
+//! - Methods taking/returning symbol index work with 8-bit code units, not true Unicode symbols,
+//!   including ::Remove(), ::SetValue(), ::Value(), ::Search(), ::Trunc() and others.
+//! If application needs to process multi-byte Unicode symbols explicitly, NCollection_Utf8Iter class can be used
+//! for iterating through Unicode string (UTF-32 code unit will be returned for each position).
+//!
+//! Class provides editing operations with built-in memory management to make AsciiString objects easier to use than ordinary character arrays.
+//! AsciiString objects follow value semantics; in other words, they are the actual strings,
+//! not handles to strings, and are copied through assignment.
+//! You may use HAsciiString objects to get handles to strings.
 class TCollection_AsciiString 
 {
 public:
@@ -96,7 +98,16 @@ public:
   //! in place of any non-ascii character found in the source string.
   //! Otherwise, creates UTF-8 unicode string.
   Standard_EXPORT TCollection_AsciiString(const TCollection_ExtendedString& astring, const Standard_Character replaceNonAscii = 0);
-  
+
+#if !defined(_WIN32) || defined(_NATIVE_WCHAR_T_DEFINED)
+  //! Initialize UTF-8 Unicode string from wide-char string considering it as Unicode string
+  //! (the size of wide char is a platform-dependent - e.g. on Windows wchar_t is UTF-16).
+  //!
+  //! This constructor is unavailable if application is built with deprecated msvc option "-Zc:wchar_t-",
+  //! since OCCT itself is never built with this option.
+  Standard_EXPORT TCollection_AsciiString (const Standard_WideChar* theStringUtf);
+#endif
+
   //! Appends <other>  to me. This is an unary operator.
   Standard_EXPORT void AssignCat (const Standard_Character other);
 void operator += (const Standard_Character other)
@@ -261,11 +272,7 @@ void operator = (const TCollection_AsciiString& fromwhere)
 }
   
   //! Frees memory allocated by AsciiString.
-  Standard_EXPORT void Destroy();
-~TCollection_AsciiString()
-{
-  Destroy();
-}
+  Standard_EXPORT ~TCollection_AsciiString();
   
   //! Returns the index of the first character of <me> that is
   //! present in <Set>.
@@ -337,8 +344,8 @@ void operator = (const TCollection_AsciiString& fromwhere)
   Standard_EXPORT void InsertBefore (const Standard_Integer Index, const TCollection_AsciiString& other);
   
   //! Returns True if the string <me> contains zero character.
-  Standard_EXPORT Standard_Boolean IsEmpty() const;
-  
+  Standard_Boolean IsEmpty() const { return mylength == 0; }
+
   //! Returns true if the characters in this ASCII string
   //! are identical to the characters in ASCII string other.
   //! Note that this method is an alias of operator ==.
@@ -402,7 +409,13 @@ Standard_Boolean operator > (const TCollection_AsciiString& other) const
 {
   return IsGreater(other);
 }
-  
+
+  //! Determines whether the beginning of this string instance matches the specified string.
+  Standard_EXPORT Standard_Boolean StartsWith (const TCollection_AsciiString& theStartString) const;
+
+  //! Determines whether the end of this string instance matches the specified string.
+  Standard_EXPORT Standard_Boolean EndsWith (const TCollection_AsciiString& theEndString) const;
+
   //! Converts a AsciiString containing a numeric expression to
   //! an Integer.
   //! Example: "215" returns 215.
@@ -666,34 +679,21 @@ friend Standard_EXPORT Standard_IStream& operator >> (Standard_IStream& astream,
 
 friend class TCollection_HAsciiString;
 
-
-protected:
-
-
-
-
-
 private:
 
-  
   Standard_EXPORT void Split (const Standard_Integer where, TCollection_AsciiString& result);
   
   Standard_EXPORT void SubString (const Standard_Integer FromIndex, const Standard_Integer ToIndex, TCollection_AsciiString& result) const;
   
   Standard_EXPORT void Token (const Standard_CString separators, const Standard_Integer whichone, TCollection_AsciiString& result) const;
 
+private:
 
-  Standard_PCharacter mystring;
-  Standard_Integer mylength;
-
+  Standard_PCharacter mystring; //!< NULL-terminated string
+  Standard_Integer    mylength; //!< length in bytes (excluding terminating NULL symbol)
 
 };
 
-
 #include <TCollection_AsciiString.lxx>
 
-
-
-
-
 #endif // _TCollection_AsciiString_HeaderFile
index beb2785..d3965c6 100644 (file)
@@ -12,7 +12,9 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
+#include <TCollection_ExtendedString.hxx>
 
+#include <NCollection_UtfIterator.hxx>
 #include <Standard.hxx>
 #include <Standard_ExtString.hxx>
 #include <Standard_NegativeValue.hxx>
 #include <Standard_NumericError.hxx>
 #include <Standard_OutOfRange.hxx>
 #include <TCollection_AsciiString.hxx>
-#include <TCollection_ExtendedString.hxx>
 
 #include <cctype>
 #include <cstdio>
 
 namespace
 {
-  static Standard_PExtCharacter Allocate (const Standard_Size theLength)
+  //! Allocate string buffer (automatically adding extra symbol for NULL-termination).
+  static Standard_ExtCharacter* allocateExtChars (const Standard_Size theLength)
   {
-    return (Standard_PExtCharacter )Standard::Allocate (theLength);
+    return (Standard_ExtCharacter* )Standard::Allocate ((theLength + 1) * sizeof(Standard_ExtCharacter));
   }
 
-  static Standard_PExtCharacter Reallocate (Standard_Address theAddr, const Standard_Size theLength)
+  //! Re-allocate string buffer (automatically adding extra symbol for NULL-termination).
+  static Standard_ExtCharacter* reallocateExtChars (Standard_Address theAddr,
+                                                    const Standard_Size theLength)
   {
-    return (Standard_PExtCharacter )Standard::Reallocate (theAddr, theLength);
+    return (Standard_ExtCharacter* )Standard::Reallocate (theAddr, (theLength + 1) * sizeof(Standard_ExtCharacter));
   }
 
   static const Standard_ExtCharacter NULL_EXTSTRING[1] = {0};
-}
 
-//============================== input value have len = 2 bytes ====
-inline Standard_ExtCharacter ConvertToUnicode2B (unsigned char *p)
-{
-  // *p, *(p+1)
-  // little endian
-  union {
-    struct {
-      unsigned char  l;
-      unsigned char  h;
-    } hl;
-    Standard_ExtCharacter chr;
-  } EL;
-
-  unsigned char l = *(p+1);
-  l |= 0xC0;
-  unsigned char h = *p;
-  h <<= 6;
-  h |= 0x3F;
-  l &= h;// l is defined
-  h = *p;
-  h >>= 2;
-  h &= 0x07;
-  EL.hl.l = l;
-  EL.hl.h = h;
-  return EL.chr;
-}
-
-//============================== input value have len = 3 bytes ====
-inline Standard_ExtCharacter ConvertToUnicode3B (unsigned char *p)
-{
-  // *p, *(p+1), *(p+2) =>0 , 1, 2
-  // little endian
-  union {
-    struct {
-      unsigned char  l;
-      unsigned char  h;
-    } hl;
-    Standard_ExtCharacter chr;
-  } EL;
-
-
-  unsigned char h = *(p+1);//h = 10yyyyyy
-  unsigned char l = *(p+2);//h = 10zzzzzz
-
-  l |= 0xC0;
-  h <<= 6;   //yy------
-  h |= 0x3F; //yy111111
-  l &= h;   //  yyzzzzzz - l is defined 
-  EL.hl.l = l; 
-  unsigned char a = *p;// a = 1110xxxx
-  a <<= 4;//xxxx----
-  a |= 0x0F;//a = xxxx1111
-  h = *(p+1);
-  h >>= 2;//----yyyy
-  h |= 0xF0; //1111yyyy
-  a &= h; // a = xxxxyyyy
-  EL.hl.h = a; //h is defined
-  return EL.chr;
-}
-//============================== returns number of symbols in UTF8 string ====
-inline Standard_Integer  nbSymbols(const Standard_CString aStr) {
-  Standard_Integer aLen = 0;// length in symbols
-  int i = 0;
-  while (aStr[i] != '\0') {  
-    if((aStr[i] & 0x80) == 0x00) //1byte => 1 symb - Lat1
-      {aLen++; i++;}
-    else if((aStr[i] & 0xE0) == 0xC0 && 
-            (aStr[i+1] && 
-             (aStr[i+1] & 0xC0) == 0x80)) {//2 bytes => 1 symb
-      aLen++;
-      i += 2;
-    } else if((aStr[i] & 0xF0) == 0xE0 && 
-              ((aStr[i+1] && (aStr[i+1] & 0xC0) == 0x80)) &&
-              (aStr[i+2] && (aStr[i+2] & 0xC0) == 0x80)) {
-      aLen++;
-      i += 3;
-    } else 
-      i++; 
-  }
-  return aLen;
+  //! Returns the number of 16-bit code units in Unicode string
+  template<typename T>
+  static Standard_Integer nbSymbols (const T* theUtfString)
+  {
+    Standard_Integer aNbCodeUnits = 0;
+    for (NCollection_UtfIterator<T> anIter (theUtfString); *anIter != 0; ++anIter)
+    {
+      aNbCodeUnits += anIter.AdvanceCodeUnitsUtf16();
+    }
+    return aNbCodeUnits;
+  }
+
+  //! Convert from wchar_t* to extended string.
+  //! Default implementation when size of wchar_t and extended char is different (e.g. Linux / UNIX).
+  template<size_t CharSize>
+  inline Standard_ExtCharacter* Standard_UNUSED fromWideString (const Standard_WideChar* theUtfString,
+                                                                Standard_Integer& theLength)
+  {
+    theLength = nbSymbols (theUtfString);
+    Standard_ExtCharacter* aString = allocateExtChars (theLength);
+    NCollection_UtfWideIter anIterRead (theUtfString);
+    for (Standard_ExtCharacter* anIterWrite = aString; *anIterRead != 0; ++anIterRead)
+    {
+      anIterWrite = anIterRead.GetUtf (anIterWrite);
+    }
+    aString[theLength] = '\0';
+    return aString;
+  }
+
+  //! Use memcpy() conversion when size is the same (e.g. on Windows).
+  template<>
+  inline Standard_ExtCharacter* Standard_UNUSED fromWideString<sizeof(Standard_ExtCharacter)> (const Standard_WideChar* theUtfString,
+                                                                                               Standard_Integer& theLength)
+  {
+    for (theLength = 0; theUtfString[theLength] != L'\0'; ++theLength) {}
+    Standard_ExtCharacter* aString = allocateExtChars (theLength);
+    const Standard_Integer aSize = theLength * sizeof(Standard_ExtCharacter);
+    memcpy (aString, theUtfString, aSize);
+    aString[theLength] = '\0';
+    return aString;
+  }
+
 }
 
 //-----------------------------------------------------------------------------
 // Create an empty ExtendedString
 // ----------------------------------------------------------------------------
 TCollection_ExtendedString::TCollection_ExtendedString()
+: mystring (allocateExtChars (0)),
+  mylength (0)
 {
-//  mystring = 0L;
-  mylength = 0;
-  mystring = Allocate((mylength+1)*2);
-  mystring[mylength] = '\0';
+  mystring[0] = '\0';
 }
 
 //----------------------------------------------------------------------------
 // Create an ExtendedString from a Standard_CString
 //----------------------------------------------------------------------------
 TCollection_ExtendedString::TCollection_ExtendedString
-                                          (const Standard_CString astring, 
+                                          (const Standard_CString theString,
                                            const Standard_Boolean isMultiByte) 
-  : mystring(0), mylength(0)
-{
-  if (astring) {
-    if(!isMultiByte) {
-      mylength = (int)strlen( astring );
-      mystring = Allocate((mylength+1)*2);
-      for (int i = 0 ; i < mylength ; i++)
-        mystring[i] = ToExtCharacter(astring[i]); 
-      mystring[mylength] =  '\0';
-    }
-    else {
-      mylength = nbSymbols(astring);
-      mystring = Allocate( (mylength+1)*2 );
-      if(!ConvertToUnicode (astring))
-      {
-        mylength = (int)strlen( astring );
-        mystring = Reallocate(mystring, (mylength+1)*2);
-        for (int i = 0 ; i < mylength ; i++)
-          mystring[i] = ToExtCharacter(astring[i]); 
-        mystring[mylength] =  '\0';
-      }
+: mystring (NULL),
+  mylength (0)
+{
+  if (theString == NULL)
+  {
+    Standard_NullObject::Raise ("TCollection_ExtendedString : null parameter ");
+  }
+
+  if (isMultiByte)
+  {
+    mylength = nbSymbols (theString);
+    mystring = allocateExtChars (mylength);
+    mystring[mylength] = '\0';
+    if (ConvertToUnicode (theString))
+    {
+      return;
     }
   }
-  else {
-    Standard_NullObject::Raise("TCollection_ExtendedString : "
-                               "parameter 'astring'");
+
+  mylength = (int)strlen(theString);
+  mystring = reallocateExtChars (mystring, mylength);
+  for (int aCharIter = 0; aCharIter < mylength; ++aCharIter)
+  {
+    mystring[aCharIter] = ToExtCharacter (theString[aCharIter]);
   }
+  mystring[mylength] = '\0';
 }
 
 //---------------------------------------------------------------------------
 // Create an ExtendedString from an ExtString
 //--------------------------------------------------------------------------
-TCollection_ExtendedString::TCollection_ExtendedString
-                                        (const Standard_ExtString astring) 
-  : mystring(0), mylength(0)
+TCollection_ExtendedString::TCollection_ExtendedString (const Standard_ExtString theString)
+: mystring (NULL),
+  mylength (0)
 {
-
-  if (astring) {
-    for ( mylength=0; astring[mylength]; ++mylength );
-    const Standard_Integer size = (mylength+1)*2;
-    mystring = Allocate(size);
-    memcpy( mystring, astring, size );
-    mystring[mylength] =  '\0';
-  }
-  else {
+  if (theString == NULL)
+  {
     Standard_NullObject::Raise("TCollection_ExtendedString : null parameter ");
   }
+
+  for (mylength = 0; theString[mylength] != '\0'; ++mylength) {}
+  mystring = allocateExtChars (mylength);
+  const Standard_Integer aSizeBytes = mylength * sizeof(Standard_ExtCharacter);
+  memcpy (mystring, theString, aSizeBytes);
+  mystring[mylength] = '\0';
+}
+
+// ----------------------------------------------------------------------------
+// TCollection_ExtendedString
+// ----------------------------------------------------------------------------
+TCollection_ExtendedString::TCollection_ExtendedString (const Standard_WideChar* theStringUtf)
+: mystring (NULL),
+  mylength (0)
+{
+  if (theStringUtf == NULL)
+  {
+    Standard_NullObject::Raise ("TCollection_ExtendedString : null parameter ");
+  }
+
+  mystring = fromWideString<sizeof(Standard_WideChar)> (theStringUtf, mylength);
 }
 
 // ----------------------------------------------------------------------------
@@ -197,15 +173,15 @@ TCollection_ExtendedString::TCollection_ExtendedString
 {
   if ( aChar != '\0' ) {
     mylength    = 1;
-    mystring    = Allocate(2*2);
+    mystring    = allocateExtChars (1);
     mystring[0] = ToExtCharacter(aChar);
-    mystring[1] =  '\0';
+    mystring[1] = '\0';
   }
   else {
     //    mystring = 0L;
     mylength = 0;
-    mystring = Allocate((mylength+1)*2);
-    mystring[mylength] = '\0';
+    mystring = allocateExtChars (0);
+    mystring[0] = '\0';
   }
 }
 
@@ -216,9 +192,9 @@ TCollection_ExtendedString::TCollection_ExtendedString
                                         (const Standard_ExtCharacter aChar)
 {
   mylength    = 1;
-  mystring    = Allocate(2*2);
+  mystring    = allocateExtChars (1);
   mystring[0] = aChar;
-  mystring[1] =  '\0';
+  mystring[1] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -228,10 +204,10 @@ TCollection_ExtendedString::TCollection_ExtendedString
                                         (const Standard_Integer      length,
                                          const Standard_ExtCharacter filler )
 {
-  mystring = Allocate( (length+1)*2 );
+  mystring = allocateExtChars (length);
   mylength = length;
   for (int i = 0 ; i < length ; i++) mystring[i] = filler;
-  mystring[length] =  '\0';
+  mystring[mylength] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -244,9 +220,9 @@ TCollection_ExtendedString::TCollection_ExtendedString
          char t [13];} CHN ;
   Sprintf(&CHN.t[0],"%d",aValue);
   mylength = (int)strlen(CHN.t);
-  mystring = Allocate((mylength+1)*2);
+  mystring = allocateExtChars (mylength);
   for (int i = 0 ; i < mylength ; i++) mystring[i] = ToExtCharacter(CHN.t[i]);
-  mystring[mylength] =  '\0';
+  mystring[mylength] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -259,9 +235,9 @@ TCollection_ExtendedString::TCollection_ExtendedString
          char t [50];} CHN ;
   Sprintf(&CHN.t[0],"%g",aValue);
   mylength = (int)strlen( CHN.t );
-  mystring = Allocate((mylength+1)*2);
+  mystring = allocateExtChars (mylength);
   for (int i = 0 ; i < mylength ; i++) mystring[i] = ToExtCharacter(CHN.t[i]);
-  mystring[mylength] =  '\0';
+  mystring[mylength] = '\0';
 }
 
 //-----------------------------------------------------------------------------
@@ -270,51 +246,61 @@ TCollection_ExtendedString::TCollection_ExtendedString
 TCollection_ExtendedString::TCollection_ExtendedString
                                 (const TCollection_ExtendedString& astring)
 {
-  const Standard_Integer size = (astring.mylength+1)*2;
+  const Standard_Integer aSizeBytes = astring.mylength * sizeof(Standard_ExtCharacter);
   mylength = astring.mylength;
-  mystring = Allocate(size);
-  memcpy( mystring, astring.mystring, size );
-  mystring[mylength] =  '\0';
+  mystring = allocateExtChars (astring.mylength);
+  memcpy (mystring, astring.mystring, aSizeBytes);
+  mystring[mylength] = '\0';
 }
 
 //---------------------------------------------------------------------------
 //  Create an extendedstring from an AsciiString 
 //---------------------------------------------------------------------------
 TCollection_ExtendedString::TCollection_ExtendedString
-                                (const TCollection_AsciiString& astring) 
+                                (const TCollection_AsciiString& theString)
 {
-  mylength = nbSymbols(astring.ToCString());
-  mystring = Allocate((mylength+1)*2);
-  if(!ConvertToUnicode (astring.ToCString()))
+  mylength = nbSymbols (theString.ToCString());
+  mystring = allocateExtChars (mylength);
+  mystring[mylength] = '\0';
+  if (ConvertToUnicode (theString.ToCString()))
+  {
+    return;
+  }
+
+  mylength = theString.Length();
+  mystring = reallocateExtChars (mystring, mylength);
+  Standard_CString aCString = theString.ToCString();
+  for (Standard_Integer aCharIter = 0; aCharIter <= mylength; ++aCharIter)
   {
-    mylength = astring.Length();
-    mystring = Reallocate(mystring, (mylength+1)*2);
-    Standard_CString aCString = astring.ToCString();
-    for (Standard_Integer i = 0; i <= mylength ; i++)
-      mystring[i] = ToExtCharacter( aCString[i] );
+    mystring[aCharIter] = ToExtCharacter (aCString[aCharIter]);
   }
+  mystring[mylength] = '\0';
 }
 
 // ----------------------------------------------------------------------------
 //  AssignCat
 // ----------------------------------------------------------------------------
-void TCollection_ExtendedString::AssignCat
-                                (const TCollection_ExtendedString& other) 
+void TCollection_ExtendedString::AssignCat (const TCollection_ExtendedString& theOther)
 {
-  Standard_Integer otherlength = other.mylength; 
-  if (otherlength) {
-    Standard_ExtString sother = other.mystring;
-    Standard_Integer newlength = mylength + otherlength; 
-    if (mystring) {
-      mystring = Reallocate(mystring, (newlength+1)*2 );
-      memcpy( mystring + mylength, sother, (otherlength+1)*2 );
-    }
-    else {
-      mystring = Allocate( (newlength+1)*2 );
-      memcpy( mystring, sother, (otherlength+1)*2 );
-    }
-    mylength = newlength;
+  if (theOther.mylength == 0)
+  {
+    return;
+  }
+
+  const Standard_Integer anOtherLength = theOther.mylength;
+  const Standard_Integer aNewlength    = mylength + anOtherLength;
+  if (mystring != NULL)
+  {
+    mystring = reallocateExtChars (mystring, aNewlength);
+    memcpy (mystring + mylength, theOther.mystring, anOtherLength * sizeof(Standard_ExtCharacter));
   }
+  else
+  {
+    mystring = allocateExtChars (aNewlength);
+    memcpy (mystring, theOther.mystring, anOtherLength * sizeof(Standard_ExtCharacter));
+  }
+  mylength = aNewlength;
+  mystring[mylength] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -346,11 +332,15 @@ void TCollection_ExtendedString::ChangeAll(const Standard_ExtCharacter aChar,
 // ----------------------------------------------------------------------------
 void TCollection_ExtendedString::Clear()
 {
-  if (mystring) Standard::Free(mystring);
-//  mystring = 0L;
+  if (mylength == 0)
+  {
+    return;
+  }
+
+  Standard::Free (mystring);
   mylength = 0;
-  mystring = Allocate((mylength+1)*2);
-  mystring[mylength] = '\0';
+  mystring = allocateExtChars (mylength);
+  mystring[0] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -360,21 +350,25 @@ void TCollection_ExtendedString::Copy (const TCollection_ExtendedString& fromwhe
 {
 
   if (fromwhere.mystring) {
-    const Standard_Integer newlength = fromwhere.mylength;
-    const Standard_Integer size      = (newlength + 1) * 2;
-    if (mystring) {
-      mystring = Reallocate(mystring, size );
+    const Standard_Integer newlength  = fromwhere.mylength;
+    const Standard_Integer aSizeBytes = newlength * sizeof(Standard_ExtCharacter);
+    if (mystring != NULL)
+    {
+      mystring = reallocateExtChars (mystring, newlength);
     }
     else {
-      mystring = Allocate( size );
+      mystring = allocateExtChars (newlength);
     }
     mylength = newlength;
-    memcpy( mystring, fromwhere.mystring, size );
+    memcpy (mystring, fromwhere.mystring, aSizeBytes);
+    mystring[mylength] = '\0';
   }
-  else {
-    if (mystring) {
+  else
+  {
+    if (mystring != 0)
+    {
       mylength = 0;
-      mystring[mylength] =  '\0';
+      mystring[0] = '\0';
     }
   }
 }
@@ -382,7 +376,7 @@ void TCollection_ExtendedString::Copy (const TCollection_ExtendedString& fromwhe
 // ----------------------------------------------------------------------------
 // Destroy
 // ----------------------------------------------------------------------------
-void TCollection_ExtendedString::Destroy()
+TCollection_ExtendedString::~TCollection_ExtendedString()
 {
   if (mystring) Standard::Free(mystring);
   mystring = 0L;
@@ -401,11 +395,12 @@ void TCollection_ExtendedString::Insert(const Standard_Integer where,
     Standard_OutOfRange::Raise("TCollection_ExtendedString::Insert : "
                                "Parameter where is negative");
 
-  if (mystring) {
-      mystring = Reallocate(mystring, (mylength+2)*2);
+  if (mystring != NULL)
+  {
+    mystring = reallocateExtChars (mystring, mylength + 1);
   }
   else {
-    mystring = Allocate((mylength+2)*2);
+    mystring = allocateExtChars (mylength + 1);
   }
   if (where != mylength +1) {
     for (int i=mylength-1; i >= where-1; i--)
@@ -413,7 +408,7 @@ void TCollection_ExtendedString::Insert(const Standard_Integer where,
   }
   mystring[where-1] = what;
   mylength++;
-  mystring[mylength] =  '\0';
+  mystring[mylength] = '\0';
 }
 
 // ----------------------------------------------------------------------------
@@ -429,10 +424,10 @@ void TCollection_ExtendedString::Insert(const Standard_Integer            where,
       Standard_Integer newlength = mylength + whatlength;
       
       if (mystring) {
-          mystring = Reallocate(mystring,(newlength+1)*2);
+          mystring = reallocateExtChars (mystring, newlength);
       }
       else {
-        mystring = Allocate((newlength+1)*2);
+        mystring = allocateExtChars (newlength);
       }
       if (where != mylength +1) {
         for (int i=mylength-1; i >= where-1; i--)
@@ -442,7 +437,7 @@ void TCollection_ExtendedString::Insert(const Standard_Integer            where,
         mystring[where-1+i] = swhat[i];
       
       mylength = newlength;
-      mystring[mylength] =  '\0';
+      mystring[mylength] = '\0';
     }
   }
   else {
@@ -524,6 +519,34 @@ Standard_Boolean TCollection_ExtendedString::IsGreater
 }
 
 // ----------------------------------------------------------------------------
+// StartsWith
+// ----------------------------------------------------------------------------
+Standard_Boolean TCollection_ExtendedString::StartsWith (const TCollection_ExtendedString& theStartString) const
+{
+  if (this == &theStartString)
+  {
+    return true;
+  }
+
+  return mylength >= theStartString.mylength
+      && memcmp (theStartString.mystring, mystring, theStartString.mylength) == 0;
+}
+
+// ----------------------------------------------------------------------------
+// EndsWith
+// ----------------------------------------------------------------------------
+Standard_Boolean TCollection_ExtendedString::EndsWith (const TCollection_ExtendedString& theEndString) const
+{
+  if (this == &theEndString)
+  {
+    return true;
+  }
+
+  return mylength >= theEndString.mylength
+      && memcmp (theEndString.mystring, mystring + mylength - theEndString.mylength, theEndString.mylength) == 0;
+}
+
+// ----------------------------------------------------------------------------
 // IsAscii
 // ----------------------------------------------------------------------------
 Standard_Boolean TCollection_ExtendedString::IsAscii()  const 
@@ -672,10 +695,10 @@ void TCollection_ExtendedString::SetValue
     size += (where - 1);  
     if (size >= mylength){
       if (mystring) {
-        mystring = Reallocate (mystring,(size+1)*2);
+        mystring = reallocateExtChars (mystring, size);
       }
       else {
-        mystring = Allocate((size+1)*2);
+        mystring = allocateExtChars (size);
       }
       mylength = size;
     } 
@@ -717,7 +740,7 @@ TCollection_ExtendedString TCollection_ExtendedString::Token
                                "parameter 'separators'");
   
   int                   i,j,k,l;
-  Standard_PExtCharacter  buftmp = Allocate((mylength+1)*2); 
+  Standard_PExtCharacter  buftmp = allocateExtChars (mylength);
   Standard_ExtCharacter aSep;
   
   Standard_Boolean isSepFound   = Standard_False, otherSepFound;
@@ -776,6 +799,7 @@ TCollection_ExtendedString TCollection_ExtendedString::Token
     Standard::Free(res.mystring);
     res.mystring = buftmp;
     for ( res.mylength=0; buftmp[res.mylength]; ++res.mylength );
+    res.mystring[res.mylength] = '\0';
   }
   return res;
 }
@@ -820,49 +844,39 @@ Standard_ExtCharacter TCollection_ExtendedString::Value
 //----------------------------------------------------------------------------
 // Convert CString (including multibyte case) to UniCode representation
 //----------------------------------------------------------------------------
-Standard_Boolean TCollection_ExtendedString::ConvertToUnicode 
-                                                (const Standard_CString aStr)
-{
-  Standard_Boolean aRes = Standard_True;
-  Standard_ExtCharacter* p = mystring;
-  int i = 0;
-  while (aStr[i] != '\0') { 
-    if((aStr[i] & 0x80) == 0x00) //1byte => 1 symb - Lat1
-      {*p++ = ToExtCharacter(aStr[i]); i++;}
-    else if((aStr[i] & 0xE0) == 0xC0 && 
-            (aStr[i+1] && 
-             (aStr[i+1] & 0xC0) == 0x80)) {//2 bytes => 1 symb
-      *p++ = ConvertToUnicode2B((unsigned char*)&aStr[i]);
-      i += 2;
-    } else if((aStr[i] & 0xF0) == 0xE0 && 
-              ((aStr[i+1] && (aStr[i+1] & 0xC0) == 0x80)) &&
-              (aStr[i+2] && (aStr[i+2] & 0xC0) == 0x80)) {      
-      *p++ = ConvertToUnicode3B((unsigned char*)&aStr[i]);
-      i += 3;
-    } else { //unsupported case ==> not UTF8
-      aRes = Standard_False;
-      break;
+Standard_Boolean TCollection_ExtendedString::ConvertToUnicode (const Standard_CString theStringUtf)
+{
+  NCollection_Utf8Iter anIterRead (theStringUtf);
+  Standard_ExtCharacter* anIterWrite = mystring;
+  if (*anIterRead == 0)
+  {
+    *anIterWrite = '\0';
+    return Standard_True;
+  }
+
+  for (; *anIterRead != 0; ++anIterRead)
+  {
+    if (!anIterRead.IsValid())
+    {
+      return Standard_False;
     }
+
+    anIterWrite = anIterRead.GetUtf (anIterWrite);
   }
-  *p = 0x0000;
-  return aRes;
+  return Standard_True;
 }
+
 //----------------------------------------------------------------------------
 // Returns expected CString length in UTF8 coding.
 //----------------------------------------------------------------------------
 Standard_Integer TCollection_ExtendedString::LengthOfCString() const
 {
-  Standard_Integer i=0, aLen=0;
-  while(mystring[i]) {
-    if((mystring[i] & 0xFF80) == 0) 
-      aLen++;
-    else if((mystring[i] & 0xF800) == 0) 
-      aLen +=2;
-    else  
-      aLen += 3;
-    i++;
+  Standard_Integer aSizeBytes = 0;
+  for (NCollection_Utf16Iter anIter (mystring); *anIter != 0; ++anIter)
+  {
+    aSizeBytes += anIter.AdvanceBytesUtf8();
   }
- return aLen;
+  return aSizeBytes;
 }
 
 //----------------------------------------------------------------------------
@@ -871,43 +885,18 @@ Standard_Integer TCollection_ExtendedString::LengthOfCString() const
 //----------------------------------------------------------------------------
 Standard_Integer TCollection_ExtendedString::ToUTF8CString(Standard_PCharacter& theCString) const
 {
-  Standard_Integer i=0, j=0;
-  unsigned char a,b,c;
-  while(mystring[i]) {
-    if((mystring[i] & 0xFF80) == 0) {
-      theCString[j++] = (char)mystring[i];
-    } 
-    else if((mystring[i] & 0xF800) == 0) {
-      b = (unsigned char)mystring[i];//yyzzzzzz
-      c = (unsigned char)mystring[i];//yyzzzzzz
-      a = (unsigned char)(mystring[i]>>8);//00000yyy
-      b &= 0x3F;
-      b |= 0x80;
-      a <<=2;
-      a |= 0xC0;//110yyy00;
-      c >>=6;
-      c &= 0x03;
-      a |=c;
-      theCString[j++] = a;
-      theCString[j++] = b;
-    } else {
-      b = (unsigned char)mystring[i];//yyzzzzzz
-      c = (unsigned char)mystring[i];//yyzzzzzz
-      unsigned char d = a = (unsigned char)(mystring[i]>>8);//xxxxyyyy
-      c &= 0x3F;
-      c |= 0x80;//10zzzzzz
-      b >>= 6; //000000yy
-      d <<= 2;//xxyyyy00;
-      b |= d;
-      b = (b & 0x3F) | 0x80;//10yyyyyy
-      a >>= 4; //0000xxxx
-      a |= 0xE0;//1110xxxx
-      theCString[j++] = a;
-      theCString[j++] = b;
-      theCString[j++] = c;
-    }
-    i++;
+  NCollection_Utf16Iter anIterRead (mystring);
+  Standard_Utf8Char* anIterWrite = theCString;
+  if (*anIterRead == 0)
+  {
+    *anIterWrite = '\0';
+    return 0;
+  }
+
+  for (; *anIterRead != 0; ++anIterRead)
+  {
+    anIterWrite = anIterRead.GetUtf (anIterWrite);
   }
-  theCString[j] = 0x00;
-  return j;
+  *anIterWrite = '\0';
+  return Standard_Integer(anIterWrite - theCString);
 }
index 6260d3d..6564479 100644 (file)
@@ -38,16 +38,21 @@ class Standard_NegativeValue;
 class TCollection_AsciiString;
 
 
-//! A variable-length sequence of "extended"
-//! (UNICODE) characters (16-bit character type). It
-//! provides editing operations with built-in memory
-//! management to make ExtendedString objects
-//! easier to use than ordinary extended character arrays.
-//! ExtendedString objects follow "value
-//! semantics", that is, they are the actual strings,
-//! not handles to strings, and are copied through
-//! assignment. You may use HExtendedString
-//! objects to get handles to strings.
+//! A variable-length sequence of "extended" (UNICODE) characters (16-bit character type).
+//! It provides editing operations with built-in memory management
+//! to make ExtendedString objects easier to use than ordinary extended character arrays.
+//! ExtendedString objects follow "value semantics", that is, they are the actual strings,
+//! not handles to strings, and are copied through assignment.
+//! You may use HExtendedString objects to get handles to strings.
+//!
+//! Beware that class can transparently store UTF-16 string with surrogate pairs
+//! (Unicode symbol represented by two 16-bit code units).
+//! However, surrogate pairs are not considered by the following methods:
+//! - Method ::Length() return the number of 16-bit code units, not the number of Unicode symbols.
+//! - Methods taking/returning symbol index work with 16-bit code units, not true Unicode symbols,
+//!   including ::Remove(), ::SetValue(), ::Value(), ::Search(), ::Trunc() and others.
+//! If application needs to process surrogate pairs, NCollection_Utf16Iter class can be used
+//! for iterating through Unicode string (UTF-32 code unit will be returned for each position).
 class TCollection_ExtendedString 
 {
 public:
@@ -67,6 +72,15 @@ public:
   
   //! Creation by converting an ExtString to an extended string.
   Standard_EXPORT TCollection_ExtendedString(const Standard_ExtString astring);
+
+#if !defined(_WIN32) || defined(_NATIVE_WCHAR_T_DEFINED)
+  //! Initialize from wide-char string considering it as Unicode string
+  //! (the size of wide char is a platform-dependent - e.g. on Windows wchar_t is UTF-16).
+  //!
+  //! This constructor is unavailable if application is built with deprecated msvc option "-Zc:wchar_t-",
+  //! since OCCT itself is never built with this option.
+  Standard_EXPORT TCollection_ExtendedString (const Standard_WideChar* theStringUtf);
+#endif
   
   //! Initializes a AsciiString with a single character.
   Standard_EXPORT TCollection_ExtendedString(const Standard_Character aChar);
@@ -128,21 +142,17 @@ void operator = (const TCollection_ExtendedString& fromwhere)
 }
   
   //! Frees memory allocated by ExtendedString.
-  Standard_EXPORT void Destroy();
-~TCollection_ExtendedString()
-{
-  Destroy();
-}
+  Standard_EXPORT ~TCollection_ExtendedString();
   
   //! Insert a Character at position <where>.
   Standard_EXPORT void Insert (const Standard_Integer where, const Standard_ExtCharacter what);
   
   //! Insert a ExtendedString at position <where>.
   Standard_EXPORT void Insert (const Standard_Integer where, const TCollection_ExtendedString& what);
-  
+
   //! Returns True if this string contains no characters.
-    Standard_Boolean IsEmpty() const;
-  
+  Standard_Boolean IsEmpty() const { return mylength == 0; }
+
   //! Returns true if the characters in this extended
   //! string are identical to the characters in the other extended string.
   //! Note that this method is an alias of operator ==
@@ -206,13 +216,19 @@ Standard_Boolean operator > (const TCollection_ExtendedString& other) const
 {
   return IsGreater(other);
 }
-  
+
+  //! Determines whether the beginning of this string instance matches the specified string.
+  Standard_EXPORT Standard_Boolean StartsWith (const TCollection_ExtendedString& theStartString) const;
+
+  //! Determines whether the end of this string instance matches the specified string.
+  Standard_EXPORT Standard_Boolean EndsWith (const TCollection_ExtendedString& theEndString) const;
+
   //! Returns True if the ExtendedString contains only
   //! "Ascii Range" characters .
   Standard_EXPORT Standard_Boolean IsAscii() const;
-  
-  //! Returns number of characters in <me>.
-  //! This is the same functionality as 'strlen' in C.
+
+  //! Returns the number of 16-bit code units
+  //! (might be greater than number of Unicode symbols if string contains surrogate pairs).
   Standard_EXPORT Standard_Integer Length() const;
   
   //! Displays <me> .
@@ -274,7 +290,14 @@ friend Standard_EXPORT Standard_OStream& operator << (Standard_OStream& astream,
   
   //! Returns pointer to ExtString
   Standard_EXPORT Standard_ExtString ToExtString() const;
-  
+
+#ifdef _WIN32
+  //! Returns pointer to string as wchar_t* on Windows platform where wchar_t* is considered as UTF-16 string.
+  //! This method is useful to pass string into wide-char system APIs,
+  //! and makes sense only on Windows (other systems use UTF-8 and can miss wide-char functions at all).
+  const Standard_WideChar* ToWideString() const { return (const Standard_WideChar*)ToExtString(); }
+#endif
+
   //! Truncates <me> to <ahowmany> characters.
   //! Example:  me = "Hello Dolly" -> Trunc(3) -> me = "Hel"
   //! Exceptions
@@ -292,19 +315,25 @@ friend Standard_EXPORT Standard_OStream& operator << (Standard_OStream& astream,
   //! Standard_OutOfRange if where lies outside
   //! the bounds of this extended string.
   Standard_EXPORT Standard_ExtCharacter Value (const Standard_Integer where) const;
-  
-  //! Returns a hashed value for the extended string
-  //! astring within the range 1..Upper.
-  //! Note: if astring is ASCII, the computed value is
-  //! the same as the value computed with the HashCode function on a
-  //! TCollection_AsciiString string composed with equivalent ASCII characters
-    static Standard_Integer HashCode (const TCollection_ExtendedString& astring, const Standard_Integer Upper);
-  
+
+  //! Returns a hashed value for the extended string within the range 1..theUpper.
+  //! Note: if string is ASCII, the computed value is the same as the value computed with the HashCode function on a
+  //! TCollection_AsciiString string composed with equivalent ASCII characters.
+  static Standard_Integer HashCode (const TCollection_ExtendedString& theString,
+                                    const Standard_Integer theUpper)
+  {
+    return ::HashCode (theString.ToExtString(), theUpper);
+  }
+
   //! Returns true if the characters in this extended
   //! string are identical to the characters in the other extended string.
   //! Note that this method is an alias of operator ==.
-    static Standard_Boolean IsEqual (const TCollection_ExtendedString& string1, const TCollection_ExtendedString& string2);
-  
+  static Standard_Boolean IsEqual (const TCollection_ExtendedString& theString1,
+                                   const TCollection_ExtendedString& theString2)
+  {
+    return theString1.IsEqual (theString2);
+  }
+
   //! Converts the internal <mystring> to UTF8 coding and
   //! returns length of the out CString. A memory for the
   //! <theCString> should be allocated before call!
@@ -315,34 +344,24 @@ friend Standard_EXPORT Standard_OStream& operator << (Standard_OStream& astream,
   //! to CString containing symbols in UTF8 coding.
   Standard_EXPORT Standard_Integer LengthOfCString() const;
 
-
-
-
-protected:
-
-
-
-
-
 private:
 
-  
   //! Returns true if the input CString was successfuly converted
   //! to UTF8 coding
   Standard_EXPORT Standard_Boolean ConvertToUnicode (const Standard_CString astring);
 
+private:
 
-  Standard_PExtCharacter mystring;
-  Standard_Integer mylength;
-
+  Standard_PExtCharacter mystring; //!< NULL-terminated string
+  Standard_Integer       mylength; //!< length in 16-bit code units (excluding terminating NULL symbol)
 
 };
 
-
-#include <TCollection_ExtendedString.lxx>
-
-
-
-
+//! Compute hash code for extended string
+inline Standard_Integer HashCode (const TCollection_ExtendedString& theString,
+                                  const Standard_Integer theUpper)
+{
+  return TCollection_ExtendedString::HashCode (theString, theUpper);
+}
 
 #endif // _TCollection_ExtendedString_HeaderFile
diff --git a/src/TCollection/TCollection_ExtendedString.lxx b/src/TCollection/TCollection_ExtendedString.lxx
deleted file mode 100644 (file)
index 3688a66..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
-//
-// This file is part of Open CASCADE Technology software library.
-//
-// This library is free software; you can redistribute it and/or modify it under
-// the terms of the GNU Lesser General Public License version 2.1 as published
-// by the Free Software Foundation, with special exception defined in the file
-// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
-// distribution for complete text of the license and disclaimer of any warranty.
-//
-// Alternatively, this file may be used under the terms of Open CASCADE
-// commercial license or contractual agreement.
-
-//------------------------------------------------------------------------
-//  HashCode
-//------------------------------------------------------------------------
-inline Standard_Integer HashCode(const TCollection_ExtendedString& theString,
-                                 const Standard_Integer theUpper)
-{
-  return TCollection_ExtendedString::HashCode(theString, theUpper);
-}
-
-//------------------------------------------------------------------------
-//  HashCode
-//------------------------------------------------------------------------
-inline Standard_Integer 
-  TCollection_ExtendedString::HashCode (const TCollection_ExtendedString& theString,
-                                        const Standard_Integer theUpper)
-{
-  return ::HashCode(theString.ToExtString(), theUpper);
-}
-
-//------------------------------------------------------------------------
-//  IsEqual
-//------------------------------------------------------------------------
-inline Standard_Boolean
-  TCollection_ExtendedString::IsEqual (const TCollection_ExtendedString& theString1,
-                                       const TCollection_ExtendedString& theString2)
-{
-  return theString1.IsEqual(theString2);
-}
-
-//------------------------------------------------------------------------
-//  IsEmpty
-//------------------------------------------------------------------------
-inline Standard_Boolean TCollection_ExtendedString::IsEmpty() const
-{
-  return mylength == 0;
-}