0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / PCDM / PCDM_ReadWriter.cxx
1 // Created on: 1997-12-09
2 // Created by: Jean-Louis Frenkel
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <CDM_Document.hxx>
19 #include <PCDM.hxx>
20 #include <PCDM_DOMHeaderParser.hxx>
21 #include <PCDM_ReadWriter.hxx>
22 #include <PCDM_ReadWriter_1.hxx>
23 #include <Standard_ErrorHandler.hxx>
24 #include <Standard_Type.hxx>
25 #include <Storage_BaseDriver.hxx>
26 #include <Storage_Data.hxx>
27 #include <Storage_HeaderData.hxx>
28 #include <Storage_TypeData.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <TCollection_ExtendedString.hxx>
31 #include <TColStd_HSequenceOfAsciiString.hxx>
32 #include <UTL.hxx>
33
34 IMPLEMENT_STANDARD_RTTIEXT(PCDM_ReadWriter,Standard_Transient)
35
36 #define FILE_FORMAT "FILE_FORMAT: "
37
38 static TCollection_ExtendedString TryXmlDriverType
39                                 (const TCollection_AsciiString& theFileName);
40
41 static TCollection_ExtendedString TryXmlDriverType (Standard_IStream& theIStream);
42
43 //=======================================================================
44 //function : Open
45 //purpose  : 
46 //=======================================================================
47
48 void PCDM_ReadWriter::Open (const Handle(Storage_BaseDriver)&   aDriver,
49                             const TCollection_ExtendedString&   aFileName,
50                             const Storage_OpenMode              aMode)
51 {
52   Storage_Error error = UTL::OpenFile(aDriver,aFileName,aMode);
53   if(error != Storage_VSOk) {
54     Standard_SStream aMsg; aMsg << "could not open the file: ";
55     aMsg << aFileName;
56     switch (error) {
57     case Storage_VSOpenError: aMsg << "; file was not found or permission denied"; break;
58     case Storage_VSAlreadyOpen: aMsg<< "; file was already opened";
59     default:
60       break;
61     }
62     aMsg << (char)0;
63     throw Standard_Failure(aMsg.str().c_str());
64   }
65 }
66
67 //=======================================================================
68 //function : Reader
69 //purpose  : 
70 //=======================================================================
71
72 Handle(PCDM_ReadWriter) PCDM_ReadWriter::Reader (const TCollection_ExtendedString&)
73 {
74   return (new PCDM_ReadWriter_1);
75 }
76
77 //=======================================================================
78 //function : Writer
79 //purpose  : 
80 //=======================================================================
81
82 Handle(PCDM_ReadWriter) PCDM_ReadWriter::Writer()
83 {
84   return (new PCDM_ReadWriter_1);
85 }
86  
87 //=======================================================================
88 //function : WriteFileFormat
89 //purpose  : 
90 //=======================================================================
91
92 void PCDM_ReadWriter::WriteFileFormat (const Handle(Storage_Data)& aData,
93                                        const Handle(CDM_Document)& aDocument)
94
95   TCollection_AsciiString ligne(FILE_FORMAT);
96   ligne += TCollection_AsciiString(aDocument->StorageFormat(),'?');
97
98   aData->AddToUserInfo(ligne);
99 }
100
101 //=======================================================================
102 //function : FileFormat
103 //purpose  : 
104 //=======================================================================
105
106 TCollection_ExtendedString PCDM_ReadWriter::FileFormat
107                                 (const TCollection_ExtendedString& aFileName)
108 {
109   TCollection_ExtendedString theFormat;
110   
111   Handle(Storage_BaseDriver) theFileDriver;
112
113   // conversion to UTF-8 is done inside
114   TCollection_AsciiString theFileName (aFileName);
115   if (PCDM::FileDriverType (theFileName, theFileDriver) == PCDM_TOFD_Unknown)
116     return ::TryXmlDriverType (theFileName);
117
118   Standard_Boolean theFileIsOpen(Standard_False);
119   try {
120     OCC_CATCH_SIGNALS
121     
122     Open(theFileDriver,aFileName,Storage_VSRead);
123     theFileIsOpen=Standard_True;
124     Storage_HeaderData hd;
125     hd.Read (theFileDriver);
126     const TColStd_SequenceOfAsciiString &refUserInfo = hd.UserInfo();
127     Standard_Boolean found=Standard_False;
128     for (Standard_Integer i =1; !found && i<=  refUserInfo.Length() ; i++) {
129       if(refUserInfo(i).Search(FILE_FORMAT) != -1) {
130         found=Standard_True;
131         theFormat=TCollection_ExtendedString(refUserInfo(i).Token(" ",2).ToCString(),
132                                              Standard_True);
133       }
134     }
135     if (!found)
136     {
137       Storage_TypeData td;
138       td.Read (theFileDriver);
139       theFormat = td.Types()->Value(1);
140     }
141   }
142   catch (Standard_Failure const&) {}
143   
144   if(theFileIsOpen)
145   {
146     theFileDriver->Close();
147   }
148
149   return theFormat;
150 }
151
152 //=======================================================================
153 //function : FileFormat
154 //purpose  : 
155 //=======================================================================
156
157 TCollection_ExtendedString PCDM_ReadWriter::FileFormat (Standard_IStream& theIStream, Handle(Storage_Data)& theData)
158 {
159   TCollection_ExtendedString aFormat;
160
161   Handle(Storage_BaseDriver) aFileDriver;
162   if (PCDM::FileDriverType (theIStream, aFileDriver) == PCDM_TOFD_XmlFile)
163   {
164     return ::TryXmlDriverType (theIStream);
165   }
166   if (!aFileDriver)
167   {
168     // type is not recognized, return empty string
169     return aFormat;
170   }
171
172   aFileDriver->ReadCompleteInfo (theIStream, theData);
173
174   for (Standard_Integer i = 1; i <= theData->HeaderData()->UserInfo().Length(); i++)
175   {
176     const TCollection_AsciiString& aLine = theData->HeaderData()->UserInfo().Value(i);
177
178     if(aLine.Search (FILE_FORMAT) != -1)
179     {
180       aFormat = TCollection_ExtendedString (aLine.Token(" ",2).ToCString(), Standard_True);
181     }
182   }
183
184   return aFormat;
185 }
186
187 //=======================================================================
188 //function : ::TryXmlDriverType
189 //purpose  : called from FileFormat()
190 //=======================================================================
191
192 static TCollection_ExtendedString TryXmlDriverType
193                                 (const TCollection_AsciiString& theFileName)
194 {
195   TCollection_ExtendedString theFormat;
196   PCDM_DOMHeaderParser       aParser;
197   const char                 * aDocumentElementName = "document";
198   aParser.SetStartElementName (Standard_CString(aDocumentElementName));
199
200   // Parse the file; if there is no error or an error appears before retrieval
201   // of the DocumentElement, the XML format cannot be defined
202   if (aParser.parse (theFileName.ToCString()))
203   {
204     LDOM_Element anElement = aParser.GetElement();
205     if (anElement.getTagName().equals (LDOMString(aDocumentElementName)))
206       theFormat = anElement.getAttribute ("format");
207   }
208   return theFormat;
209 }
210
211 //=======================================================================
212 //function : ::TryXmlDriverType
213 //purpose  : called from FileFormat()
214 //=======================================================================
215
216 static TCollection_ExtendedString TryXmlDriverType (Standard_IStream& theIStream)
217 {
218   TCollection_ExtendedString theFormat;
219   PCDM_DOMHeaderParser       aParser;
220   const char                 * aDocumentElementName = "document";
221   aParser.SetStartElementName (Standard_CString(aDocumentElementName));
222
223   if (theIStream.good())
224   {
225     // Parse the file; if there is no error or an error appears before retrieval
226     // of the DocumentElement, the XML format cannot be defined
227     if (aParser.parse (theIStream, Standard_True))
228     {
229       LDOM_Element anElement = aParser.GetElement();
230       if (anElement.getTagName().equals (LDOMString(aDocumentElementName)))
231         theFormat = anElement.getAttribute ("format");
232     }
233   }
234
235   return theFormat;
236 }