1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 #include <Resource_Manager.hxx>
20 #include <Resource_Manager.ixx>
21 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
22 #include <Resource_QuickSortOfArray1.hxx>
23 #include <Resource_LexicalCompare.hxx>
25 #include <OSD_Path.hxx>
26 #include <OSD_File.hxx>
27 #include <OSD_Directory.hxx>
28 #include <OSD_Protection.hxx>
30 #include <Standard_ErrorHandler.hxx>
31 #include <TCollection_ExtendedString.hxx>
32 #include <Resource_Unicode.hxx>
33 #include <TColStd_Array1OfAsciiString.hxx>
44 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
45 TCollection_AsciiString& aToken1,
46 TCollection_AsciiString& aToken2);
48 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine);
50 static Standard_Boolean Debug;
52 Resource_Manager::Resource_Manager(const Standard_CString aName,
53 TCollection_AsciiString& aDefaultsDirectory,
54 TCollection_AsciiString& anUserDefaultsDirectory,
55 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
57 if ( !aDefaultsDirectory.IsEmpty() ) {
58 Load(aDefaultsDirectory,myName,myRefMap);
62 cout << "Resource Manager Warning: aDefaultsDirectory is empty." << endl;
64 if ( !anUserDefaultsDirectory.IsEmpty() ) {
65 Load(anUserDefaultsDirectory,myName,myRefMap);
69 cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << endl;
72 Resource_Manager::Resource_Manager(const Standard_CString aName,
73 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
75 Debug = (getenv("ResourceDebug") != NULL) ;
77 TCollection_AsciiString EnvVar, CSF_ = "CSF_" ;
78 TCollection_AsciiString Directory ;
79 Standard_CString dir ;
81 if ( getenv ("CSF_ResourceVerbose") != NULL )
82 myVerbose = Standard_True;
84 EnvVar = CSF_ + aName + "Defaults" ;
85 if ((dir = getenv (EnvVar.ToCString())) != NULL) {
87 Load(Directory,myName,myRefMap);
91 cout << "Resource Manager Warning: Environment variable \"" << EnvVar
92 << "\" not set." << endl;
94 EnvVar = CSF_ + aName + "UserDefaults" ;
95 if ((dir = getenv (EnvVar.ToCString())) != NULL) {
97 Load(Directory, myName, myUserMap);
101 cout << "Resource Manager Warning: Environment variable \"" << EnvVar
102 << "\" not set." << endl;
105 void Resource_Manager::Load(TCollection_AsciiString& aDirectory,
106 TCollection_AsciiString& aName,
107 Resource_DataMapOfAsciiStringAsciiString& aMap)
109 Standard_Integer Kind, Pos;
110 TCollection_AsciiString Token1, Token2;
111 TCollection_AsciiString Directory, Name;
112 TCollection_AsciiString FileName;
113 FileName = aDirectory + "/" + aName;
114 OSD_File File = OSD_Path(FileName);
115 File.Open(OSD_ReadOnly,OSD_Protection());
118 cout << "Resource Manager Warning: Cannot read file \"" << FileName
119 << "\". File not found or permission denied." << endl;
122 Standard_Integer LineNumber = 1;
123 while ((Kind = WhatKindOfLine(File, Token1, Token2)) != END) {
129 Directory = OSD_Path::AbsolutePath(aDirectory,Token1);
130 Pos = Directory.SearchFromEnd("/");
132 Name = Directory.Split(Pos);
133 Directory.Trunc(Pos-1);
134 Load(Directory,Name,aMap);
138 if (!aMap.Bind(Token1,Token2))
139 aMap(Token1) = Token2;
143 cout << "Resource Manager: Syntax error at line "
144 << LineNumber << " in file : " << FileName << endl;
151 cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference")
152 << " file \"" << FileName << "\" loaded" << endl;
155 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
156 TCollection_AsciiString& aToken1,
157 TCollection_AsciiString& aToken2)
159 TCollection_AsciiString WhiteSpace = " \t" ;
160 Standard_Integer Pos1,Pos2,Pos ;
161 TCollection_AsciiString Line ;
163 if (!GetLine(aFile,Line))
166 if (Line.Value(1) == '!')
169 if (Line.Value(1) == '#') {
171 if ((Line.Token(" \t")).IsDifferent("include"))
174 aToken1 = Line.Token(" \t\n",2);
178 Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length());
179 if (Line.Value(Pos1) == '\n')
182 Pos2 = Line.Location(1,':',Pos1,Line.Length());
183 if (!Pos2 || Pos1 == Pos2)
186 for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--);
187 aToken1 = Line.SubString(Pos1, Pos);
190 cout << "Key = '" << aToken1 << flush ;
192 if ((Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length()))) {
193 if (Line.Value(Pos) == '\\')
194 switch(Line.Value(Pos+1)) {
202 if (Pos == Line.Length())
205 aToken2 = Line.SubString(Pos,Line.Length()-1);
208 cout << "'\t Value = '" << aToken2 << "'" << endl << flush;
212 // Retourne 0 (EOF) ou une ligne toujours terminee par <NL>.
214 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine)
216 TCollection_AsciiString Buffer;
217 Standard_Integer BufSize = 10;
218 Standard_Integer Len;
222 aFile.ReadLine(Buffer,BufSize,Len);
225 if (!aLine.Length()) return 0;
227 } while (aLine.Value(aLine.Length()) != '\n');
232 //=======================================================================
234 //purpose : Sort and save the user resources in the user file.
235 // Creates the file if it does not exist.
236 //=======================================================================
237 Standard_Boolean Resource_Manager::Save() const
239 Standard_Integer Index;
240 TCollection_AsciiString EnvVar, CSF_ = "CSF_";
241 Standard_CString dir;
243 EnvVar = CSF_ + myName + "UserDefaults";
245 if ((dir = getenv (EnvVar.ToCString())) == NULL) {
247 cout << "Resource Manager Warning: environment variable \""
248 << EnvVar << "\" not set. Cannot save resources." << endl ;
249 return Standard_False;
251 TCollection_AsciiString FilePath = dir;
252 OSD_Directory Dir = OSD_Path(FilePath);
253 Standard_Boolean Status = Standard_True;
254 if ( !Dir.Exists() ) {
258 Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX));
260 catch (Standard_Failure) {
261 Status = Standard_False;
264 Status = Status && !Dir.Failed();
267 cout << "Resource Manager: Error opening or creating directory \"" << FilePath
268 << "\". Permission denied. Cannot save resources." << endl;
269 return Standard_False;
273 FilePath += "/"; FilePath += myName;
274 OSD_Path Path(FilePath);
275 OSD_File File = Path;
276 OSD_Protection theProt;
277 Status = Standard_True;
281 File.Build(OSD_ReadWrite, theProt);
283 catch (Standard_Failure) {
284 Status = Standard_False;
287 Status = Status && !File.Failed();
290 cout << "Resource Manager: Error opening or creating file \"" << FilePath
291 << "\". Permission denied. Cannot save resources." << endl;
292 return Standard_False;
295 Resource_LexicalCompare Comp;
296 Standard_Integer NbKey = myUserMap.Extent();
297 TColStd_Array1OfAsciiString KeyArray(1,NbKey+1); // 1 more item is added to allow saving empty resource
298 Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap);
300 for ( Index = 1; Iter.More(); Iter.Next())
301 KeyArray(Index++)= Iter.Key();
303 Resource_QuickSortOfArray1::Sort(KeyArray, Comp);
305 TCollection_AsciiString Line, Value;
306 for (Index = 1 ; Index <= NbKey ; Index++) {
307 Value = myUserMap(KeyArray(Index));
308 if (!Value.IsEmpty())
309 switch(Value.Value(1)) {
313 Value.Insert(1,'\\');
316 Line = KeyArray(Index) + ":\t" + Value + "\n";
319 cout << "Line = '" << Line << "'" << endl;
321 File.Write(Line, Line.Length());
324 cout << "Resource Manager: Resources saved in file " << FilePath << endl;
326 return Standard_True;
329 //=======================================================================
331 //purpose : Gets the value of an integer resource
332 //=======================================================================
334 Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const
336 TCollection_AsciiString Result = Value(aResourceName) ;
337 if (!Result.IsIntegerValue()) {
338 TCollection_AsciiString n("Value of resource `");
340 n+= "` is not an integer";
341 Standard_TypeMismatch::Raise(n.ToCString());
343 return Result.IntegerValue();
346 //=======================================================================
348 //purpose : Gets the value of a real resource
349 //=======================================================================
351 Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const
353 TCollection_AsciiString Result = Value(aResourceName) ;
354 if (!Result.IsRealValue()) {
355 TCollection_AsciiString n("Value of resource `");
357 n+= "` is not a real";
358 Standard_TypeMismatch::Raise(n.ToCString());
360 return Result.RealValue();
363 //=======================================================================
365 //purpose : Gets the value of a CString resource
366 //=======================================================================
368 Standard_CString Resource_Manager::Value(const Standard_CString aResource) const
370 TCollection_AsciiString Resource(aResource);
371 if (myUserMap.IsBound(Resource))
372 return myUserMap(Resource).ToCString();
373 if (myRefMap.IsBound(Resource))
374 return myRefMap(Resource).ToCString();
375 Resource_NoSuchResource::Raise(aResource);
379 //=======================================================================
380 //function : ExtValue
381 //purpose : Gets the value of a ExtString resource
382 //=======================================================================
384 Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource)
386 TCollection_AsciiString Resource(aResource);
387 if (myExtStrMap.IsBound(Resource))
388 return myExtStrMap(Resource).ToExtString();
390 TCollection_AsciiString Result = Value(aResource);
391 TCollection_ExtendedString ExtResult;
393 Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult);
395 myExtStrMap.Bind(Resource, ExtResult);
396 return myExtStrMap(Resource).ToExtString();
399 //=======================================================================
400 //function : SetResource
401 //purpose : Sets the new value of an integer resource.
402 // If the resource does not exist, it is created.
403 //=======================================================================
404 void Resource_Manager::SetResource(const Standard_CString aResourceName,
405 const Standard_Integer aValue)
407 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
410 //=======================================================================
411 //function : SetResource
412 //purpose : Sets the new value of a real resource.
413 // If the resource does not exist, it is created.
414 //=======================================================================
415 void Resource_Manager::SetResource(const Standard_CString aResourceName,
416 const Standard_Real aValue)
418 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
421 //=======================================================================
422 //function : SetResource
423 //purpose : Sets the new value of ExtString resource.
424 // If the resource does not exist, it is created.
425 //=======================================================================
426 void Resource_Manager::SetResource(const Standard_CString aResource,
427 const Standard_ExtString aValue)
429 Standard_PCharacter pStr;
430 TCollection_AsciiString Resource = aResource;
431 TCollection_ExtendedString ExtValue = aValue;
432 TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' ');
434 if (!myExtStrMap.Bind(Resource,ExtValue)) {
435 myExtStrMap(Resource) = ExtValue;
438 pStr=(Standard_PCharacter)FormatStr.ToCString();
440 Resource_Unicode::ConvertUnicodeToFormat(ExtValue,
441 pStr,//FormatStr.ToCString(),
442 FormatStr.Length()) ;
443 SetResource(aResource,FormatStr.ToCString());
446 //=======================================================================
447 //function : SetResource
448 //purpose : Sets the new value of an enum resource.
449 // If the resource does not exist, it is created.
450 //=======================================================================
451 void Resource_Manager::SetResource(const Standard_CString aResource,
452 const Standard_CString aValue)
454 TCollection_AsciiString Resource = aResource;
455 TCollection_AsciiString Value = aValue;
456 if (!myUserMap.Bind(Resource, Value))
457 myUserMap(Resource) = Value;
460 //=======================================================================
462 //purpose : Tells if a resource exits.
463 //=======================================================================
464 Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
466 TCollection_AsciiString Resource(aResource);
467 if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
468 return Standard_True;
469 return Standard_False;