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>
36 //! Auxiliary enumeration for function WhatKindOfLine().
37 enum Resource_KindOfLine
42 Resource_KOL_Resource,
46 static Resource_KindOfLine WhatKindOfLine(OSD_File& aFile,
47 TCollection_AsciiString& aToken1,
48 TCollection_AsciiString& aToken2);
50 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine);
52 static Standard_Boolean Debug;
54 Resource_Manager::Resource_Manager(const Standard_CString aName,
55 TCollection_AsciiString& aDefaultsDirectory,
56 TCollection_AsciiString& anUserDefaultsDirectory,
57 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
59 if ( !aDefaultsDirectory.IsEmpty() ) {
60 OSD_Path anOSDPath(aDefaultsDirectory);
61 anOSDPath.DownTrek(anOSDPath.Name());
62 anOSDPath.SetName(aName);
63 TCollection_AsciiString aPath;
64 anOSDPath.SystemName(aPath);
69 cout << "Resource Manager Warning: aDefaultsDirectory is empty." << endl;
71 if ( !anUserDefaultsDirectory.IsEmpty() ) {
72 OSD_Path anOSDPath(anUserDefaultsDirectory);
73 anOSDPath.DownTrek(anOSDPath.Name());
74 anOSDPath.SetName(aName);
75 TCollection_AsciiString aPath;
76 anOSDPath.SystemName(aPath);
81 cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << endl;
84 Resource_Manager::Resource_Manager(const Standard_CString aName,
85 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
87 Debug = (getenv("ResourceDebug") != NULL) ;
89 TCollection_AsciiString Directory ;
91 if ( getenv ("CSF_ResourceVerbose") != NULL )
92 myVerbose = Standard_True;
94 TCollection_AsciiString aPath,aUserPath;
95 GetResourcePath(aPath,aName,Standard_False);
96 GetResourcePath(aUserPath,aName,Standard_True);
101 cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "Defaults\" not set." << endl;
103 if (!aUserPath.IsEmpty())
104 Load(aUserPath,myRefMap);
106 cout << "Resource Manager Warning: Environment variable \"CSF_" << aName << "UserDefaults\" not set." << endl;
109 void Resource_Manager::Load(TCollection_AsciiString& aPath,
110 Resource_DataMapOfAsciiStringAsciiString& aMap)
112 Resource_KindOfLine aKind;
113 TCollection_AsciiString Token1, Token2;
114 TCollection_AsciiString Directory, Name;
115 TCollection_AsciiString FileName;
116 OSD_File File = OSD_Path(aPath);
117 File.Open(OSD_ReadOnly,OSD_Protection());
120 cout << "Resource Manager Warning: Cannot read file \"" << FileName
121 << "\". File not found or permission denied." << endl;
124 Standard_Integer LineNumber = 1;
125 while ((aKind = WhatKindOfLine(File, Token1, Token2)) != Resource_KOL_End) {
127 case Resource_KOL_End:
128 case Resource_KOL_Comment:
129 case Resource_KOL_Empty:
131 case Resource_KOL_Resource:
132 if (!aMap.Bind(Token1,Token2))
133 aMap(Token1) = Token2;
135 case Resource_KOL_Error:
137 cout << "Resource Manager: Syntax error at line "
138 << LineNumber << " in file : " << FileName << endl;
145 cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference")
146 << " file \"" << FileName << "\" loaded" << endl;
149 static Resource_KindOfLine WhatKindOfLine(OSD_File& aFile,
150 TCollection_AsciiString& aToken1,
151 TCollection_AsciiString& aToken2)
153 TCollection_AsciiString WhiteSpace = " \t" ;
154 Standard_Integer Pos1,Pos2,Pos ;
155 TCollection_AsciiString Line ;
157 if (!GetLine(aFile,Line))
158 return Resource_KOL_End;
160 if (Line.Value(1) == '!')
161 return Resource_KOL_Comment;
163 Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length());
164 if (Line.Value(Pos1) == '\n')
165 return Resource_KOL_Empty;
167 Pos2 = Line.Location(1,':',Pos1,Line.Length());
168 if (!Pos2 || Pos1 == Pos2)
169 return Resource_KOL_Error;
171 for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--);
172 aToken1 = Line.SubString(Pos1, Pos);
175 cout << "Key = '" << aToken1 << flush ;
177 Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length());
179 if (Line.Value(Pos) == '\\')
180 switch(Line.Value(Pos+1)) {
188 if (Pos == Line.Length())
191 Line.Remove(1,Pos-1);
192 Line.Remove(Line.Length());
196 cout << "'\t Value = '" << aToken2 << "'" << endl << flush;
197 return Resource_KOL_Resource;
200 // Retourne 0 (EOF) ou une ligne toujours terminee par <NL>.
202 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine)
204 TCollection_AsciiString Buffer;
205 Standard_Integer BufSize = 10;
206 Standard_Integer Len;
210 aFile.ReadLine(Buffer,BufSize,Len);
212 if (aFile.IsAtEnd()) {
213 if (!aLine.Length()) return 0;
216 } while (aLine.Value(aLine.Length()) != '\n');
221 //=======================================================================
223 //purpose : Sort and save the user resources in the user file.
224 // Creates the file if it does not exist.
225 //=======================================================================
226 Standard_Boolean Resource_Manager::Save() const
228 TCollection_AsciiString anEnvVar("CSF_");
230 anEnvVar += "UserDefaults";
232 Standard_CString dir;
233 if ((dir = getenv (anEnvVar.ToCString())) == NULL) {
235 cout << "Resource Manager Warning: environment variable \""
236 << anEnvVar << "\" not set. Cannot save resources." << endl ;
237 return Standard_False;
240 TCollection_AsciiString aFilePath(dir);
241 OSD_Path anOSDPath(aFilePath);
242 OSD_Directory Dir = anOSDPath;
243 Standard_Boolean Status = Standard_True;
244 if ( !Dir.Exists() ) {
248 Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX));
250 catch (Standard_Failure) {
251 Status = Standard_False;
254 Status = Status && !Dir.Failed();
257 cout << "Resource Manager: Error opening or creating directory \"" << aFilePath
258 << "\". Permission denied. Cannot save resources." << endl;
259 return Standard_False;
263 anOSDPath.DownTrek(anOSDPath.Name());
264 anOSDPath.SetName(myName);
265 anOSDPath.SystemName(aFilePath);
267 OSD_File File = anOSDPath;
268 OSD_Protection theProt;
269 Status = Standard_True;
273 File.Build(OSD_ReadWrite, theProt);
275 catch (Standard_Failure) {
276 Status = Standard_False;
279 Status = Status && !File.Failed();
282 cout << "Resource Manager: Error opening or creating file \"" << aFilePath
283 << "\". Permission denied. Cannot save resources." << endl;
284 return Standard_False;
287 const Standard_Integer NbKey = myUserMap.Extent();
290 TColStd_Array1OfAsciiString KeyArray(1,NbKey);
291 Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap);
293 Standard_Integer Index;
294 for ( Index = 1; Iter.More(); Iter.Next())
295 KeyArray(Index++)= Iter.Key();
297 std::sort (KeyArray.begin(), KeyArray.end());
299 TCollection_AsciiString Line, Value;
300 for (Index = 1 ; Index <= NbKey ; Index++) {
301 Value = myUserMap(KeyArray(Index));
302 if (!Value.IsEmpty())
303 switch(Value.Value(1)) {
307 Value.Insert(1,'\\');
310 Line = KeyArray(Index) + ":\t" + Value + "\n";
313 cout << "Line = '" << Line << "'" << endl;
315 File.Write(Line, Line.Length());
318 cout << "Resource Manager: Resources saved in file " << aFilePath << endl;
321 return Standard_True;
324 //=======================================================================
326 //purpose : Gets the value of an integer resource
327 //=======================================================================
329 Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const
331 TCollection_AsciiString Result = Value(aResourceName) ;
332 if (!Result.IsIntegerValue()) {
333 TCollection_AsciiString n("Value of resource `");
335 n+= "` is not an integer";
336 Standard_TypeMismatch::Raise(n.ToCString());
338 return Result.IntegerValue();
341 //=======================================================================
343 //purpose : Gets the value of a real resource
344 //=======================================================================
346 Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const
348 TCollection_AsciiString Result = Value(aResourceName) ;
349 if (!Result.IsRealValue()) {
350 TCollection_AsciiString n("Value of resource `");
352 n+= "` is not a real";
353 Standard_TypeMismatch::Raise(n.ToCString());
355 return Result.RealValue();
358 //=======================================================================
360 //purpose : Gets the value of a CString resource
361 //=======================================================================
363 Standard_CString Resource_Manager::Value(const Standard_CString aResource) const
365 TCollection_AsciiString Resource(aResource);
366 if (myUserMap.IsBound(Resource))
367 return myUserMap(Resource).ToCString();
368 if (myRefMap.IsBound(Resource))
369 return myRefMap(Resource).ToCString();
370 Resource_NoSuchResource::Raise(aResource);
374 //=======================================================================
375 //function : ExtValue
376 //purpose : Gets the value of a ExtString resource
377 //=======================================================================
379 Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource)
381 TCollection_AsciiString Resource(aResource);
382 if (myExtStrMap.IsBound(Resource))
383 return myExtStrMap(Resource).ToExtString();
385 TCollection_AsciiString Result = Value(aResource);
386 TCollection_ExtendedString ExtResult;
388 Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult);
390 myExtStrMap.Bind(Resource, ExtResult);
391 return myExtStrMap(Resource).ToExtString();
394 //=======================================================================
395 //function : SetResource
396 //purpose : Sets the new value of an integer resource.
397 // If the resource does not exist, it is created.
398 //=======================================================================
399 void Resource_Manager::SetResource(const Standard_CString aResourceName,
400 const Standard_Integer aValue)
402 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
405 //=======================================================================
406 //function : SetResource
407 //purpose : Sets the new value of a real resource.
408 // If the resource does not exist, it is created.
409 //=======================================================================
410 void Resource_Manager::SetResource(const Standard_CString aResourceName,
411 const Standard_Real aValue)
413 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
416 //=======================================================================
417 //function : SetResource
418 //purpose : Sets the new value of ExtString resource.
419 // If the resource does not exist, it is created.
420 //=======================================================================
421 void Resource_Manager::SetResource(const Standard_CString aResource,
422 const Standard_ExtString aValue)
424 Standard_PCharacter pStr;
425 TCollection_AsciiString Resource = aResource;
426 TCollection_ExtendedString ExtValue = aValue;
427 TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' ');
429 if (!myExtStrMap.Bind(Resource,ExtValue)) {
430 myExtStrMap(Resource) = ExtValue;
433 pStr=(Standard_PCharacter)FormatStr.ToCString();
435 Resource_Unicode::ConvertUnicodeToFormat(ExtValue,
436 pStr,//FormatStr.ToCString(),
437 FormatStr.Length()) ;
438 SetResource(aResource,FormatStr.ToCString());
441 //=======================================================================
442 //function : SetResource
443 //purpose : Sets the new value of an enum resource.
444 // If the resource does not exist, it is created.
445 //=======================================================================
446 void Resource_Manager::SetResource(const Standard_CString aResource,
447 const Standard_CString aValue)
449 TCollection_AsciiString Resource = aResource;
450 TCollection_AsciiString Value = aValue;
451 if (!myUserMap.Bind(Resource, Value))
452 myUserMap(Resource) = Value;
455 //=======================================================================
457 //purpose : Tells if a resource exits.
458 //=======================================================================
459 Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
461 TCollection_AsciiString Resource(aResource);
462 if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
463 return Standard_True;
464 return Standard_False;
467 //=======================================================================
468 //function : GetResourcePath
470 //=======================================================================
472 void Resource_Manager::GetResourcePath (TCollection_AsciiString& aPath, const Standard_CString aName, const Standard_Boolean isUserDefaults)
476 TCollection_AsciiString anEnvVar("CSF_");
478 anEnvVar += isUserDefaults?"UserDefaults":"Defaults";
480 Standard_CString dir;
481 if ((dir = getenv (anEnvVar.ToCString())) == NULL)
484 TCollection_AsciiString aResPath(dir);
486 OSD_Path anOSDPath(aResPath);
487 anOSDPath.DownTrek(anOSDPath.Name());
488 anOSDPath.SetName(aName);
490 anOSDPath.SystemName(aPath);