b311480e |
1 | // Copyright (c) 1998-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
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. |
8 | // |
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. |
11 | // |
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. |
18 | |
7fd59977 |
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> |
24 | |
25 | #include <OSD_Path.hxx> |
26 | #include <OSD_File.hxx> |
27 | #include <OSD_Directory.hxx> |
28 | #include <OSD_Protection.hxx> |
29 | |
30 | #include <Standard_ErrorHandler.hxx> |
31 | #include <TCollection_ExtendedString.hxx> |
32 | #include <Resource_Unicode.hxx> |
33 | #include <TColStd_Array1OfAsciiString.hxx> |
34 | |
35 | #include <errno.h> |
36 | |
37 | #define END 0 |
38 | #define EMPTY 1 |
39 | #define COMMENT 2 |
40 | #define INCLUDE 3 |
41 | #define RESOURCE 4 |
42 | #define ERROR -1 |
43 | |
44 | static Standard_Integer WhatKindOfLine(OSD_File& aFile, |
45 | TCollection_AsciiString& aToken1, |
46 | TCollection_AsciiString& aToken2); |
47 | |
48 | static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine); |
49 | |
50 | static Standard_Boolean Debug; |
51 | |
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) |
56 | { |
57 | if ( !aDefaultsDirectory.IsEmpty() ) { |
58 | Load(aDefaultsDirectory,myName,myRefMap); |
59 | } |
60 | else |
61 | if (myVerbose) |
62 | cout << "Resource Manager Warning: aDefaultsDirectory is empty." << endl; |
63 | |
64 | if ( !anUserDefaultsDirectory.IsEmpty() ) { |
65 | Load(anUserDefaultsDirectory,myName,myRefMap); |
66 | } |
67 | else |
68 | if (myVerbose) |
69 | cout << "Resource Manager Warning: anUserDefaultsDirectory is empty." << endl; |
70 | } |
71 | |
72 | Resource_Manager::Resource_Manager(const Standard_CString aName, |
73 | const Standard_Boolean Verbose) : myName(aName), myVerbose(Verbose) |
74 | { |
75 | Debug = (getenv("ResourceDebug") != NULL) ; |
76 | |
77 | TCollection_AsciiString EnvVar, CSF_ = "CSF_" ; |
78 | TCollection_AsciiString Directory ; |
79 | Standard_CString dir ; |
80 | |
81 | if ( getenv ("CSF_ResourceVerbose") != NULL ) |
82 | myVerbose = Standard_True; |
83 | |
84 | EnvVar = CSF_ + aName + "Defaults" ; |
85 | if ((dir = getenv (EnvVar.ToCString())) != NULL) { |
86 | Directory = dir; |
87 | Load(Directory,myName,myRefMap); |
88 | } |
89 | else |
90 | if (myVerbose) |
91 | cout << "Resource Manager Warning: Environment variable \"" << EnvVar |
92 | << "\" not set." << endl; |
93 | |
94 | EnvVar = CSF_ + aName + "UserDefaults" ; |
95 | if ((dir = getenv (EnvVar.ToCString())) != NULL) { |
96 | Directory = dir; |
97 | Load(Directory, myName, myUserMap); |
98 | } |
99 | else |
100 | if (myVerbose) |
101 | cout << "Resource Manager Warning: Environment variable \"" << EnvVar |
102 | << "\" not set." << endl; |
103 | } |
104 | |
105 | void Resource_Manager::Load(TCollection_AsciiString& aDirectory, |
106 | TCollection_AsciiString& aName, |
107 | Resource_DataMapOfAsciiStringAsciiString& aMap) |
108 | { |
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()); |
116 | if (File.Failed()) { |
117 | if (myVerbose) |
118 | cout << "Resource Manager Warning: Cannot read file \"" << FileName |
119 | << "\". File not found or permission denied." << endl; |
120 | return; |
121 | } |
122 | Standard_Integer LineNumber = 1; |
123 | while ((Kind = WhatKindOfLine(File, Token1, Token2)) != END) { |
124 | switch (Kind) { |
125 | case COMMENT : |
126 | case EMPTY : |
127 | break ; |
128 | case INCLUDE : |
129 | Directory = OSD_Path::AbsolutePath(aDirectory,Token1); |
130 | Pos = Directory.SearchFromEnd("/"); |
131 | if (Pos != 0) { |
132 | Name = Directory.Split(Pos); |
133 | Directory.Trunc(Pos-1); |
134 | Load(Directory,Name,aMap); |
135 | } |
136 | break; |
137 | case RESOURCE : |
138 | if (!aMap.Bind(Token1,Token2)) |
139 | aMap(Token1) = Token2; |
140 | break; |
141 | case ERROR : |
142 | if (myVerbose) |
143 | cout << "Resource Manager: Syntax error at line " |
144 | << LineNumber << " in file : " << FileName << endl; |
145 | break; |
146 | } |
147 | LineNumber++; |
148 | } |
149 | File.Close(); |
150 | if (myVerbose) |
151 | cout << "Resource Manager: " << ((&aMap == &myUserMap) ? "User" : "Reference") |
152 | << " file \"" << FileName << "\" loaded" << endl; |
153 | } |
154 | |
155 | static Standard_Integer WhatKindOfLine(OSD_File& aFile, |
156 | TCollection_AsciiString& aToken1, |
157 | TCollection_AsciiString& aToken2) |
158 | { |
159 | TCollection_AsciiString WhiteSpace = " \t" ; |
160 | Standard_Integer Pos1,Pos2,Pos ; |
161 | TCollection_AsciiString Line ; |
162 | |
163 | if (!GetLine(aFile,Line)) |
164 | return END; |
165 | |
166 | if (Line.Value(1) == '!') |
167 | return COMMENT; |
168 | |
169 | if (Line.Value(1) == '#') { |
170 | Line.Remove(1); |
171 | if ((Line.Token(" \t")).IsDifferent("include")) |
172 | return ERROR; |
173 | |
174 | aToken1 = Line.Token(" \t\n",2); |
175 | return INCLUDE; |
176 | } |
177 | |
178 | Pos1 = Line.FirstLocationNotInSet(WhiteSpace, 1, Line.Length()); |
179 | if (Line.Value(Pos1) == '\n') |
180 | return EMPTY; |
181 | |
182 | Pos2 = Line.Location(1,':',Pos1,Line.Length()); |
183 | if (!Pos2 || Pos1 == Pos2) |
184 | return ERROR; |
185 | |
186 | for (Pos = Pos2-1; Line.Value(Pos) == '\t' || Line.Value(Pos) == ' ' ; Pos--); |
187 | aToken1 = Line.SubString(Pos1, Pos); |
188 | |
189 | if (Debug) |
190 | cout << "Key = '" << aToken1 << flush ; |
191 | |
192 | if ((Pos = Line.FirstLocationNotInSet(WhiteSpace, Pos2+1, Line.Length()))) { |
193 | if (Line.Value(Pos) == '\\') |
194 | switch(Line.Value(Pos+1)) { |
195 | case '\\' : |
196 | case ' ' : |
197 | case '\t' : |
198 | Pos++; |
199 | break; |
200 | } |
201 | } |
202 | if (Pos == Line.Length()) |
203 | aToken2.Clear(); |
204 | else |
205 | aToken2 = Line.SubString(Pos,Line.Length()-1); |
206 | |
207 | if (Debug) |
208 | cout << "'\t Value = '" << aToken2 << "'" << endl << flush; |
209 | return RESOURCE; |
210 | } |
211 | |
212 | // Retourne 0 (EOF) ou une ligne toujours terminee par <NL>. |
213 | |
214 | static Standard_Integer GetLine(OSD_File& aFile,TCollection_AsciiString& aLine) |
215 | { |
216 | TCollection_AsciiString Buffer; |
217 | Standard_Integer BufSize = 10; |
218 | Standard_Integer Len; |
219 | |
220 | aLine.Clear(); |
221 | do { |
222 | aFile.ReadLine(Buffer,BufSize,Len); |
223 | aLine += Buffer; |
224 | if (aFile.IsAtEnd()) |
225 | if (!aLine.Length()) return 0; |
226 | else aLine += "\n"; |
227 | } while (aLine.Value(aLine.Length()) != '\n'); |
228 | |
229 | return 1; |
230 | } |
231 | |
232 | //======================================================================= |
233 | //function : Save |
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 |
238 | { |
239 | Standard_Integer Index; |
240 | TCollection_AsciiString EnvVar, CSF_ = "CSF_"; |
241 | Standard_CString dir; |
242 | |
243 | EnvVar = CSF_ + myName + "UserDefaults"; |
244 | |
245 | if ((dir = getenv (EnvVar.ToCString())) == NULL) { |
246 | if (myVerbose) |
247 | cout << "Resource Manager Warning: environment variable \"" |
248 | << EnvVar << "\" not set. Cannot save resources." << endl ; |
249 | return Standard_False; |
250 | } |
251 | TCollection_AsciiString FilePath = dir; |
252 | OSD_Directory Dir = OSD_Path(FilePath); |
253 | Standard_Boolean Status = Standard_True; |
254 | if ( !Dir.Exists() ) { |
255 | { |
256 | try { |
257 | OCC_CATCH_SIGNALS |
258 | Dir.Build(OSD_Protection(OSD_RX, OSD_RWX, OSD_RX, OSD_RX)); |
259 | } |
260 | catch (Standard_Failure) { |
261 | Status = Standard_False; |
262 | } |
263 | } |
264 | Status = Status && !Dir.Failed(); |
265 | if (!Status) { |
266 | if (myVerbose) |
267 | cout << "Resource Manager: Error opening or creating directory \"" << FilePath |
268 | << "\". Permission denied. Cannot save resources." << endl; |
269 | return Standard_False; |
270 | } |
271 | } |
272 | |
273 | FilePath += "/"; FilePath += myName; |
274 | OSD_Path Path(FilePath); |
275 | OSD_File File = Path; |
276 | OSD_Protection theProt; |
277 | Status = Standard_True; |
278 | { |
279 | try { |
280 | OCC_CATCH_SIGNALS |
281 | File.Build(OSD_ReadWrite, theProt); |
282 | } |
283 | catch (Standard_Failure) { |
284 | Status = Standard_False; |
285 | } |
286 | } |
287 | Status = Status && !File.Failed(); |
288 | if (!Status) { |
289 | if (myVerbose) |
290 | cout << "Resource Manager: Error opening or creating file \"" << FilePath |
291 | << "\". Permission denied. Cannot save resources." << endl; |
292 | return Standard_False; |
293 | } |
294 | |
295 | Resource_LexicalCompare Comp; |
296 | Standard_Integer NbKey = myUserMap.Extent(); |
174178b9 |
297 | TColStd_Array1OfAsciiString KeyArray(1,NbKey+1); // 1 more item is added to allow saving empty resource |
7fd59977 |
298 | Resource_DataMapIteratorOfDataMapOfAsciiStringAsciiString Iter(myUserMap); |
299 | |
300 | for ( Index = 1; Iter.More(); Iter.Next()) |
301 | KeyArray(Index++)= Iter.Key(); |
302 | |
303 | Resource_QuickSortOfArray1::Sort(KeyArray, Comp); |
304 | |
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)) { |
310 | case '\\' : |
311 | case ' ' : |
312 | case '\t' : |
313 | Value.Insert(1,'\\'); |
314 | break; |
315 | } |
316 | Line = KeyArray(Index) + ":\t" + Value + "\n"; |
317 | |
318 | if (Debug) |
319 | cout << "Line = '" << Line << "'" << endl; |
320 | |
321 | File.Write(Line, Line.Length()); |
322 | } |
323 | if (myVerbose) |
324 | cout << "Resource Manager: Resources saved in file " << FilePath << endl; |
325 | File.Close(); |
326 | return Standard_True; |
327 | } |
328 | |
329 | //======================================================================= |
330 | //function : Integer |
331 | //purpose : Gets the value of an integer resource |
332 | //======================================================================= |
333 | |
334 | Standard_Integer Resource_Manager::Integer(const Standard_CString aResourceName) const |
335 | { |
336 | TCollection_AsciiString Result = Value(aResourceName) ; |
337 | if (!Result.IsIntegerValue()) { |
338 | TCollection_AsciiString n("Value of resource `"); |
339 | n+= aResourceName; |
340 | n+= "` is not an integer"; |
341 | Standard_TypeMismatch::Raise(n.ToCString()); |
342 | } |
343 | return Result.IntegerValue(); |
344 | } |
345 | |
346 | //======================================================================= |
347 | //function : Real |
348 | //purpose : Gets the value of a real resource |
349 | //======================================================================= |
350 | |
351 | Standard_Real Resource_Manager::Real(const Standard_CString aResourceName) const |
352 | { |
353 | TCollection_AsciiString Result = Value(aResourceName) ; |
354 | if (!Result.IsRealValue()) { |
355 | TCollection_AsciiString n("Value of resource `"); |
356 | n+= aResourceName; |
357 | n+= "` is not a real"; |
358 | Standard_TypeMismatch::Raise(n.ToCString()); |
359 | } |
360 | return Result.RealValue(); |
361 | } |
362 | |
363 | //======================================================================= |
364 | //function : Value |
365 | //purpose : Gets the value of a CString resource |
366 | //======================================================================= |
367 | |
368 | Standard_CString Resource_Manager::Value(const Standard_CString aResource) const |
369 | { |
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); |
376 | return (""); |
377 | } |
378 | |
379 | //======================================================================= |
380 | //function : ExtValue |
381 | //purpose : Gets the value of a ExtString resource |
382 | //======================================================================= |
383 | |
384 | Standard_ExtString Resource_Manager::ExtValue(const Standard_CString aResource) |
385 | { |
386 | TCollection_AsciiString Resource(aResource); |
387 | if (myExtStrMap.IsBound(Resource)) |
388 | return myExtStrMap(Resource).ToExtString(); |
389 | |
390 | TCollection_AsciiString Result = Value(aResource); |
391 | TCollection_ExtendedString ExtResult; |
392 | |
393 | Resource_Unicode::ConvertFormatToUnicode(Result.ToCString(),ExtResult); |
394 | |
395 | myExtStrMap.Bind(Resource, ExtResult); |
396 | return myExtStrMap(Resource).ToExtString(); |
397 | } |
398 | |
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) |
406 | { |
407 | SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString()); |
408 | } |
409 | |
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) |
417 | { |
418 | SetResource(aResourceName,TCollection_AsciiString(aValue).ToCString()); |
419 | } |
420 | |
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) |
428 | { |
429 | Standard_PCharacter pStr; |
430 | TCollection_AsciiString Resource = aResource; |
431 | TCollection_ExtendedString ExtValue = aValue; |
432 | TCollection_AsciiString FormatStr(ExtValue.Length()*3+10, ' '); |
433 | |
434 | if (!myExtStrMap.Bind(Resource,ExtValue)) { |
435 | myExtStrMap(Resource) = ExtValue; |
436 | } |
437 | // |
438 | pStr=(Standard_PCharacter)FormatStr.ToCString(); |
439 | // |
440 | Resource_Unicode::ConvertUnicodeToFormat(ExtValue, |
441 | pStr,//FormatStr.ToCString(), |
442 | FormatStr.Length()) ; |
443 | SetResource(aResource,FormatStr.ToCString()); |
444 | } |
445 | |
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) |
453 | { |
454 | TCollection_AsciiString Resource = aResource; |
455 | TCollection_AsciiString Value = aValue; |
456 | if (!myUserMap.Bind(Resource, Value)) |
457 | myUserMap(Resource) = Value; |
458 | } |
459 | |
460 | //======================================================================= |
461 | //function : Find |
462 | //purpose : Tells if a resource exits. |
463 | //======================================================================= |
464 | Standard_Boolean Resource_Manager::Find(const Standard_CString aResource) const |
465 | { |
466 | TCollection_AsciiString Resource(aResource); |
467 | if (myUserMap.IsBound(Resource) || myRefMap.IsBound(Resource)) |
468 | return Standard_True; |
469 | return Standard_False; |
470 | } |