1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Resource_Manager.hxx>
17 #include <OSD_Directory.hxx>
18 #include <OSD_Environment.hxx>
19 #include <OSD_File.hxx>
20 #include <OSD_Path.hxx>
21 #include <OSD_Protection.hxx>
22 #include <Resource_LexicalCompare.hxx>
23 #include <Resource_NoSuchResource.hxx>
24 #include <Resource_Unicode.hxx>
25 #include <Standard_ErrorHandler.hxx>
26 #include <Standard_OutOfRange.hxx>
27 #include <Standard_Type.hxx>
28 #include <Standard_TypeMismatch.hxx>
29 #include <TCollection_AsciiString.hxx>
30 #include <TCollection_ExtendedString.hxx>
31 #include <TColStd_Array1OfAsciiString.hxx>
36 IMPLEMENT_STANDARD_RTTIEXT(Resource_Manager,Standard_Transient)
38 //! Auxiliary enumeration for function WhatKindOfLine().
39 enum Resource_KindOfLine
44 Resource_KOL_Resource,
48 static Resource_KindOfLine WhatKindOfLine(OSD_File& aFile,
49 TCollection_AsciiString& aToken1,
50 TCollection_AsciiString& aToken2);
52 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine);
54 static Standard_Boolean Debug;
56 // =======================================================================
57 // function : Resource_Manager
59 // =======================================================================
60 Resource_Manager::Resource_Manager (const TCollection_AsciiString& theName,
61 const TCollection_AsciiString& theDefaultsDirectory,
62 const TCollection_AsciiString& theUserDefaultsDirectory,
63 const Standard_Boolean theIsVerbose)
65 myVerbose (theIsVerbose)
67 if (!theDefaultsDirectory.IsEmpty())
69 OSD_Path anOSDPath (theDefaultsDirectory);
70 if (!anOSDPath.Name().IsEmpty())
72 anOSDPath.DownTrek (anOSDPath.Name() + anOSDPath.Extension());
74 anOSDPath.SetName (theName);
75 anOSDPath.SetExtension ("");
76 TCollection_AsciiString aPath;
77 anOSDPath.SystemName (aPath);
78 Load (aPath, myRefMap);
82 std::cout << "Resource Manager Warning: aDefaultsDirectory is empty." << std::endl;
85 if (!theUserDefaultsDirectory.IsEmpty())
87 OSD_Path anOSDPath (theUserDefaultsDirectory);
88 if (!anOSDPath.Name().IsEmpty())
90 anOSDPath.DownTrek (anOSDPath.Name() + anOSDPath.Extension());
92 anOSDPath.SetName (theName);
93 anOSDPath.SetExtension ("");
94 TCollection_AsciiString aPath;
95 anOSDPath.SystemName (aPath);
96 Load (aPath, myRefMap);
100 std::cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << std::endl;
104 Resource_Manager::Resource_Manager(const Standard_CString aName,
105 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
107 OSD_Environment envDebug("ResourceDebug");
108 Debug = (!envDebug.Value().IsEmpty()) ;
110 TCollection_AsciiString Directory ;
112 OSD_Environment envVerbose("CSF_ResourceVerbose");
113 if (!envVerbose.Value().IsEmpty())
114 myVerbose = Standard_True;
116 TCollection_AsciiString aPath,aUserPath;
117 GetResourcePath(aPath,aName,Standard_False);
118 GetResourcePath(aUserPath,aName,Standard_True);
120 if (!aPath.IsEmpty())
121 Load(aPath,myRefMap);
123 std::cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "Defaults\" not set." << std::endl;
125 if (!aUserPath.IsEmpty())
126 Load(aUserPath,myRefMap);
128 std::cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "UserDefaults\" not set." << std::endl;
131 // =======================================================================
132 // function : Resource_Manager
134 // =======================================================================
135 Resource_Manager::Resource_Manager()
136 : myName(""), myVerbose(Standard_False)
141 // =======================================================================
144 // =======================================================================
145 void Resource_Manager::Load(const TCollection_AsciiString& thePath,
146 Resource_DataMapOfAsciiStringAsciiString& aMap)
148 Resource_KindOfLine aKind;
149 TCollection_AsciiString Token1, Token2;
150 OSD_Path Path (thePath);
151 OSD_File File = Path;
152 TCollection_AsciiString FileName = Path.Name();
153 File.Open(OSD_ReadOnly,OSD_Protection());
156 std::cout << "Resource Manager Warning: Cannot read file \"" << FileName
157 << "\". File not found or permission denied." << std::endl;
160 Standard_Integer LineNumber = 1;
161 while ((aKind = WhatKindOfLine(File, Token1, Token2)) != Resource_KOL_End) {
163 case Resource_KOL_End:
164 case Resource_KOL_Comment:
165 case Resource_KOL_Empty:
167 case Resource_KOL_Resource:
168 if (!aMap.Bind(Token1,Token2))
169 aMap(Token1) = Token2;
171 case Resource_KOL_Error:
173 std::cout << "Resource Manager: Syntax error at line "
174 << LineNumber << " in file : " << FileName << std::endl;
181 std::cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference")
182 << " file \"" << FileName << "\" loaded" << std::endl;
185 static Resource_KindOfLine WhatKindOfLine(OSD_File& aFile,
186 TCollection_AsciiString& aToken1,
187 TCollection_AsciiString& aToken2)
189 TCollection_AsciiString WhiteSpace = " \t" ;
190 Standard_Integer Pos1,Pos2,Pos ;
191 TCollection_AsciiString Line ;
193 if (!GetLine(aFile,Line))
194 return Resource_KOL_End;
196 if (Line.Value(1) == '!')
197 return Resource_KOL_Comment;
199 Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length());
200 if (Line.Value(Pos1) == '\n')
201 return Resource_KOL_Empty;
203 Pos2 = Line.Location(1,':',Pos1,Line.Length());
204 if (!Pos2 || Pos1 == Pos2)
205 return Resource_KOL_Error;
207 for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--);
208 aToken1 = Line.SubString(Pos1, Pos);
211 std::cout << "Key = '" << aToken1 << std::flush ;
213 Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length());
215 if (Line.Value(Pos) == '\\')
216 switch(Line.Value(Pos+1)) {
224 if (Pos == Line.Length())
227 Line.Remove(1,Pos-1);
228 const Standard_Integer aLineLength = Line.Length();
229 if (aLineLength >= 2)
231 if (Line.Value(aLineLength - 1) == '\r')
233 Line.Remove(aLineLength - 1);
236 Line.Remove(Line.Length());
240 std::cout << "'\t Value = '" << aToken2 << "'" << std::endl << std::flush;
241 return Resource_KOL_Resource;
244 // Retourne 0 (EOF) ou une ligne toujours terminee par <NL>.
246 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine)
248 TCollection_AsciiString Buffer;
249 Standard_Integer BufSize = 10;
250 Standard_Integer Len;
254 aFile.ReadLine(Buffer,BufSize,Len);
256 if (aFile.IsAtEnd()) {
257 if (!aLine.Length()) return 0;
260 } while (aLine.Value(aLine.Length()) != '\n');
265 //=======================================================================
267 //purpose : Sort and save the user resources in the user file.
268 // Creates the file if it does not exist.
269 //=======================================================================
270 Standard_Boolean Resource_Manager::Save() const
272 TCollection_AsciiString anEnvVar("CSF_");
274 anEnvVar += "UserDefaults";
276 TCollection_AsciiString dir;
277 OSD_Environment anEnv(anEnvVar);
281 std::cout << "Resource Manager Warning: environment variable \""
282 << anEnvVar << "\" not set. Cannot save resources." << std::endl ;
283 return Standard_False;
286 TCollection_AsciiString aFilePath(dir);
287 OSD_Path anOSDPath(aFilePath);
288 OSD_Directory Dir = anOSDPath;
289 Standard_Boolean aStatus = Standard_True;
290 if ( !Dir.Exists() ) {
294 Dir.Build(OSD_Protection(OSD_RX, OSD_RWXD, OSD_RX, OSD_RX));
296 catch (Standard_Failure const&) {
297 aStatus = Standard_False;
300 aStatus = aStatus && !Dir.Failed();
303 std::cout << "Resource Manager: Error opening or creating directory \"" << aFilePath
304 << "\". Permission denied. Cannot save resources." << std::endl;
305 return Standard_False;
309 if (!anOSDPath.Name().IsEmpty())
311 anOSDPath.DownTrek (anOSDPath.Name () + anOSDPath.Extension ());
313 anOSDPath.SetName(myName);
314 anOSDPath.SetExtension("");
315 anOSDPath.SystemName(aFilePath);
317 OSD_File File = anOSDPath;
318 OSD_Protection theProt;
319 aStatus = Standard_True;
323 File.Build(OSD_ReadWrite, theProt);
325 catch (Standard_Failure const&) {
326 aStatus = Standard_False;
329 aStatus = aStatus && !File.Failed();
332 std::cout << "Resource Manager: Error opening or creating file \"" << aFilePath
333 << "\". Permission denied. Cannot save resources." << std::endl;
334 return Standard_False;
337 const Standard_Integer NbKey = myUserMap.Extent();
340 TColStd_Array1OfAsciiString KeyArray(1,NbKey);
341 Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap);
343 Standard_Integer Index;
344 for ( Index = 1; Iter.More(); Iter.Next())
345 KeyArray(Index++)= Iter.Key();
347 std::sort (KeyArray.begin(), KeyArray.end());
349 TCollection_AsciiString Line, Value;
350 for (Index = 1 ; Index <= NbKey ; Index++) {
351 Value = myUserMap(KeyArray(Index));
352 if (!Value.IsEmpty())
353 switch(Value.Value(1)) {
357 Value.Insert(1,'\\');
360 Line = KeyArray(Index) + ":\t" + Value + "\n";
363 std::cout << "Line = '" << Line << "'" << std::endl;
365 File.Write(Line, Line.Length());
368 std::cout << "Resource Manager: Resources saved in file " << aFilePath << std::endl;
371 return Standard_True;
374 //=======================================================================
376 //purpose : Gets the value of an integer resource
377 //=======================================================================
379 Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const
381 TCollection_AsciiString Result = Value(aResourceName) ;
382 if (!Result.IsIntegerValue()) {
383 TCollection_AsciiString n("Value of resource `");
385 n+= "` is not an integer";
386 throw Standard_TypeMismatch(n.ToCString());
388 return Result.IntegerValue();
391 //=======================================================================
393 //purpose : Gets the value of a real resource
394 //=======================================================================
396 Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const
398 TCollection_AsciiString Result = Value(aResourceName) ;
399 if (!Result.IsRealValue()) {
400 TCollection_AsciiString n("Value of resource `");
402 n+= "` is not a real";
403 throw Standard_TypeMismatch(n.ToCString());
405 return Result.RealValue();
408 //=======================================================================
410 //purpose : Gets the value of a CString resource
411 //=======================================================================
413 Standard_CString Resource_Manager::Value(const Standard_CString aResource) const
415 TCollection_AsciiString Resource(aResource);
416 if (myUserMap.IsBound(Resource))
417 return myUserMap(Resource).ToCString();
418 if (myRefMap.IsBound(Resource))
419 return myRefMap(Resource).ToCString();
420 throw Resource_NoSuchResource(aResource);
423 //=======================================================================
424 //function : ExtValue
425 //purpose : Gets the value of a ExtString resource
426 //=======================================================================
428 Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource)
430 TCollection_AsciiString Resource(aResource);
431 if (myExtStrMap.IsBound(Resource))
432 return myExtStrMap(Resource).ToExtString();
434 TCollection_AsciiString Result = Value(aResource);
435 TCollection_ExtendedString ExtResult;
437 Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult);
439 myExtStrMap.Bind(Resource, ExtResult);
440 return myExtStrMap(Resource).ToExtString();
443 //=======================================================================
444 //function : SetResource
445 //purpose : Sets the new value of an integer resource.
446 // If the resource does not exist, it is created.
447 //=======================================================================
448 void Resource_Manager::SetResource(const Standard_CString aResourceName,
449 const Standard_Integer aValue)
451 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
454 //=======================================================================
455 //function : SetResource
456 //purpose : Sets the new value of a real resource.
457 // If the resource does not exist, it is created.
458 //=======================================================================
459 void Resource_Manager::SetResource(const Standard_CString aResourceName,
460 const Standard_Real aValue)
462 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
465 //=======================================================================
466 //function : SetResource
467 //purpose : Sets the new value of ExtString resource.
468 // If the resource does not exist, it is created.
469 //=======================================================================
470 void Resource_Manager::SetResource(const Standard_CString aResource,
471 const Standard_ExtString aValue)
473 Standard_PCharacter pStr;
474 TCollection_AsciiString Resource = aResource;
475 TCollection_ExtendedString ExtValue = aValue;
476 TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' ');
478 if (!myExtStrMap.Bind(Resource,ExtValue)) {
479 myExtStrMap(Resource) = ExtValue;
482 pStr=(Standard_PCharacter)FormatStr.ToCString();
484 Resource_Unicode::ConvertUnicodeToFormat(ExtValue,
485 pStr,//FormatStr.ToCString(),
486 FormatStr.Length()) ;
487 SetResource(aResource,FormatStr.ToCString());
490 //=======================================================================
491 //function : SetResource
492 //purpose : Sets the new value of an enum resource.
493 // If the resource does not exist, it is created.
494 //=======================================================================
495 void Resource_Manager::SetResource(const Standard_CString aResource,
496 const Standard_CString aValue)
498 TCollection_AsciiString Resource = aResource;
499 TCollection_AsciiString Value = aValue;
500 if (!myUserMap.Bind(Resource, Value))
501 myUserMap(Resource) = Value;
504 //=======================================================================
506 //purpose : Tells if a resource exits.
507 //=======================================================================
508 Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
510 TCollection_AsciiString Resource(aResource);
511 if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
512 return Standard_True;
513 return Standard_False;
516 //=======================================================================
519 //=======================================================================
520 Standard_Boolean Resource_Manager::Find (const TCollection_AsciiString& theResource,
521 TCollection_AsciiString& theValue) const
523 return myUserMap.Find (theResource, theValue)
524 || myRefMap .Find (theResource, theValue);
527 //=======================================================================
528 //function : GetResourcePath
530 //=======================================================================
532 void Resource_Manager::GetResourcePath (TCollection_AsciiString& aPath, const Standard_CString aName, const Standard_Boolean isUserDefaults)
536 TCollection_AsciiString anEnvVar("CSF_");
538 anEnvVar += isUserDefaults?"UserDefaults":"Defaults";
540 TCollection_AsciiString dir;
541 OSD_Environment anEnv(anEnvVar);
546 TCollection_AsciiString aResPath(dir);
548 OSD_Path anOSDPath(aResPath);
550 if (!anOSDPath.Name().IsEmpty())
552 anOSDPath.DownTrek (anOSDPath.Name () + anOSDPath.Extension ());
554 anOSDPath.SetName (aName);
555 anOSDPath.SetExtension ("");
557 anOSDPath.SystemName(aPath);
560 //=======================================================================
563 //=======================================================================
564 Resource_DataMapOfAsciiStringAsciiString& Resource_Manager::GetMap(Standard_Boolean theRefMap)
566 return theRefMap ? myRefMap : myUserMap;