1 #include <Resource_Manager.hxx>
2 #include <Resource_Manager.ixx>
3 #include <Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString.hxx>
4 #include <Resource_QuickSortOfArray1.hxx>
5 #include <Resource_LexicalCompare.hxx>
7 #include <OSD_Path.hxx>
8 #include <OSD_File.hxx>
9 #include <OSD_Directory.hxx>
10 #include <OSD_Protection.hxx>
12 #include <Standard_ErrorHandler.hxx>
13 #include <TCollection_ExtendedString.hxx>
14 #include <Resource_Unicode.hxx>
15 #include <TColStd_Array1OfAsciiString.hxx>
26 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
27 TCollection_AsciiString& aToken1,
28 TCollection_AsciiString& aToken2);
30 static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine);
32 static Standard_Boolean Debug;
34 Resource_Manager::Resource_Manager(const Standard_CString aName,
35 TCollection_AsciiString& aDefaultsDirectory,
36 TCollection_AsciiString& anUserDefaultsDirectory,
37 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
39 if ( !aDefaultsDirectory.IsEmpty() ) {
40 Load(aDefaultsDirectory,myName,myRefMap);
44 cout << "Resource Manager Warning: aDefaultsDirectory is empty." << endl;
46 if ( !anUserDefaultsDirectory.IsEmpty() ) {
47 Load(anUserDefaultsDirectory,myName,myRefMap);
51 cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << endl;
54 Resource_Manager::Resource_Manager(const Standard_CString aName,
55 const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose)
57 Debug = (getenv("ResourceDebug") != NULL) ;
59 TCollection_AsciiString EnvVar, CSF_ = "CSF_" ;
60 TCollection_AsciiString Directory ;
61 Standard_CString dir ;
63 if ( getenv ("CSF_ResourceVerbose") != NULL )
64 myVerbose = Standard_True;
66 EnvVar = CSF_ + aName + "Defaults" ;
67 if ((dir = getenv (EnvVar.ToCString())) != NULL) {
69 Load(Directory,myName,myRefMap);
73 cout << "Resource Manager Warning: Environment variable \"" << EnvVar
74 << "\" not set." << endl;
76 EnvVar = CSF_ + aName + "UserDefaults" ;
77 if ((dir = getenv (EnvVar.ToCString())) != NULL) {
79 Load(Directory, myName, myUserMap);
83 cout << "Resource Manager Warning: Environment variable \"" << EnvVar
84 << "\" not set." << endl;
87 void Resource_Manager::Load(TCollection_AsciiString& aDirectory,
88 TCollection_AsciiString& aName,
89 Resource_DataMapOfAsciiStringAsciiString& aMap)
91 Standard_Integer Kind, Pos;
92 TCollection_AsciiString Token1, Token2;
93 TCollection_AsciiString Directory, Name;
94 TCollection_AsciiString FileName;
95 FileName = aDirectory + "/" + aName;
96 OSD_File File = OSD_Path(FileName);
97 File.Open(OSD_ReadOnly,OSD_Protection());
100 cout << "Resource Manager Warning: Cannot read file \"" << FileName
101 << "\". File not found or permission denied." << endl;
104 Standard_Integer LineNumber = 1;
105 while ((Kind = WhatKindOfLine(File, Token1, Token2)) != END) {
111 Directory = OSD_Path::AbsolutePath(aDirectory,Token1);
112 Pos = Directory.SearchFromEnd("/");
114 Name = Directory.Split(Pos);
115 Directory.Trunc(Pos-1);
116 Load(Directory,Name,aMap);
120 if (!aMap.Bind(Token1,Token2))
121 aMap(Token1) = Token2;
125 cout << "Resource Manager: Syntax error at line "
126 << LineNumber << " in file : " << FileName << endl;
133 cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference")
134 << " file \"" << FileName << "\" loaded" << endl;
137 static Standard_Integer WhatKindOfLine(OSD_File& aFile,
138 TCollection_AsciiString& aToken1,
139 TCollection_AsciiString& aToken2)
141 TCollection_AsciiString WhiteSpace = " \t" ;
142 Standard_Integer Pos1,Pos2,Pos ;
143 TCollection_AsciiString Line ;
145 if (!GetLine(aFile,Line))
148 if (Line.Value(1) == '!')
151 if (Line.Value(1) == '#') {
153 if ((Line.Token(" \t")).IsDifferent("include"))
156 aToken1 = Line.Token(" \t\n",2);
160 Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length());
161 if (Line.Value(Pos1) == '\n')
164 Pos2 = Line.Location(1,':',Pos1,Line.Length());
165 if (!Pos2 || Pos1 == Pos2)
168 for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--);
169 aToken1 = Line.SubString(Pos1, Pos);
172 cout << "Key = '" << aToken1 << flush ;
174 if ((Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length()))) {
175 if (Line.Value(Pos) == '\\')
176 switch(Line.Value(Pos+1)) {
184 if (Pos == Line.Length())
187 aToken2 = Line.SubString(Pos,Line.Length()-1);
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);
207 if (!aLine.Length()) return 0;
209 } while (aLine.Value(aLine.Length()) != '\n');
214 //=======================================================================
216 //purpose : Sort and save the user resources in the user file.
217 // Creates the file if it does not exist.
218 //=======================================================================
219 Standard_Boolean Resource_Manager::Save() const
221 Standard_Integer Index;
222 TCollection_AsciiString EnvVar, CSF_ = "CSF_";
223 Standard_CString dir;
225 EnvVar = CSF_ + myName + "UserDefaults";
227 if ((dir = getenv (EnvVar.ToCString())) == NULL) {
229 cout << "Resource Manager Warning: environment variable \""
230 << EnvVar << "\" not set. Cannot save resources." << endl ;
231 return Standard_False;
233 TCollection_AsciiString FilePath = dir;
234 OSD_Directory Dir = OSD_Path(FilePath);
235 Standard_Boolean Status = Standard_True;
236 if ( !Dir.Exists() ) {
240 Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX));
242 catch (Standard_Failure) {
243 Status = Standard_False;
246 Status = Status && !Dir.Failed();
249 cout << "Resource Manager: Error opening or creating directory \"" << FilePath
250 << "\". Permission denied. Cannot save resources." << endl;
251 return Standard_False;
255 FilePath += "/"; FilePath += myName;
256 OSD_Path Path(FilePath);
257 OSD_File File = Path;
258 OSD_Protection theProt;
259 Status = Standard_True;
263 File.Build(OSD_ReadWrite, theProt);
265 catch (Standard_Failure) {
266 Status = Standard_False;
269 Status = Status && !File.Failed();
272 cout << "Resource Manager: Error opening or creating file \"" << FilePath
273 << "\". Permission denied. Cannot save resources." << endl;
274 return Standard_False;
277 Resource_LexicalCompare Comp;
278 Standard_Integer NbKey = myUserMap.Extent();
279 TColStd_Array1OfAsciiString KeyArray(1,NbKey);
280 Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap);
282 for ( Index = 1; Iter.More(); Iter.Next())
283 KeyArray(Index++)= Iter.Key();
285 Resource_QuickSortOfArray1::Sort(KeyArray, Comp);
287 TCollection_AsciiString Line, Value;
288 for (Index = 1 ; Index <= NbKey ; Index++) {
289 Value = myUserMap(KeyArray(Index));
290 if (!Value.IsEmpty())
291 switch(Value.Value(1)) {
295 Value.Insert(1,'\\');
298 Line = KeyArray(Index) + ":\t" + Value + "\n";
301 cout << "Line = '" << Line << "'" << endl;
303 File.Write(Line, Line.Length());
306 cout << "Resource Manager: Resources saved in file " << FilePath << endl;
308 return Standard_True;
311 //=======================================================================
313 //purpose : Gets the value of an integer resource
314 //=======================================================================
316 Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const
318 TCollection_AsciiString Result = Value(aResourceName) ;
319 if (!Result.IsIntegerValue()) {
320 TCollection_AsciiString n("Value of resource `");
322 n+= "` is not an integer";
323 Standard_TypeMismatch::Raise(n.ToCString());
325 return Result.IntegerValue();
328 //=======================================================================
330 //purpose : Gets the value of a real resource
331 //=======================================================================
333 Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const
335 TCollection_AsciiString Result = Value(aResourceName) ;
336 if (!Result.IsRealValue()) {
337 TCollection_AsciiString n("Value of resource `");
339 n+= "` is not a real";
340 Standard_TypeMismatch::Raise(n.ToCString());
342 return Result.RealValue();
345 //=======================================================================
347 //purpose : Gets the value of a CString resource
348 //=======================================================================
350 Standard_CString Resource_Manager::Value(const Standard_CString aResource) const
352 TCollection_AsciiString Resource(aResource);
353 if (myUserMap.IsBound(Resource))
354 return myUserMap(Resource).ToCString();
355 if (myRefMap.IsBound(Resource))
356 return myRefMap(Resource).ToCString();
357 Resource_NoSuchResource::Raise(aResource);
361 //=======================================================================
362 //function : ExtValue
363 //purpose : Gets the value of a ExtString resource
364 //=======================================================================
366 Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource)
368 TCollection_AsciiString Resource(aResource);
369 if (myExtStrMap.IsBound(Resource))
370 return myExtStrMap(Resource).ToExtString();
372 TCollection_AsciiString Result = Value(aResource);
373 TCollection_ExtendedString ExtResult;
375 Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult);
377 myExtStrMap.Bind(Resource, ExtResult);
378 return myExtStrMap(Resource).ToExtString();
381 //=======================================================================
382 //function : SetResource
383 //purpose : Sets the new value of an integer resource.
384 // If the resource does not exist, it is created.
385 //=======================================================================
386 void Resource_Manager::SetResource(const Standard_CString aResourceName,
387 const Standard_Integer aValue)
389 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
392 //=======================================================================
393 //function : SetResource
394 //purpose : Sets the new value of a real resource.
395 // If the resource does not exist, it is created.
396 //=======================================================================
397 void Resource_Manager::SetResource(const Standard_CString aResourceName,
398 const Standard_Real aValue)
400 SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString());
403 //=======================================================================
404 //function : SetResource
405 //purpose : Sets the new value of ExtString resource.
406 // If the resource does not exist, it is created.
407 //=======================================================================
408 void Resource_Manager::SetResource(const Standard_CString aResource,
409 const Standard_ExtString aValue)
411 Standard_PCharacter pStr;
412 TCollection_AsciiString Resource = aResource;
413 TCollection_ExtendedString ExtValue = aValue;
414 TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' ');
416 if (!myExtStrMap.Bind(Resource,ExtValue)) {
417 myExtStrMap(Resource) = ExtValue;
420 pStr=(Standard_PCharacter)FormatStr.ToCString();
422 Resource_Unicode::ConvertUnicodeToFormat(ExtValue,
423 pStr,//FormatStr.ToCString(),
424 FormatStr.Length()) ;
425 SetResource(aResource,FormatStr.ToCString());
428 //=======================================================================
429 //function : SetResource
430 //purpose : Sets the new value of an enum resource.
431 // If the resource does not exist, it is created.
432 //=======================================================================
433 void Resource_Manager::SetResource(const Standard_CString aResource,
434 const Standard_CString aValue)
436 TCollection_AsciiString Resource = aResource;
437 TCollection_AsciiString Value = aValue;
438 if (!myUserMap.Bind(Resource, Value))
439 myUserMap(Resource) = Value;
442 //=======================================================================
444 //purpose : Tells if a resource exits.
445 //=======================================================================
446 Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const
448 TCollection_AsciiString Resource(aResource);
449 if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource))
450 return Standard_True;
451 return Standard_False;