1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // api_file.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53 #include <wx/utils.h>
54 #include <wx/filename.h>
55 #include <wx/dir.h>
56 #include <wx/wxcrtvararg.h>
57 #include <wx/wfstream.h>
58 #include <wx/zipstrm.h>
59 #include <wx/txtstrm.h>
60 #include <wx/log.h>
61 #include <wx/version.h>
62
63 #include "api_core.h"
64
65
66 ///////////////////////////////////////////////////////////
67 // //
68 // //
69 // //
70 ///////////////////////////////////////////////////////////
71
72 //---------------------------------------------------------
73 #define m_pStream_Base ((wxStreamBase *)m_pStream)
74 #define m_pStream_In ((wxInputStream *)m_pStream)
75 #define m_pStream_Out ((wxOutputStream *)m_pStream)
76
77
78 ///////////////////////////////////////////////////////////
79 // //
80 // //
81 // //
82 ///////////////////////////////////////////////////////////
83
84 //---------------------------------------------------------
CSG_File(void)85 CSG_File::CSG_File(void)
86 {
87 On_Construction();
88 }
89
90 //---------------------------------------------------------
CSG_File(const CSG_String & FileName,int Mode,bool bBinary,int Encoding)91 CSG_File::CSG_File(const CSG_String &FileName, int Mode, bool bBinary, int Encoding)
92 {
93 On_Construction();
94
95 Open(FileName, Mode, bBinary, Encoding);
96 }
97
98 //---------------------------------------------------------
~CSG_File(void)99 CSG_File::~CSG_File(void)
100 {
101 Close();
102 }
103
104
105 ///////////////////////////////////////////////////////////
106 // //
107 ///////////////////////////////////////////////////////////
108
109 //---------------------------------------------------------
Open(const CSG_String & FileName,int Mode,bool bBinary,int Encoding)110 bool CSG_File::Open(const CSG_String &FileName, int Mode, bool bBinary, int Encoding)
111 {
112 Close();
113
114 if( Mode == SG_FILE_R && !SG_File_Exists(FileName) )
115 {
116 return( false );
117 }
118
119 m_FileName = FileName;
120 m_Mode = Mode;
121
122 Set_Encoding(Encoding);
123
124 switch( m_Mode )
125 {
126 case SG_FILE_W:
127 m_pStream = new wxFFileOutputStream(FileName.c_str(), bBinary ? "wb" : "w");
128 break;
129
130 case SG_FILE_R:
131 m_pStream = new wxFFileInputStream (FileName.c_str(), bBinary ? "rb" : "r");
132 break;
133
134 default: // SG_FILE_RW
135 m_pStream = new wxFFileStream (FileName.c_str(), SG_File_Exists(FileName)
136 ? (bBinary ? "r+b" : "r+")
137 : (bBinary ? "w+b" : "w+")
138 );
139 break;
140 }
141
142 if( !m_pStream || !m_pStream_Base->IsOk() )
143 {
144 Close();
145
146 return( false );
147 }
148
149 return( true );
150 }
151
152 //---------------------------------------------------------
Close(void)153 bool CSG_File::Close(void)
154 {
155 if( m_pStream )
156 {
157 delete(m_pStream_Base);
158
159 m_pStream = NULL;
160 }
161
162 Set_Encoding(SG_FILE_ENCODING_UNDEFINED);
163
164 return( true );
165 }
166
167
168 ///////////////////////////////////////////////////////////
169 // //
170 ///////////////////////////////////////////////////////////
171
172 //---------------------------------------------------------
On_Construction(void)173 void CSG_File::On_Construction(void)
174 {
175 m_pStream = NULL;
176 m_pConvert = NULL;
177 m_Encoding = SG_FILE_ENCODING_UNDEFINED;
178 }
179
180 //---------------------------------------------------------
Set_Encoding(int Encoding)181 bool CSG_File::Set_Encoding(int Encoding)
182 {
183 if( m_pConvert )
184 {
185 if( m_pConvert != &wxConvLocal
186 && m_pConvert != &wxConvLibc
187 && m_pConvert != &wxConvUTF7
188 && m_pConvert != &wxConvUTF8 )
189 {
190 delete((wxMBConv *)m_pConvert);
191 }
192
193 m_pConvert = NULL;
194 }
195
196 m_Encoding = Encoding;
197
198 switch( Encoding )
199 {
200 case SG_FILE_ENCODING_ANSI : break;
201 case SG_FILE_ENCODING_UTF7 : m_pConvert = &wxConvUTF7 ; break;
202 case SG_FILE_ENCODING_UTF8 : m_pConvert = &wxConvUTF8 ; break;
203 case SG_FILE_ENCODING_UTF16LE: m_pConvert = new wxMBConvUTF16LE(); break;
204 case SG_FILE_ENCODING_UTF16BE: m_pConvert = new wxMBConvUTF16BE(); break;
205 case SG_FILE_ENCODING_UTF32LE: m_pConvert = new wxMBConvUTF32LE(); break;
206 case SG_FILE_ENCODING_UTF32BE: m_pConvert = new wxMBConvUTF32BE(); break;
207 default : break;
208 }
209
210 return( true );
211 }
212
213
214 ///////////////////////////////////////////////////////////
215 // //
216 ///////////////////////////////////////////////////////////
217
218 //---------------------------------------------------------
Length(void) const219 sLong CSG_File::Length(void) const
220 {
221 return( m_pStream ? m_pStream_Base->GetLength() : -1 );
222 }
223
224 //---------------------------------------------------------
is_EOF(void) const225 bool CSG_File::is_EOF(void) const
226 {
227 return( is_Reading() && m_pStream_In->Eof() );
228 }
229
230 //---------------------------------------------------------
Seek(sLong Offset,int Origin) const231 bool CSG_File::Seek(sLong Offset, int Origin) const
232 {
233 if( m_pStream )
234 {
235 wxSeekMode Seek = Origin == SG_FILE_CURRENT ? wxFromCurrent : Origin == SG_FILE_END ? wxFromEnd : wxFromStart;
236
237 switch( m_Mode )
238 {
239 case SG_FILE_R : return( m_pStream_In ->SeekI(Offset, Seek) != wxInvalidOffset );
240 case SG_FILE_W : return( m_pStream_Out->SeekO(Offset, Seek) != wxInvalidOffset );
241 case SG_FILE_RW: return( m_pStream_In ->SeekI(Offset, Seek) != wxInvalidOffset
242 && m_pStream_Out->SeekO(Offset, Seek) != wxInvalidOffset );
243 }
244 }
245
246 return( false );
247 }
248
249 //---------------------------------------------------------
Seek_Start(void) const250 bool CSG_File::Seek_Start(void) const { return( Seek(0, SEEK_SET) ); }
Seek_End(void) const251 bool CSG_File::Seek_End (void) const { return( Seek(0, SEEK_END) ); }
252
253 //---------------------------------------------------------
Tell(void) const254 sLong CSG_File::Tell(void) const
255 {
256 if( m_pStream )
257 {
258 switch( m_Mode )
259 {
260 case SG_FILE_R : return( m_pStream_In ->TellI() );
261 case SG_FILE_W : return( m_pStream_Out->TellO() );
262 case SG_FILE_RW: return( m_pStream_In ->TellI() );
263 }
264 }
265
266 return( -1 );
267 }
268
269 //---------------------------------------------------------
Printf(const char * Format,...)270 int CSG_File::Printf(const char *Format, ...)
271 {
272 if( !is_Writing() )
273 {
274 return( 0 );
275 }
276
277 wxString String;
278
279 #ifdef _SAGA_LINUX
280 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
281 va_list argptr; va_start(argptr, _Format);
282 int Result = String.PrintfV(_Format, argptr);
283 #else
284 va_list argptr; va_start(argptr, Format);
285 int Result = String.PrintfV(Format, argptr);
286 #endif
287 va_end(argptr);
288
289 Write(&String);
290
291 return( Result );
292 }
293
294 //---------------------------------------------------------
Printf(const wchar_t * Format,...)295 int CSG_File::Printf(const wchar_t *Format, ...)
296 {
297 if( !is_Writing() )
298 {
299 return( 0 );
300 }
301
302 wxString String;
303
304 #ifdef _SAGA_LINUX
305 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
306 va_list argptr; va_start(argptr, _Format);
307 int Result = String.PrintfV(_Format, argptr);
308 #else
309 va_list argptr; va_start(argptr, Format);
310 int Result = String.PrintfV(Format, argptr);
311 #endif
312
313 va_end(argptr);
314
315 Write(&String);
316
317 return( Result );
318 }
319
320 //---------------------------------------------------------
Read(void * Buffer,size_t Size,size_t Count) const321 size_t CSG_File::Read(void *Buffer, size_t Size, size_t Count) const
322 {
323 return( !is_Reading() || Size == 0 || Count == 0 ? 0 :
324 m_pStream_In->Read(Buffer, Size * Count).LastRead() / Size
325 );
326 }
327
Read(CSG_String & Buffer,size_t Size) const328 size_t CSG_File::Read(CSG_String &Buffer, size_t Size) const
329 {
330 if( is_Reading() && Size > 0 )
331 {
332 CSG_Buffer s(Size + 1);
333
334 size_t i = Read(s.Get_Data(), sizeof(char), Size);
335
336 if( i > 0 )
337 {
338 s[Size] = '\0';
339
340 Buffer = s.Get_Data();
341
342 return( i );
343 }
344 }
345
346 Buffer.Clear();
347
348 return( 0 );
349 }
350
351 //---------------------------------------------------------
Write(void * Buffer,size_t Size,size_t Count) const352 size_t CSG_File::Write(void *Buffer, size_t Size, size_t Count) const
353 {
354 return( !is_Writing() || Size == 0 || Count == 0 ? 0 :
355 m_pStream_Out->Write(Buffer, Size * Count).LastWrite()
356 );
357 }
358
Write(const CSG_String & Buffer) const359 size_t CSG_File::Write(const CSG_String &Buffer) const
360 {
361 if( m_pConvert )
362 {
363 wxString _Buffer(Buffer.w_str());
364
365 const wxScopedCharBuffer s(_Buffer.mb_str(*((wxMBConv *)m_pConvert)));
366
367 return( Write((void *)s.data(), sizeof(char), s.length()) );
368 }
369
370 CSG_Buffer s(Buffer.to_ASCII());
371
372 return( Write((void *)s.Get_Data(), sizeof(char), s.Get_Size()) );
373 }
374
375 //---------------------------------------------------------
Read_Line(CSG_String & sLine) const376 bool CSG_File::Read_Line(CSG_String &sLine) const
377 {
378 if( !is_Reading() || is_EOF() )
379 {
380 return( false );
381 }
382
383 if( m_pConvert )
384 {
385 wxTextInputStream Stream(*m_pStream_In, " \t", *((wxMBConv *)m_pConvert));
386
387 wxString s(Stream.ReadLine()); sLine = CSG_String(&s);
388 }
389 else
390 {
391 wxTextInputStream Stream(*m_pStream_In, " \t");
392
393 wxString s(Stream.ReadLine()); sLine = CSG_String(&s);
394 }
395
396 return( !sLine.is_Empty() || !is_EOF() );
397 }
398
399 //---------------------------------------------------------
Read_Char(void) const400 int CSG_File::Read_Char(void) const
401 {
402 return( !is_Reading() ? 0 : m_pStream_In->GetC() );
403 }
404
405 //---------------------------------------------------------
Read_Int(bool bByteOrderBig) const406 int CSG_File::Read_Int(bool bByteOrderBig) const
407 {
408 int Value = 0;
409
410 if( Read(&Value, sizeof(Value)) == 1 )
411 {
412 if( bByteOrderBig )
413 {
414 SG_Swap_Bytes(&Value, sizeof(Value));
415 }
416 }
417
418 return( Value );
419 }
420
Write_Int(int Value,bool bByteOrderBig)421 bool CSG_File::Write_Int(int Value, bool bByteOrderBig)
422 {
423 if( bByteOrderBig )
424 {
425 SG_Swap_Bytes(&Value, sizeof(Value));
426 }
427
428 return( Write(&Value, sizeof(Value)) == sizeof(Value) );
429 }
430
431 //---------------------------------------------------------
Read_Double(bool bByteOrderBig) const432 double CSG_File::Read_Double(bool bByteOrderBig) const
433 {
434 double Value = 0;
435
436 if( Read(&Value, sizeof(Value)) == 1 )
437 {
438 if( bByteOrderBig )
439 {
440 SG_Swap_Bytes(&Value, sizeof(Value));
441 }
442 }
443
444 return( Value );
445 }
446
Write_Double(double Value,bool bByteOrderBig)447 bool CSG_File::Write_Double(double Value, bool bByteOrderBig)
448 {
449 if( bByteOrderBig )
450 {
451 SG_Swap_Bytes(&Value, sizeof(Value));
452 }
453
454 return( Write(&Value, sizeof(Value)) == sizeof(Value) );
455 }
456
457 //---------------------------------------------------------
Scan(int & Value) const458 bool CSG_File::Scan(int &Value) const
459 {
460 if( is_Reading() )
461 {
462 int c;
463
464 while( !is_EOF() && isspace(c = Read_Char()) ); // remove leading white space
465
466 if( isdigit(c) || strchr("-+", c) )
467 {
468 CSG_String s = (char)c;
469
470 while( !is_EOF() && isdigit(c = Read_Char()) )
471 {
472 s += (char)c;
473 }
474
475 return( s.asInt(Value) );
476 }
477 }
478
479 return( false );
480 }
481
Scan(double & Value) const482 bool CSG_File::Scan(double &Value) const
483 {
484 if( is_Reading() )
485 {
486 int c;
487
488 while( !is_EOF() && isspace(c = Read_Char()) ); // remove leading white space
489
490 if( isdigit(c) || strchr("-+.,eE", c) )
491 {
492 CSG_String s = (char)c;
493
494 while( !is_EOF() && (isdigit(c = Read_Char()) || strchr(".,eE", c) || strchr("", c)) )
495 {
496 s += (char)c;
497 }
498
499 return( s.asDouble(Value) );
500 }
501 }
502
503 return( false );
504 }
505
Scan(CSG_String & Value,SG_Char Separator) const506 bool CSG_File::Scan(CSG_String &Value, SG_Char Separator) const
507 {
508 if( is_Reading() && !is_EOF() )
509 {
510 Value.Clear();
511
512 int c;
513
514 while( !is_EOF() && (c = Read_Char()) != Separator && c != EOF )
515 {
516 Value += (char)c;
517 }
518
519 return( true );
520 }
521
522 return( false );
523 }
524
525 //---------------------------------------------------------
Scan_Int(void) const526 int CSG_File::Scan_Int(void) const
527 {
528 int Value;
529
530 return( Scan(Value) ? Value : 0 );
531 }
532
Scan_Double(void) const533 double CSG_File::Scan_Double(void) const
534 {
535 double Value;
536
537 return( Scan(Value) ? Value : 0.0 );
538 }
539
Scan_String(SG_Char Separator) const540 CSG_String CSG_File::Scan_String(SG_Char Separator) const
541 {
542 CSG_String Value;
543
544 Scan(Value, Separator);
545
546 return( Value );
547 }
548
549
550 ///////////////////////////////////////////////////////////
551 // //
552 // //
553 // //
554 ///////////////////////////////////////////////////////////
555
556 //---------------------------------------------------------
CSG_File_Zip(void)557 CSG_File_Zip::CSG_File_Zip(void)
558 {
559 On_Construction();
560 }
561
562 //---------------------------------------------------------
CSG_File_Zip(const CSG_String & FileName,int Mode,int Encoding)563 CSG_File_Zip::CSG_File_Zip(const CSG_String &FileName, int Mode, int Encoding)
564 {
565 On_Construction();
566
567 Open(FileName, Mode, Encoding);
568 }
569
570 //---------------------------------------------------------
~CSG_File_Zip(void)571 CSG_File_Zip::~CSG_File_Zip(void)
572 {
573 Close();
574 }
575
576 //---------------------------------------------------------
Open(const CSG_String & FileName,int Mode,int Encoding)577 bool CSG_File_Zip::Open(const CSG_String &FileName, int Mode, int Encoding)
578 {
579 wxLogNull logNo; // suppress user notification dialog for invalid zip files
580
581 Close();
582
583 m_Mode = Mode;
584
585 Set_Encoding(Encoding);
586
587 if( Mode == SG_FILE_W )
588 {
589 m_pStream = new wxZipOutputStream(new wxFileOutputStream(FileName.c_str()));
590 }
591 else if( Mode == SG_FILE_R && SG_File_Exists(FileName) )
592 {
593 m_pStream = new wxZipInputStream (new wxFileInputStream (FileName.c_str()));
594 }
595
596 if( !m_pStream || !m_pStream_Base->IsOk() )
597 {
598 Close();
599
600 return( false );
601 }
602
603 if( is_Reading() )
604 {
605 wxZipEntry *pEntry;
606
607 while( (pEntry = ((wxZipInputStream *)m_pStream)->GetNextEntry()) != NULL )
608 {
609 m_Files += pEntry;
610 }
611 }
612
613 return( true );
614 }
615
616 //---------------------------------------------------------
Close(void)617 bool CSG_File_Zip::Close(void)
618 {
619 for(size_t i=0; i<m_Files.Get_Size(); i++)
620 {
621 delete((wxZipEntry *)m_Files[i]);
622 }
623
624 m_Files.Set_Array(0);
625
626 return( CSG_File::Close() );
627 }
628
629 //---------------------------------------------------------
Add_Directory(const CSG_String & Name)630 bool CSG_File_Zip::Add_Directory(const CSG_String &Name)
631 {
632 return( is_Writing() && ((wxZipOutputStream *)m_pStream)->PutNextDirEntry(Name.c_str()) );
633 }
634
635 //---------------------------------------------------------
Add_File(const CSG_String & Name,bool bBinary)636 bool CSG_File_Zip::Add_File(const CSG_String &Name, bool bBinary)
637 {
638 if( is_Writing() )
639 {
640 wxZipEntry *pEntry = new wxZipEntry(Name.c_str());
641
642 pEntry->SetIsText(bBinary == false);
643
644 #if wxCHECK_VERSION(3, 1, 1)
645 ((wxZipOutputStream *)m_pStream)->SetFormat(wxZIP_FORMAT_ZIP64);
646 #endif
647
648 if( ((wxZipOutputStream *)m_pStream)->PutNextEntry(pEntry) )
649 {
650 m_FileName = Name;
651
652 return( true );
653 }
654 }
655
656 return( false );
657 }
658
659 //---------------------------------------------------------
is_Directory(size_t Index)660 bool CSG_File_Zip::is_Directory(size_t Index)
661 {
662 if( is_Reading() && m_Files[Index] )
663 {
664 return( ((wxZipEntry *)m_Files[Index])->IsDir() );
665 }
666
667 return( false );
668 }
669
670 //---------------------------------------------------------
Get_File(size_t Index)671 bool CSG_File_Zip::Get_File(size_t Index)
672 {
673 if( is_Reading() && m_Files[Index] )
674 {
675 if( ((wxZipInputStream *)m_pStream)->OpenEntry(*(wxZipEntry *)m_Files[Index]) )
676 {
677 m_FileName = Get_File_Name(Index);
678
679 return( true );
680 }
681 }
682
683 return( false );
684 }
685
686 //---------------------------------------------------------
Get_File(const CSG_String & Name)687 bool CSG_File_Zip::Get_File(const CSG_String &Name)
688 {
689 if( is_Reading() )
690 {
691 for(size_t i=0; i<m_Files.Get_Size(); i++)
692 {
693 if( !((wxZipEntry *)m_Files[i])->GetName().Cmp(Name.c_str()) )
694 {
695 return( Get_File(i) );
696 }
697 }
698 }
699
700 return( false );
701 }
702
703 //---------------------------------------------------------
Get_File_Name(size_t Index)704 CSG_String CSG_File_Zip::Get_File_Name(size_t Index)
705 {
706 CSG_String s;
707
708 if( is_Reading() && m_Files[Index] )
709 {
710 wxString Name(((wxZipEntry *)m_Files[Index])->GetName()); s = &Name;
711 }
712
713 return( s );
714 }
715
716
717 ///////////////////////////////////////////////////////////
718 // //
719 // //
720 // //
721 ///////////////////////////////////////////////////////////
722
723 //---------------------------------------------------------
SG_Dir_Exists(const CSG_String & Directory)724 bool SG_Dir_Exists(const CSG_String &Directory)
725 {
726 return( wxFileName::DirExists(Directory.c_str()) );
727 }
728
729 //---------------------------------------------------------
SG_Dir_Create(const CSG_String & Directory)730 bool SG_Dir_Create(const CSG_String &Directory)
731 {
732 if( SG_Dir_Exists(Directory) )
733 {
734 return( true );
735 }
736
737 return( wxFileName::Mkdir(Directory.c_str()) );
738 }
739
740 //---------------------------------------------------------
SG_Dir_Delete(const CSG_String & Directory,bool bRecursive)741 bool SG_Dir_Delete(const CSG_String &Directory, bool bRecursive)
742 {
743 if( !SG_Dir_Exists(Directory) )
744 {
745 return( true );
746 }
747
748 return( wxDir::Remove(Directory.c_str(), bRecursive ? wxPATH_RMDIR_RECURSIVE : 0) );
749 }
750
751 //---------------------------------------------------------
SG_Dir_Get_Current(void)752 CSG_String SG_Dir_Get_Current(void)
753 {
754 wxString cwd = wxFileName::GetCwd();
755
756 return( CSG_String(&cwd) );
757 }
758
759 //---------------------------------------------------------
SG_Dir_Get_Temp(void)760 CSG_String SG_Dir_Get_Temp(void)
761 {
762 wxString fname = wxFileName::GetTempDir();
763
764 return( CSG_String(&fname) );
765 }
766
767 //---------------------------------------------------------
SG_Dir_List_Subdirectories(CSG_Strings & List,const CSG_String & Directory)768 bool SG_Dir_List_Subdirectories (CSG_Strings &List, const CSG_String &Directory)
769 {
770 List.Clear();
771
772 wxDir Dir;
773
774 if( Dir.Open(Directory.c_str()) )
775 {
776 wxString FileName;
777
778 if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_DIRS) )
779 {
780 do
781 {
782 List += SG_File_Make_Path(Directory, &FileName);
783 }
784 while( Dir.GetNext(&FileName) );
785 }
786 }
787
788 return( List.Get_Count() > 0 );
789 }
790
791 //---------------------------------------------------------
SG_Dir_List_Files(CSG_Strings & List,const CSG_String & Directory)792 bool SG_Dir_List_Files (CSG_Strings &List, const CSG_String &Directory)
793 {
794 return( SG_Dir_List_Files(List, Directory, "") );
795 }
796
SG_Dir_List_Files(CSG_Strings & List,const CSG_String & Directory,const CSG_String & Extension)797 bool SG_Dir_List_Files (CSG_Strings &List, const CSG_String &Directory, const CSG_String &Extension)
798 {
799 List.Clear();
800
801 wxDir Dir;
802
803 if( Dir.Open(Directory.c_str()) )
804 {
805 wxString FileName;
806
807 if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_FILES) )
808 {
809 do
810 {
811 if( Extension.is_Empty() || SG_File_Cmp_Extension(&FileName, Extension) )
812 {
813 List += SG_File_Make_Path(Directory, &FileName);
814 }
815 }
816 while( Dir.GetNext(&FileName) );
817 }
818 }
819
820 return( List.Get_Count() > 0 );
821 }
822
823
824 ///////////////////////////////////////////////////////////
825 // //
826 // //
827 // //
828 ///////////////////////////////////////////////////////////
829
830 //---------------------------------------------------------
SG_File_Exists(const CSG_String & FileName)831 bool SG_File_Exists(const CSG_String &FileName)
832 {
833 return( wxFileExists(FileName.c_str()) );
834 }
835
836 //---------------------------------------------------------
SG_File_Delete(const CSG_String & FileName)837 bool SG_File_Delete(const CSG_String &FileName)
838 {
839 return( SG_File_Exists(FileName) && wxRemoveFile(FileName.c_str()) );
840 }
841
842 //---------------------------------------------------------
SG_File_Get_Name_Temp(const CSG_String & Prefix)843 CSG_String SG_File_Get_Name_Temp(const CSG_String &Prefix)
844 {
845 return( SG_File_Get_Name_Temp(Prefix, "") );
846 }
847
SG_File_Get_Name_Temp(const CSG_String & Prefix,const CSG_String & Directory)848 CSG_String SG_File_Get_Name_Temp(const CSG_String &Prefix, const CSG_String &Directory)
849 {
850 if( !SG_Dir_Exists(Directory) )
851 {
852 return( CSG_String(wxFileName::CreateTempFileName(Prefix.c_str()).wc_str()) );
853 }
854
855 return( CSG_String(wxFileName::CreateTempFileName(SG_File_Make_Path(Directory, Prefix).w_str()).wc_str()) );
856 }
857
858 //---------------------------------------------------------
SG_File_Get_Name(const CSG_String & full_Path,bool bExtension)859 CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
860 {
861 wxFileName fn(full_Path.c_str());
862
863 if( bExtension )
864 {
865 wxString s(fn.GetFullName()); return( CSG_String(&s) );
866 }
867
868 wxString s(fn.GetName()); return( &s );
869 }
870
871 //---------------------------------------------------------
SG_File_Get_Path(const CSG_String & full_Path)872 CSG_String SG_File_Get_Path(const CSG_String &full_Path)
873 {
874 wxString s(wxFileName(full_Path.c_str()).GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR));
875
876 return( CSG_String(&s) );
877 }
878
879 //---------------------------------------------------------
SG_File_Get_Path_Absolute(const CSG_String & full_Path)880 CSG_String SG_File_Get_Path_Absolute(const CSG_String &full_Path)
881 {
882 wxFileName fn(full_Path.c_str());
883
884 fn.MakeAbsolute();
885
886 wxString s(fn.GetFullPath()); return( &s );
887 }
888
889 //---------------------------------------------------------
SG_File_Get_Path_Relative(const CSG_String & Directory,const CSG_String & full_Path)890 CSG_String SG_File_Get_Path_Relative(const CSG_String &Directory, const CSG_String &full_Path)
891 {
892 wxFileName fn(full_Path.c_str());
893
894 fn.MakeRelativeTo(Directory.c_str());
895
896 wxString s(fn.GetFullPath()); return( &s );
897 }
898
899 //---------------------------------------------------------
SG_File_Make_Path(const CSG_String & Directory,const CSG_String & Name)900 CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
901 {
902 return( SG_File_Make_Path(Directory, Name, "") );
903 }
904
SG_File_Make_Path(const CSG_String & Directory,const CSG_String & Name,const CSG_String & Extension)905 CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name, const CSG_String &Extension)
906 {
907 wxFileName fn;
908
909 fn.AssignDir(!Directory.is_Empty() ? Directory.c_str() : SG_File_Get_Path(Name).c_str());
910
911 if( !Extension.is_Empty() )
912 {
913 fn.SetName (SG_File_Get_Name(Name, false).c_str());
914 fn.SetExt (Extension.c_str());
915 }
916 else
917 {
918 fn.SetFullName (SG_File_Get_Name(Name, true).c_str());
919 }
920
921 wxString s(fn.GetFullPath()); return( &s );
922 }
923
924 //---------------------------------------------------------
SG_File_Cmp_Extension(const CSG_String & FileName,const CSG_String & Extension)925 bool SG_File_Cmp_Extension(const CSG_String &FileName, const CSG_String &Extension)
926 {
927 return( SG_File_Get_Extension(FileName).CmpNoCase(Extension) == 0 );
928 }
929
930 //---------------------------------------------------------
SG_File_Set_Extension(CSG_String & FileName,const CSG_String & Extension)931 bool SG_File_Set_Extension(CSG_String &FileName, const CSG_String &Extension)
932 {
933 if( FileName.Length() > 0 )
934 {
935 wxFileName fn(FileName.c_str());
936
937 fn.SetExt(Extension.c_str());
938
939 wxString s(fn.GetFullPath());
940
941 FileName = &s;
942
943 return( true );
944 }
945
946 return( false );
947 }
948
949 //---------------------------------------------------------
SG_File_Get_Extension(const CSG_String & FileName)950 CSG_String SG_File_Get_Extension(const CSG_String &FileName)
951 {
952 wxFileName fn(FileName.c_str());
953
954 wxString s(fn.GetExt()); return( &s );
955 }
956
957
958 ///////////////////////////////////////////////////////////
959 // //
960 // //
961 // //
962 ///////////////////////////////////////////////////////////
963
964 //---------------------------------------------------------
SG_Get_Environment(const CSG_String & Variable,CSG_String * Value)965 bool SG_Get_Environment(const CSG_String &Variable, CSG_String *Value)
966 {
967 if( Value == NULL )
968 {
969 return( wxGetEnv(Variable.w_str(), NULL) );
970 }
971
972 wxString s;
973
974 if( wxGetEnv(Variable.w_str(), &s) )
975 {
976 *Value = s.wc_str();
977
978 return( true );
979 }
980
981 return( false );
982 }
983
984 //---------------------------------------------------------
SG_Set_Environment(const CSG_String & Variable,const CSG_String & Value)985 bool SG_Set_Environment(const CSG_String &Variable, const CSG_String &Value)
986 {
987 return( wxSetEnv(Variable.w_str(), Value.w_str()) );
988 }
989
990
991 ///////////////////////////////////////////////////////////
992 // //
993 // //
994 // //
995 ///////////////////////////////////////////////////////////
996
997 //---------------------------------------------------------
998