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.
16 #include <OSD_Directory.hxx>
17 #include <OSD_File.hxx>
18 #include <OSD_Path.hxx>
19 #include <OSD_Protection.hxx>
20 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
21 #include <Resource_LexicalCompare.hxx>
22 #include <Resource_Manager.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>
41 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
42 TCollection_AsciiString& aToken1,
43 TCollection_AsciiString& aToken2);
45 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine);
47 static Standard_Boolean Debug;
49 Resource_Manager::Resource_Manager(const Standard_CString aName,
50 TCollection_AsciiString& aDefaultsDirectory,
51 TCollection_AsciiString& anUserDefaultsDirectory,
52 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
54 if ( !aDefaultsDirectory.IsEmpty() ) {
55 OSD_Path anOSDPath(aDefaultsDirectory);
56 anOSDPath.DownTrek(anOSDPath.Name());
57 anOSDPath.SetName(aName);
58 TCollection_AsciiString aPath;
59 anOSDPath.SystemName(aPath);
64 cout << "Resource Manager Warning: aDefaultsDirectory is empty." << endl;
66 if ( !anUserDefaultsDirectory.IsEmpty() ) {
67 OSD_Path anOSDPath(anUserDefaultsDirectory);
68 anOSDPath.DownTrek(anOSDPath.Name());
69 anOSDPath.SetName(aName);
70 TCollection_AsciiString aPath;
71 anOSDPath.SystemName(aPath);
76 cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << endl;
79 Resource_Manager::Resource_Manager(const Standard_CString aName,
80 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
82 Debug = (getenv("ResourceDebug") != NULL) ;
84 TCollection_AsciiString Directory ;
86 if ( getenv ("CSF_ResourceVerbose") != NULL )
87 myVerbose = Standard_True;
89 TCollection_AsciiString aPath,aUserPath;
90 GetResourcePath(aPath,aName,Standard_False);
91 GetResourcePath(aUserPath,aName,Standard_True);
96 cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "Defaults\" not set." << endl;
98 if (!aUserPath.IsEmpty())
99 Load(aUserPath,myRefMap);
101 cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "UserDefaults\" not set." << endl;
104 void Resource_Manager::Load(TCollection_AsciiString& aPath,
105 Resource_DataMapOfAsciiStringAsciiString& aMap)
107 Standard_Integer Kind;
108 TCollection_AsciiString Token1, Token2;
109 TCollection_AsciiString Directory, Name;
110 TCollection_AsciiString FileName;
111 OSD_File File = OSD_Path(aPath);
112 File.Open(OSD_ReadOnly,OSD_Protection());
115 cout << "Resource Manager Warning: Cannot read file \"" << FileName
116 << "\". File not found or permission denied." << endl;
119 Standard_Integer LineNumber = 1;
120 while ((Kind = WhatKindOfLine(File, Token1, Token2)) != END) {
126 if (!aMap.Bind(Token1,Token2))
127 aMap(Token1) = Token2;
131 cout << "Resource Manager: Syntax error at line "
132 << LineNumber << " in file : " << FileName << endl;
139 cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference")
140 << " file \"" << FileName << "\" loaded" << endl;
143 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
144 TCollection_AsciiString& aToken1,
145 TCollection_AsciiString& aToken2)
147 TCollection_AsciiString WhiteSpace = " \t" ;
148 Standard_Integer Pos1,Pos2,Pos ;
149 TCollection_AsciiString Line ;
151 if (!GetLine(aFile,Line))
154 if (Line.Value(1) == '!')
157 Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length());
158 if (Line.Value(Pos1) == '\n')
161 Pos2 = Line.Location(1,':',Pos1,Line.Length());
162 if (!Pos2 || Pos1 == Pos2)
165 for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--);
166 aToken1 = Line.SubString(Pos1, Pos);
169 cout << "Key = '" << aToken1 << flush ;
171 Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length());
173 if (Line.Value(Pos) == '\\')
174 switch(Line.Value(Pos+1)) {
182 if (Pos == Line.Length())
185 Line.Remove(1,Pos-1);
186 Line.Remove(Line.Length());
190 cout << "'\t Value = '" << aToken2 << "'" << endl << flush;
194 // Retourne 0 (EOF) ou une ligne toujours terminee par <NL>.
196 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine)
198 TCollection_AsciiString Buffer;
199 Standard_Integer BufSize = 10;
200 Standard_Integer Len;
204 aFile.ReadLine(Buffer,BufSize,Len);
206 if (aFile.IsAtEnd()) {
207 if (!aLine.Length()) return 0;
210 } while (aLine.Value(aLine.Length()) != '\n');
215 //=======================================================================
217 //purpose : Sort and save the user resources in the user file.
218 // Creates the file if it does not exist.
219 //=======================================================================
220 Standard_Boolean Resource_Manager::Save() const
222 TCollection_AsciiString anEnvVar("CSF_");
224 anEnvVar += "UserDefaults";
226 Standard_CString dir;
227 if ((dir = getenv (anEnvVar.ToCString())) == NULL) {
229 cout << "Resource Manager Warning: environment variable \""
230 << anEnvVar << "\" not set. Cannot save resources." << endl ;
231 return Standard_False;
234 TCollection_AsciiString aFilePath(dir);
235 OSD_Path anOSDPath(aFilePath);
236 OSD_Directory Dir = anOSDPath;
237 Standard_Boolean Status = Standard_True;
238 if ( !Dir.Exists() ) {
242 Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX));
244 catch (Standard_Failure) {
245 Status = Standard_False;
248 Status = Status && !Dir.Failed();
251 cout << "Resource Manager: Error opening or creating directory \"" << aFilePath
252 << "\". Permission denied. Cannot save resources." << endl;
253 return Standard_False;
257 anOSDPath.DownTrek(anOSDPath.Name());
258 anOSDPath.SetName(myName);
259 anOSDPath.SystemName(aFilePath);
261 OSD_File File = anOSDPath;
262 OSD_Protection theProt;
263 Status = Standard_True;
267 File.Build(OSD_ReadWrite, theProt);
269 catch (Standard_Failure) {
270 Status = Standard_False;
273 Status = Status && !File.Failed();
276 cout << "Resource Manager: Error opening or creating file \"" << aFilePath
277 << "\". Permission denied. Cannot save resources." << endl;
278 return Standard_False;
281 const Standard_Integer NbKey = myUserMap.Extent();
284 TColStd_Array1OfAsciiString KeyArray(1,NbKey);
285 Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap);
287 Standard_Integer Index;
288 for ( Index = 1; Iter.More(); Iter.Next())
289 KeyArray(Index++)= Iter.Key();
291 std::sort (KeyArray.begin(), KeyArray.end());
293 TCollection_AsciiString Line, Value;
294 for (Index = 1 ; Index <= NbKey ; Index++) {
295 Value = myUserMap(KeyArray(Index));
296 if (!Value.IsEmpty())
297 switch(Value.Value(1)) {
301 Value.Insert(1,'\\');
304 Line = KeyArray(Index) + ":\t" + Value + "\n";
307 cout << "Line = '" << Line << "'" << endl;
309 File.Write(Line, Line.Length());
312 cout << "Resource Manager: Resources saved in file " << aFilePath << endl;
315 return Standard_True;
318 //=======================================================================
320 //purpose : Gets the value of an integer resource
321 //=======================================================================
323 Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const
325 TCollection_AsciiString Result = Value(aResourceName) ;
326 if (!Result.IsIntegerValue()) {
327 TCollection_AsciiString n("Value of resource `");
329 n+= "` is not an integer";
330 Standard_TypeMismatch::Raise(n.ToCString());
332 return Result.IntegerValue();
335 //=======================================================================
337 //purpose : Gets the value of a real resource
338 //=======================================================================
340 Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const
342 TCollection_AsciiString Result = Value(aResourceName) ;
343 if (!Result.IsRealValue()) {
344 TCollection_AsciiString n("Value of resource `");
346 n+= "` is not a real";
347 Standard_TypeMismatch::Raise(n.ToCString());
349 return Result.RealValue();
352 //=======================================================================
354 //purpose : Gets the value of a CString resource
355 //=======================================================================
357 Standard_CString Resource_Manager::Value(const Standard_CString aResource) const
359 TCollection_AsciiString Resource(aResource);
360 if (myUserMap.IsBound(Resource))
361 return myUserMap(Resource).ToCString();
362 if (myRefMap.IsBound(Resource))
363 return myRefMap(Resource).ToCString();
364 Resource_NoSuchResource::Raise(aResource);
368 //=======================================================================
369 //function : ExtValue
370 //purpose : Gets the value of a ExtString resource
371 //=======================================================================
373 Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource)
375 TCollection_AsciiString Resource(aResource);
376 if (myExtStrMap.IsBound(Resource))
377 return myExtStrMap(Resource).ToExtString();
379 TCollection_AsciiString Result = Value(aResource);
380 TCollection_ExtendedString ExtResult;
382 Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult);
384 myExtStrMap.Bind(Resource, ExtResult);
385 return myExtStrMap(Resource).ToExtString();
388 //=======================================================================
389 //function : SetResource
390 //purpose : Sets the new value of an integer resource.
391 // If the resource does not exist, it is created.
392 //=======================================================================
393 void Resource_Manager::SetResource(const Standard_CString aResourceName,
394 const Standard_Integer aValue)
396 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
399 //=======================================================================
400 //function : SetResource
401 //purpose : Sets the new value of a real resource.
402 // If the resource does not exist, it is created.
403 //=======================================================================
404 void Resource_Manager::SetResource(const Standard_CString aResourceName,
405 const Standard_Real aValue)
407 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
410 //=======================================================================
411 //function : SetResource
412 //purpose : Sets the new value of ExtString resource.
413 // If the resource does not exist, it is created.
414 //=======================================================================
415 void Resource_Manager::SetResource(const Standard_CString aResource,
416 const Standard_ExtString aValue)
418 Standard_PCharacter pStr;
419 TCollection_AsciiString Resource = aResource;
420 TCollection_ExtendedString ExtValue = aValue;
421 TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' ');
423 if (!myExtStrMap.Bind(Resource,ExtValue)) {
424 myExtStrMap(Resource) = ExtValue;
427 pStr=(Standard_PCharacter)FormatStr.ToCString();
429 Resource_Unicode::ConvertUnicodeToFormat(ExtValue,
430 pStr,//FormatStr.ToCString(),
431 FormatStr.Length()) ;
432 SetResource(aResource,FormatStr.ToCString());
435 //=======================================================================
436 //function : SetResource
437 //purpose : Sets the new value of an enum resource.
438 // If the resource does not exist, it is created.
439 //=======================================================================
440 void Resource_Manager::SetResource(const Standard_CString aResource,
441 const Standard_CString aValue)
443 TCollection_AsciiString Resource = aResource;
444 TCollection_AsciiString Value = aValue;
445 if (!myUserMap.Bind(Resource, Value))
446 myUserMap(Resource) = Value;
449 //=======================================================================
451 //purpose : Tells if a resource exits.
452 //=======================================================================
453 Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
455 TCollection_AsciiString Resource(aResource);
456 if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
457 return Standard_True;
458 return Standard_False;
461 //=======================================================================
462 //function : GetResourcePath
464 //=======================================================================
466 void Resource_Manager::GetResourcePath (TCollection_AsciiString& aPath, const Standard_CString aName, const Standard_Boolean isUserDefaults)
470 TCollection_AsciiString anEnvVar("CSF_");
472 anEnvVar += isUserDefaults?"UserDefaults":"Defaults";
474 Standard_CString dir;
475 if ((dir = getenv (anEnvVar.ToCString())) == NULL)
478 TCollection_AsciiString aResPath(dir);
480 OSD_Path anOSDPath(aResPath);
481 anOSDPath.DownTrek(anOSDPath.Name());
482 anOSDPath.SetName(aName);
484 anOSDPath.SystemName(aPath);