0032565: Foundation Classes, OSD_FileSystem - expose interface for registering global...
[occt.git] / src / OSD / OSD_FileSystem.cxx
1 // Copyright (c) 2021 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <OSD_FileSystem.hxx>
15 #include <OSD_FileSystemSelector.hxx>
16 #include <OSD_LocalFileSystem.hxx>
17
18 IMPLEMENT_STANDARD_RTTIEXT(OSD_FileSystem, Standard_Transient)
19
20 //=======================================================================
21 // function : createDefaultFileSystem
22 // purpose :
23 //=======================================================================
24 static Handle(OSD_FileSystem) createDefaultFileSystem()
25 {
26   Handle(OSD_FileSystemSelector) aSystem = new OSD_FileSystemSelector();
27   aSystem->AddProtocol (new OSD_LocalFileSystem());
28   return aSystem;
29 }
30
31 //=======================================================================
32 // function : OSD_FileSystem
33 // purpose :
34 //=======================================================================
35 OSD_FileSystem::OSD_FileSystem()
36 {
37 }
38
39 //=======================================================================
40 // function : ~OSD_FileSystem
41 // purpose :
42 //=======================================================================
43 OSD_FileSystem::~OSD_FileSystem()
44 {
45 }
46
47 //=======================================================================
48 // function : DefaultFileSystem
49 // purpose :
50 //=======================================================================
51 const Handle(OSD_FileSystem)& OSD_FileSystem::DefaultFileSystem()
52 {
53   static const Handle(OSD_FileSystem) aDefSystem = createDefaultFileSystem();
54   return aDefSystem;
55 }
56
57 //=======================================================================
58 // function : AddDefaultProtocol
59 // purpose :
60 //=======================================================================
61 void OSD_FileSystem::AddDefaultProtocol (const Handle(OSD_FileSystem)& theFileSystem, bool theIsPreferred)
62 {
63   Handle(OSD_FileSystemSelector) aFileSelector = Handle(OSD_FileSystemSelector)::DownCast (DefaultFileSystem());
64   aFileSelector->AddProtocol (theFileSystem, theIsPreferred);
65 }
66
67 //=======================================================================
68 // function : RemoveDefaultProtocol
69 // purpose :
70 //=======================================================================
71 void OSD_FileSystem::RemoveDefaultProtocol (const Handle(OSD_FileSystem)& theFileSystem)
72 {
73   Handle(OSD_FileSystemSelector) aFileSelector = Handle(OSD_FileSystemSelector)::DownCast (DefaultFileSystem());
74   aFileSelector->RemoveProtocol (theFileSystem);
75 }
76
77 //=======================================================================
78 // function : openIStream
79 // purpose :
80 //=======================================================================
81 opencascade::std::shared_ptr<std::istream> OSD_FileSystem::OpenIStream (const TCollection_AsciiString& theUrl,
82                                                                         const std::ios_base::openmode theMode,
83                                                                         const int64_t theOffset,
84                                                                         const opencascade::std::shared_ptr<std::istream>& theOldStream)
85 {
86   Standard_ASSERT_RAISE (theOffset >= -1, "Incorrect negative stream position during stream opening");
87
88   opencascade::std::shared_ptr<std::istream> aNewStream;
89   opencascade::std::shared_ptr<OSD_IStreamBuffer> anOldStream = opencascade::std::dynamic_pointer_cast<OSD_IStreamBuffer> (theOldStream);
90   if (anOldStream.get() != NULL
91    && theUrl.IsEqual (anOldStream->Url().c_str())
92    && IsOpenIStream (anOldStream))
93   {
94     if (!anOldStream->good())
95     {
96       // Reset flags without re-opening
97       anOldStream->clear();
98     }
99     aNewStream = anOldStream;
100     if (theOffset >= 0)
101     {
102       aNewStream->seekg ((std::streamoff )theOffset, std::ios_base::beg);
103     }
104   }
105   if (aNewStream.get() == NULL)
106   {
107     opencascade::std::shared_ptr<std::streambuf> aFileBuf = OpenStreamBuffer (theUrl, theMode | std::ios_base::in);
108     if (aFileBuf.get() == NULL)
109     {
110       return opencascade::std::shared_ptr<std::istream>();
111     }
112
113     aNewStream.reset (new OSD_IStreamBuffer (theUrl.ToCString(), aFileBuf));
114     if (theOffset > 0)
115     {
116       aNewStream->seekg ((std::streamoff )theOffset, std::ios_base::beg);
117     }
118   }
119   return aNewStream;
120 }
121
122 //=======================================================================
123 // function : OpenOStream
124 // purpose :
125 //=======================================================================
126 opencascade::std::shared_ptr<std::ostream> OSD_FileSystem::OpenOStream (const TCollection_AsciiString& theUrl,
127                                                                         const std::ios_base::openmode theMode)
128 {
129   opencascade::std::shared_ptr<std::ostream> aNewStream;
130   opencascade::std::shared_ptr<std::streambuf> aFileBuf = OpenStreamBuffer (theUrl, theMode | std::ios_base::out);
131   if (aFileBuf.get() == NULL)
132   {
133     return opencascade::std::shared_ptr<std::ostream>();
134   }
135
136   aNewStream.reset(new OSD_OStreamBuffer (theUrl.ToCString(), aFileBuf));
137   return aNewStream;
138 }