SAGA API Version 9.12
Loading...
Searching...
No Matches
api_file.cpp
Go to the documentation of this file.
1
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// //
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/txtstrm.h>
59#include <wx/zipstrm.h>
60#include <wx/tarstrm.h>
61#include <wx/zstream.h>
62#include <wx/log.h>
63#include <wx/version.h>
64
65#include "api_core.h"
66
67
69// //
70// //
71// //
73
74//---------------------------------------------------------
75#define m_pStream_Base ((wxStreamBase *)m_pStream)
76#define m_pStream_I ((wxFFileInputStream *)m_pStream)
77#define m_pStream_O ((wxFFileOutputStream *)m_pStream)
78#define m_pStream_IO ((wxFFileStream *)m_pStream)
79
80
82// //
83// //
84// //
86
87//---------------------------------------------------------
92
93//---------------------------------------------------------
94CSG_File::CSG_File(const SG_Char *FileName, int Mode, bool bBinary, int Encoding)
95{
97
98 Open(FileName, Mode, bBinary, Encoding);
99}
100
101//---------------------------------------------------------
103{
104 Close();
105}
106
107
109// //
111
112//---------------------------------------------------------
113bool CSG_File::Open(const SG_Char *_FileName, int Mode, bool bBinary, int Encoding)
114{
115 Close();
116
117 if( !_FileName ) { return( false ); } CSG_String FileName(_FileName);
118
119 CSG_String Path(SG_File_Get_Path(FileName));
120
121 if( !Path.is_Empty() && !SG_Dir_Exists(Path) )
122 {
123 return( false );
124 }
125
126 if( Mode == SG_FILE_R && !SG_File_Exists(FileName) )
127 {
128 return( false );
129 }
130
131 m_FileName = FileName; m_Mode = Mode;
132
133 Set_Encoding(Encoding);
134
135 switch( m_Mode )
136 {
137 case SG_FILE_W:
138 m_pStream = new wxFFileOutputStream(FileName.c_str(), bBinary ? "wb" : "w");
139 break;
140
141 case SG_FILE_R:
142 m_pStream = new wxFFileInputStream (FileName.c_str(), bBinary ? "rb" : "r");
143 break;
144
145 default: // SG_FILE_RW
146 m_pStream = new wxFFileStream (FileName.c_str(), SG_File_Exists(FileName)
147 ? (bBinary ? "r+b" : "r+")
148 : (bBinary ? "w+b" : "w+")
149 );
150 break;
151 }
152
153 if( !m_pStream || !m_pStream_Base->IsOk() )
154 {
155 Close();
156
157 return( false );
158 }
159
160 return( true );
161}
162
163//---------------------------------------------------------
165{
166 if( m_pStream )
167 {
168 delete(m_pStream_Base);
169
170 m_pStream = NULL;
171 }
172
174
175 return( true );
176}
177
178
180// //
182
183//---------------------------------------------------------
185{
186 m_pStream = NULL;
187 m_pConvert = NULL;
189}
190
191//---------------------------------------------------------
192bool CSG_File::Set_Encoding(int Encoding)
193{
194 if( m_pConvert )
195 {
196 if( m_pConvert != &wxConvLocal
197 && m_pConvert != &wxConvLibc
198 && m_pConvert != &wxConvUTF7
199 && m_pConvert != &wxConvUTF8 )
200 {
201 delete((wxMBConv *)m_pConvert);
202 }
203
204 m_pConvert = NULL;
205 }
206
207 m_Encoding = Encoding;
208
209 switch( Encoding )
210 {
211 case SG_FILE_ENCODING_ANSI : break;
212 case SG_FILE_ENCODING_UTF7 : m_pConvert = &wxConvUTF7 ; break;
213 case SG_FILE_ENCODING_UTF8 : m_pConvert = &wxConvUTF8 ; break;
214 case SG_FILE_ENCODING_UTF16LE: m_pConvert = new wxMBConvUTF16LE(); break;
215 case SG_FILE_ENCODING_UTF16BE: m_pConvert = new wxMBConvUTF16BE(); break;
216 case SG_FILE_ENCODING_UTF32LE: m_pConvert = new wxMBConvUTF32LE(); break;
217 case SG_FILE_ENCODING_UTF32BE: m_pConvert = new wxMBConvUTF32BE(); break;
218 default : break;
219 }
220
221 return( true );
222}
223
224
226// //
228
229//---------------------------------------------------------
231{
232 return( m_pStream ? m_pStream_Base->GetLength() : -1 );
233}
234
235//---------------------------------------------------------
236bool CSG_File::is_EOF(void) const
237{
238 return( is_Reading() && (m_Mode == SG_FILE_R ? m_pStream_I->Eof() : m_pStream_IO->Eof()) );
239}
240
241//---------------------------------------------------------
242bool CSG_File::Seek(sLong Offset, int Origin) const
243{
244 if( m_pStream )
245 {
246 wxSeekMode Seek = Origin == SG_FILE_CURRENT ? wxFromCurrent : Origin == SG_FILE_END ? wxFromEnd : wxFromStart;
247
248 switch( m_Mode )
249 {
250 case SG_FILE_R : return( m_pStream_I ->SeekI(Offset, Seek) != wxInvalidOffset );
251 case SG_FILE_W : return( m_pStream_O ->SeekO(Offset, Seek) != wxInvalidOffset );
252 default : return( m_pStream_IO->SeekI(Offset, Seek) != wxInvalidOffset
253 && m_pStream_IO->SeekO(Offset, Seek) != wxInvalidOffset );
254 }
255 }
256
257 return( false );
258}
259
260//---------------------------------------------------------
261bool CSG_File::Seek_Start(void) const { return( Seek(0, SEEK_SET) ); }
262bool CSG_File::Seek_End (void) const { return( Seek(0, SEEK_END) ); }
263
264//---------------------------------------------------------
266{
267 if( m_pStream )
268 {
269 switch( m_Mode )
270 {
271 case SG_FILE_R : return( m_pStream_I ->TellI() );
272 case SG_FILE_W : return( m_pStream_O ->TellO() );
273 default : return( m_pStream_IO->TellI() );
274 }
275 }
276
277 return( -1 );
278}
279
280//---------------------------------------------------------
282{
283 return( m_pStream_O && m_pStream_O->GetFile()->Flush() );
284}
285
286//---------------------------------------------------------
287int CSG_File::Printf(const char *Format, ...)
288{
289 if( !is_Writing() )
290 {
291 return( 0 );
292 }
293
294 wxString String;
295
296#ifdef _SAGA_LINUX
297 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
298 va_list argptr; va_start(argptr, _Format);
299 int Result = String.PrintfV(_Format, argptr);
300#else
301 va_list argptr; va_start(argptr, Format);
302 int Result = String.PrintfV(Format, argptr);
303#endif
304 va_end(argptr);
305
306 Write(&String);
307
308 return( Result );
309}
310
311//---------------------------------------------------------
312int CSG_File::Printf(const wchar_t *Format, ...)
313{
314 if( !is_Writing() )
315 {
316 return( 0 );
317 }
318
319 wxString String;
320
321#ifdef _SAGA_LINUX
322 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
323 va_list argptr; va_start(argptr, _Format);
324 int Result = String.PrintfV(_Format, argptr);
325#else
326 va_list argptr; va_start(argptr, Format);
327 int Result = String.PrintfV(Format, argptr);
328#endif
329
330 va_end(argptr);
331
332 Write(&String);
333
334 return( Result );
335}
336
337//---------------------------------------------------------
338size_t CSG_File::Read(void *Buffer, size_t Size, size_t Count) const
339{
340 return( !is_Reading() || Size == 0 || Count == 0 ? 0 : m_Mode == SG_FILE_R
341 ? m_pStream_I ->Read(Buffer, Size * Count).LastRead() / Size
342 : m_pStream_IO->Read(Buffer, Size * Count).LastRead() / Size
343 );
344}
345
346size_t CSG_File::Read(CSG_String &Buffer, size_t Size) const
347{
348 if( is_Reading() && Size > 0 )
349 {
350 CSG_Buffer s(Size + 1);
351
352 size_t i = Read(s.Get_Data(), sizeof(char), Size);
353
354 if( i > 0 )
355 {
356 s[Size] = '\0';
357
358 Buffer = s.Get_Data();
359
360 return( i );
361 }
362 }
363
364 Buffer.Clear();
365
366 return( 0 );
367}
368
369size_t CSG_File::Read(CSG_String &Buffer) const
370{
371 Buffer.Clear();
372
373 if( is_Reading() )
374 {
375 CSG_String Line; while( Read_Line(Line) ) { if( !Buffer.is_Empty() ) { Buffer += '\n'; } Buffer += Line; }
376 }
377
378 return( Buffer.Length() );
379}
380
381//---------------------------------------------------------
382size_t CSG_File::Write(void *Buffer, size_t Size, size_t Count) const
383{
384 return( !is_Writing() || Size == 0 || Count == 0 ? 0 : m_Mode == SG_FILE_W
385 ? m_pStream_O ->Write(Buffer, Size * Count).LastWrite()
386 : m_pStream_IO->Write(Buffer, Size * Count).LastWrite()
387 );
388}
389
390size_t CSG_File::Write(const CSG_String &Buffer) const
391{
392 if( m_pConvert )
393 {
394 wxString _Buffer(Buffer.w_str());
395
396 const wxScopedCharBuffer s(_Buffer.mb_str(*((wxMBConv *)m_pConvert)));
397
398 return( Write((void *)s.data(), sizeof(char), s.length()) );
399 }
400
401 return( Buffer.Length() > 0 ? Write((void *)Buffer.b_str(), sizeof(char), Buffer.Length()) : 0 );
402
403// CSG_Buffer _Buffer(Buffer.to_ASCII()); // returns NULL terminated char sequence, Get_Size() count includes terminating NULL!!!
404
405// return( _Buffer.Get_Size() > 1 ? Write((void *)_Buffer.Get_Data(), sizeof(char), _Buffer.Get_Size() - 1) : 0 );
406}
407
408//---------------------------------------------------------
410{
411 if( !is_Reading() || is_EOF() )
412 {
413 return( false );
414 }
415
416 wxString s;
417
418 if( m_pConvert )
419 {
420 if( m_Mode == SG_FILE_R )
421 {
422 wxTextInputStream Stream(*m_pStream_I , " \t", *((wxMBConv *)m_pConvert)); s = Stream.ReadLine();
423 }
424 else
425 {
426 wxTextInputStream Stream(*m_pStream_IO, " \t", *((wxMBConv *)m_pConvert)); s = Stream.ReadLine();
427 }
428 }
429 else
430 {
431 if( m_Mode == SG_FILE_R )
432 {
433 wxTextInputStream Stream(*m_pStream_I , " \t" ); s = Stream.ReadLine();
434 }
435 else
436 {
437 wxTextInputStream Stream(*m_pStream_IO, " \t" ); s = Stream.ReadLine();
438 }
439 }
440
441 sLine = CSG_String(&s);
442
443 return( !sLine.is_Empty() || !is_EOF() );
444}
445
446//---------------------------------------------------------
447int CSG_File::Read_Char(void) const
448{
449 return( !is_Reading() ? 0 : m_Mode == SG_FILE_R ? m_pStream_I->GetC() : m_pStream_IO->GetC() );
450}
451
452//---------------------------------------------------------
453int CSG_File::Read_Int(bool bByteOrderBig) const
454{
455 int Value = 0;
456
457 if( Read(&Value, sizeof(Value)) == 1 )
458 {
459 if( bByteOrderBig )
460 {
461 SG_Swap_Bytes(&Value, sizeof(Value));
462 }
463 }
464
465 return( Value );
466}
467
468bool CSG_File::Write_Int(int Value, bool bByteOrderBig)
469{
470 if( bByteOrderBig )
471 {
472 SG_Swap_Bytes(&Value, sizeof(Value));
473 }
474
475 return( Write(&Value, sizeof(Value)) == sizeof(Value) );
476}
477
478//---------------------------------------------------------
479double CSG_File::Read_Double(bool bByteOrderBig) const
480{
481 double Value = 0;
482
483 if( Read(&Value, sizeof(Value)) == 1 )
484 {
485 if( bByteOrderBig )
486 {
487 SG_Swap_Bytes(&Value, sizeof(Value));
488 }
489 }
490
491 return( Value );
492}
493
494bool CSG_File::Write_Double(double Value, bool bByteOrderBig)
495{
496 if( bByteOrderBig )
497 {
498 SG_Swap_Bytes(&Value, sizeof(Value));
499 }
500
501 return( Write(&Value, sizeof(Value)) == sizeof(Value) );
502}
503
504//---------------------------------------------------------
505bool CSG_File::Scan(int &Value) const
506{
507 if( is_Reading() )
508 {
509 int c; while( !is_EOF() && isspace(c = Read_Char()) ); // remove leading white space
510
511 if( isdigit(c) || strchr("-+", c) )
512 {
513 CSG_String s = (char)c;
514
515 while( !is_EOF() && isdigit(c = Read_Char()) )
516 {
517 s += (char)c;
518 }
519
520 return( s.asInt(Value) );
521 }
522 }
523
524 return( false );
525}
526
527bool CSG_File::Scan(double &Value) const
528{
529 if( is_Reading() )
530 {
531 int c; while( !is_EOF() && isspace(c = Read_Char()) ); // remove leading white space
532
533 if( isdigit(c) || strchr("-+.,eE", c) )
534 {
535 CSG_String s = (char)c;
536
537 while( !is_EOF() && (isdigit(c = Read_Char()) || strchr(".,eE", c) || strchr("", c)) )
538 {
539 s += (char)c;
540 }
541
542 return( s.asDouble(Value) );
543 }
544 }
545
546 return( false );
547}
548
549bool CSG_File::Scan(CSG_String &Value, SG_Char Separator) const
550{
551 if( is_Reading() && !is_EOF() )
552 {
553 Value.Clear();
554
555 int c; while( !is_EOF() && (c = Read_Char()) != Separator && c != EOF )
556 {
557 Value += (char)c;
558 }
559
560 return( true );
561 }
562
563 return( false );
564}
565
566//---------------------------------------------------------
567int CSG_File::Scan_Int(void) const
568{
569 int Value; return( Scan(Value) ? Value : 0 );
570}
571
572double CSG_File::Scan_Double(void) const
573{
574 double Value; return( Scan(Value) ? Value : 0.0 );
575}
576
578{
579 CSG_String Value; Scan(Value, Separator); return( Value );
580}
581
582
584// //
585// //
586// //
588
589//---------------------------------------------------------
594
595//---------------------------------------------------------
596CSG_Archive::CSG_Archive(const SG_Char *FileName, int Mode, int Encoding)
597{
599
600 Open(FileName, Mode, Encoding);
601}
602
603//---------------------------------------------------------
605{
606 Close();
607}
608
609//---------------------------------------------------------
610bool CSG_Archive::Open(const SG_Char *_FileName, int Mode, int Encoding)
611{
612 Close();
613
614 if( !_FileName ) { return( false ); } CSG_String FileName(_FileName);
615
616 if( SG_File_Cmp_Extension(FileName, "tar") )
617 {
619 }
620 else // if( SG_File_Cmp_Extension(FileName, "zip") )
621 {
623 }
624
625 m_Archive = FileName;
626
628
629 if( !Path.is_Empty() && !SG_Dir_Exists(Path) )
630 {
631 return( false );
632 }
633
634 if( Mode == SG_FILE_R && !SG_File_Exists(m_Archive) )
635 {
636 return( false );
637 }
638
639 wxLogNull logNo; // suppress user notification dialog for invalid zip files
640
641 m_Mode = Mode; Set_Encoding(Encoding);
642
643 if( Mode == SG_FILE_W )
644 {
645 if( is_Zip() )
646 {
647 m_pStream = new wxZipOutputStream(new wxFileOutputStream(m_Archive.c_str()));
648 }
649 else
650 {
651 m_pStream = new wxTarOutputStream(new wxFileOutputStream(m_Archive.c_str()));
652 }
653 }
654 else if( Mode == SG_FILE_R && SG_File_Exists(m_Archive) )
655 {
656 if( is_Zip() )
657 {
658 m_pStream = new wxZipInputStream (new wxFileInputStream (m_Archive.c_str()));
659 }
660 else
661 {
662 m_pStream = new wxTarInputStream (new wxFileInputStream (m_Archive.c_str()));
663 }
664 }
665
666 if( !m_pStream || !m_pStream_Base->IsOk() )
667 {
668 Close();
669
670 return( false );
671 }
672
673 if( is_Reading() )
674 {
675 wxArchiveEntry *pEntry;
676
677 while( (pEntry = ((wxArchiveInputStream *)m_pStream)->GetNextEntry()) != NULL )
678 {
679 m_Files += pEntry;
680 }
681 }
682
683 return( true );
684}
685
686//---------------------------------------------------------
688{
689 for(sLong i=0; i<m_Files.Get_Size(); i++)
690 {
691 if( is_Zip() )
692 {
693 delete((wxZipEntry *)m_Files[i]);
694 }
695 else
696 {
697 delete((wxTarEntry *)m_Files[i]);
698 }
699 }
700
701 m_Files.Set_Array(0);
702
703 m_Archive.Clear();
704
705 return( CSG_File::Close() );
706}
707
708//---------------------------------------------------------
710{
711 return( is_Writing() && Name && ((wxArchiveOutputStream *)m_pStream)->PutNextDirEntry(Name) );
712}
713
714//---------------------------------------------------------
715bool CSG_Archive::Add_File(const SG_Char *Name, bool bBinary)
716{
717 if( is_Writing() && Name )
718 {
719 wxArchiveEntry *pEntry = NULL;
720
721 if( is_Zip() )
722 {
723 pEntry = new wxZipEntry(Name);
724
725 ((wxZipEntry *)pEntry)->SetIsText(bBinary == false);
726
727 #if wxCHECK_VERSION(3, 1, 1)
728 ((wxZipOutputStream *)m_pStream)->SetFormat(wxZIP_FORMAT_ZIP64);
729 #endif
730 }
731 else
732 {
733 pEntry = new wxTarEntry(Name);
734 }
735
736 if( ((wxArchiveOutputStream *)m_pStream)->PutNextEntry(pEntry) )
737 {
738 m_FileName = Name;
739
740 return( true );
741 }
742 }
743
744 return( false );
745}
746
747//---------------------------------------------------------
749{
750 if( is_Reading() && m_Files[Index] )
751 {
752 return( ((wxArchiveEntry *)m_Files[Index])->IsDir() );
753 }
754
755 return( false );
756}
757
758//---------------------------------------------------------
759bool CSG_Archive::Get_File(size_t Index)
760{
761 if( is_Reading() && m_Files[Index] )
762 {
763 if( ((wxArchiveInputStream *)m_pStream)->OpenEntry(*(wxArchiveEntry *)m_Files[Index]) )
764 {
765 m_FileName = Get_File_Name(Index);
766
767 return( true );
768 }
769 }
770
771 return( false );
772}
773
774//---------------------------------------------------------
776{
777 if( is_Reading() && Name )
778 {
779 for(sLong i=0; i<m_Files.Get_Size(); i++)
780 {
781 if( !((wxArchiveEntry *)m_Files[i])->GetName().Cmp(Name) )
782 {
783 return( Get_File(i) );
784 }
785 }
786 }
787
788 return( false );
789}
790
791//---------------------------------------------------------
793{
794 CSG_String s;
795
796 if( is_Reading() && m_Files[Index] )
797 {
798 wxString Name(((wxArchiveEntry *)m_Files[Index])->GetName()); s = &Name;
799 }
800
801 return( s );
802}
803
804
806// //
808
809//---------------------------------------------------------
810bool CSG_Archive::Extract_All(const SG_Char *_Directory)
811{
812 if( !is_Reading() )
813 {
814 return( false );
815 }
816
817 #ifdef _SAGA_MSW
818 const char Separator = '\\';
819 #else
820 const char Separator = '/';
821 #endif
822
823 CSG_String Directory(_Directory ? _Directory : SG_T(""));
824
825 if( Directory.is_Empty() )
826 {
827 Directory = SG_File_Get_Path(m_Archive);
828 }
829 else if( !SG_Dir_Exists(Directory) )
830 {
831 SG_Dir_Create(Directory, true);
832 }
833
834 Directory += Separator;
835
836 //-----------------------------------------------------
837 for(size_t i=0; i<Get_File_Count() && SG_UI_Process_Set_Progress((int)i, (int)Get_File_Count()); i++)
838 {
839 if( is_Directory(i) )
840 {
841 SG_Dir_Create(Directory + Get_File_Name(i));
842 }
843 else
844 {
845 Extract(Get_File_Name(i), Directory + Get_File_Name(i));
846 }
847 }
848
849 return( true );
850}
851
852//---------------------------------------------------------
853bool CSG_Archive::Extract(const SG_Char *File, const SG_Char *_toFile)
854{
855 if( !is_Reading() || !Get_File(File) )
856 {
857 return( false );
858 }
859
860 CSG_String toFile(_toFile ? _toFile : SG_T(""));
861
862 if( toFile.is_Empty() )
863 {
865 }
866
867 CSG_File Stream(toFile, SG_FILE_W, true, m_Encoding);
868
869 if( !Stream.is_Open() )
870 {
871 return( false );
872 }
873
874 //-----------------------------------------------------
875 #define UNZIP_BUFFER 4096
876
877 char *Buffer[UNZIP_BUFFER];
878
879 while( !is_EOF() )
880 {
881 size_t nBytes = Read(Buffer, sizeof(char), UNZIP_BUFFER);
882
883 Stream.Write(Buffer, 1, nBytes); Stream.Flush();
884 }
885
886 return( true );
887}
888
889
891// //
892// //
893// //
895
896//---------------------------------------------------------
898{
899 // nop
900}
901
902//---------------------------------------------------------
904{
905 return( wxZlibInputStream::CanHandleGZip() );
906}
907
908//---------------------------------------------------------
910{
911 if( SG_File_Exists(File) )
912 {
913 wxFFileInputStream Input(File.c_str());
914
915 if( Input.IsOk() && Input.CanRead() )
916 {
917 CSG_String Target(_Target);
918
919 if( Target.is_Empty() )
920 {
921 Target = File + ".gz";
922 }
923
924 wxZlibOutputStream Output(new wxFFileOutputStream(Target.c_str()));
925
926 if( Output.IsOk() )
927 {
928 Output.Write(Input);
929
930 return( Target );
931 }
932 }
933 }
934
935 return( "" );
936}
937
938//---------------------------------------------------------
940{
941 if( SG_File_Exists(File) )
942 {
943 wxZlibInputStream Input(new wxFFileInputStream(File.c_str()));
944
945 if( Input.IsOk() && Input.CanRead() )
946 {
947 CSG_String Target(_Target);
948
949 if( Target.is_Empty() )
950 {
951 Target = SG_File_Make_Path(SG_File_Get_Path(File), SG_File_Get_Name(File, false), "");
952 }
953
954 wxFFileOutputStream Output(Target.c_str());
955
956 if( Output.IsOk() )
957 {
958 Output.Write(Input);
959
960 return( Target );
961 }
962 }
963 }
964
965 return( "" );
966}
967
968
970// //
971// //
972// //
974
975//---------------------------------------------------------
976bool SG_Dir_Exists(const CSG_String &Directory)
977{
978 return( !Directory.is_Empty() && wxFileName::DirExists(Directory.c_str()) );
979}
980
981//---------------------------------------------------------
982bool SG_Dir_Create(const CSG_String &Directory, bool bFullPath)
983{
984 if( SG_Dir_Exists(Directory) )
985 {
986 return( true );
987 }
988
989 return( wxFileName::Mkdir(Directory.c_str(), wxS_DIR_DEFAULT, bFullPath ? wxPATH_MKDIR_FULL : 0) );
990}
991
992//---------------------------------------------------------
993bool SG_Dir_Delete(const CSG_String &Directory, bool bRecursive)
994{
995 if( !SG_Dir_Exists(Directory) )
996 {
997 return( true );
998 }
999
1000 return( wxDir::Remove(Directory.c_str(), bRecursive ? wxPATH_RMDIR_RECURSIVE : 0) );
1001}
1002
1003//---------------------------------------------------------
1005{
1006 wxString cwd = wxFileName::GetCwd();
1007
1008 return( CSG_String(&cwd) );
1009}
1010
1011//---------------------------------------------------------
1013
1023bool SG_Dir_Set_Temp(const CSG_String &Directory, bool bCreate)
1024{
1025 if( Directory.is_Empty() )
1026 {
1027 g_Dir_Temp.Clear(); // reset
1028
1029 return( true );
1030 }
1031
1032 if( SG_Dir_Exists(Directory) == false && bCreate )
1033 {
1034 SG_Dir_Create(Directory, true);
1035 }
1036
1037 if( SG_Dir_Exists(Directory) )
1038 {
1039 g_Dir_Temp = Directory;
1040
1041 return( true );
1042 }
1043
1044 return( false );
1045}
1046
1048{
1050 {
1051 return( g_Dir_Temp );
1052 }
1053
1054 wxString Dir_Temp(wxFileName::GetTempDir());
1055
1056 return( &Dir_Temp );
1057}
1058
1059//---------------------------------------------------------
1060bool SG_Dir_List_Subdirectories (CSG_Strings &List, const CSG_String &Directory, bool bRecursive)
1061{
1062 List.Clear(); wxDir Dir;
1063
1064 if( Dir.Open(Directory.c_str()) )
1065 {
1066 wxString FileName;
1067
1068 if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_DIRS) )
1069 {
1070 do
1071 {
1072 List += SG_File_Make_Path(Directory, &FileName);
1073
1074 if( bRecursive )
1075 {
1076 CSG_Strings _List; SG_Dir_List_Subdirectories(_List, SG_File_Make_Path(Directory, &FileName), bRecursive); List += _List;
1077 }
1078 }
1079 while( Dir.GetNext(&FileName) );
1080 }
1081 }
1082
1083 return( List.Get_Count() > 0 );
1084}
1085
1086//---------------------------------------------------------
1087bool SG_Dir_List_Files (CSG_Strings &List, const CSG_String &Directory, const CSG_String &Extension, bool bRecursive)
1088{
1089 List.Clear(); wxDir Dir;
1090
1091 if( Dir.Open(Directory.c_str()) )
1092 {
1093 wxString FileName;
1094
1095 if( Dir.GetFirst(&FileName, wxEmptyString, wxDIR_FILES) )
1096 {
1097 do
1098 {
1099 if( Extension.is_Empty() || SG_File_Cmp_Extension(&FileName, Extension) )
1100 {
1101 List += SG_File_Make_Path(Directory, &FileName);
1102 }
1103 }
1104 while( Dir.GetNext(&FileName) );
1105 }
1106
1107 if( bRecursive && Dir.GetFirst(&FileName, wxEmptyString, wxDIR_DIRS) )
1108 {
1109 do
1110 {
1111 CSG_Strings _List; SG_Dir_List_Files(_List, SG_File_Make_Path(Directory, &FileName), Extension, bRecursive); List += _List;
1112 }
1113 while( Dir.GetNext(&FileName) );
1114 }
1115 }
1116
1117 return( List.Get_Count() > 0 );
1118}
1119
1120
1122// //
1123// //
1124// //
1126
1127//---------------------------------------------------------
1128bool SG_File_Exists(const CSG_String &FileName)
1129{
1130 return( wxFileExists(FileName.c_str()) );
1131}
1132
1133//---------------------------------------------------------
1134bool SG_File_Delete(const CSG_String &FileName)
1135{
1136 return( SG_File_Exists(FileName) && wxRemoveFile(FileName.c_str()) );
1137}
1138
1139//---------------------------------------------------------
1140bool SG_File_Copy(const CSG_String &Source, const CSG_String &Target, bool bOverwrite)
1141{
1142 return( wxCopyFile(Source.wx_str(), Target.wx_str(), bOverwrite) );
1143}
1144
1145//---------------------------------------------------------
1147{
1148 return( SG_File_Get_Name_Temp(Prefix, "") );
1149}
1150
1152{
1153 if( !SG_Dir_Exists(Directory) )
1154 {
1155 return( CSG_String(wxFileName::CreateTempFileName(Prefix.c_str()).wc_str()) );
1156 }
1157
1158 return( CSG_String(wxFileName::CreateTempFileName(SG_File_Make_Path(Directory, Prefix).w_str()).wc_str()) );
1159}
1160
1161//---------------------------------------------------------
1162CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
1163{
1164 wxFileName fn(full_Path.c_str());
1165
1166 if( bExtension )
1167 {
1168 wxString s(fn.GetFullName()); return( CSG_String(&s) );
1169 }
1170
1171 wxString s(fn.GetName()); return( &s );
1172}
1173
1174//---------------------------------------------------------
1176{
1177 wxString s(wxFileName(full_Path.c_str()).GetPath(wxPATH_GET_VOLUME|wxPATH_GET_SEPARATOR));
1178
1179 return( CSG_String(&s) );
1180}
1181
1182//---------------------------------------------------------
1184{
1185 wxFileName fn(full_Path.c_str());
1186
1187 fn.Normalize(wxPATH_NORM_DOTS|wxPATH_NORM_ABSOLUTE|wxPATH_NORM_TILDE, CWD.c_str(), wxPATH_NATIVE);
1188
1189 wxString s(fn.GetFullPath()); return( &s );
1190}
1191
1192//---------------------------------------------------------
1194{
1195 wxFileName fn(full_Path.c_str());
1196
1197 fn.MakeRelativeTo(Directory.c_str());
1198
1199 wxString s(fn.GetFullPath()); return( &s );
1200}
1201
1202//---------------------------------------------------------
1204{
1205 return( SG_File_Make_Path(Directory, Name, "") );
1206}
1207
1208CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name, const CSG_String &Extension)
1209{
1210 wxFileName fn;
1211
1212 fn.AssignDir(!Directory.is_Empty() ? Directory.c_str() : SG_File_Get_Path(Name).c_str());
1213
1214 if( !Extension.is_Empty() )
1215 {
1216 fn.SetName (SG_File_Get_Name(Name, false).c_str()); fn.SetExt(Extension.c_str());
1217 }
1218 else
1219 {
1220 fn.SetFullName(SG_File_Get_Name(Name, true).c_str());
1221 }
1222
1223 wxString s(fn.GetFullPath()); return( &s );
1224}
1225
1226//---------------------------------------------------------
1227bool SG_File_Cmp_Path(const CSG_String &Path1, const CSG_String &Path2)
1228{
1229 wxFileName a(wxString(Path1.c_str())), b(wxString(Path2.c_str()));
1230
1231 return( a.SameAs(b) );
1232}
1233
1234//---------------------------------------------------------
1235bool SG_File_Cmp_Extension(const CSG_String &FileName, const CSG_String &Extension)
1236{
1237 return( SG_File_Get_Extension(FileName).CmpNoCase(Extension) == 0 );
1238}
1239
1240//---------------------------------------------------------
1241bool SG_File_Set_Extension(CSG_String &FileName, const CSG_String &Extension)
1242{
1243 if( FileName.Length() > 0 )
1244 {
1245 wxFileName fn(FileName.c_str());
1246
1247 fn.SetExt(Extension.c_str());
1248
1249 wxString s(fn.GetFullPath());
1250
1251 FileName = &s;
1252
1253 return( true );
1254 }
1255
1256 return( false );
1257}
1258
1259//---------------------------------------------------------
1261{
1262 wxFileName fn(FileName.c_str());
1263
1264 wxString s(fn.GetExt()); return( &s );
1265}
1266
1267
1269// //
1270// //
1271// //
1273
1274//---------------------------------------------------------
1275bool SG_Get_Environment(const CSG_String &Variable, CSG_String *Value)
1276{
1277 if( Value == NULL )
1278 {
1279 return( wxGetEnv(Variable.w_str(), NULL) );
1280 }
1281
1282 wxString s;
1283
1284 if( wxGetEnv(Variable.w_str(), &s) )
1285 {
1286 *Value = s.wc_str();
1287
1288 return( true );
1289 }
1290
1291 return( false );
1292}
1293
1294//---------------------------------------------------------
1295bool SG_Set_Environment(const CSG_String &Variable, const CSG_String &Value)
1296{
1297 return( wxSetEnv(Variable.w_str(), Value.w_str()) );
1298}
1299
1300
1302// //
1303// //
1304// //
1306
1307//---------------------------------------------------------
SAGA_API_DLL_EXPORT bool SG_File_Exists(const CSG_String &FileName)
SAGA_API_DLL_EXPORT bool SG_File_Cmp_Extension(const CSG_String &File, const CSG_String &Extension)
signed long long sLong
Definition api_core.h:158
SAGA_API_DLL_EXPORT bool SG_Dir_Create(const CSG_String &Directory, bool bFullPath=false)
Definition api_file.cpp:982
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Path(const CSG_String &full_Path)
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT bool SG_UI_Process_Set_Progress(int Position, int Range)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
SAGA_API_DLL_EXPORT bool SG_Dir_Exists(const CSG_String &Directory)
Definition api_file.cpp:976
@ SG_FILE_TYPE_TAR
Definition api_core.h:1146
@ SG_FILE_TYPE_ZIP
Definition api_core.h:1145
@ SG_FILE_CURRENT
Definition api_core.h:1162
@ SG_FILE_END
Definition api_core.h:1163
#define SG_Char
Definition api_core.h:536
@ SG_FILE_ENCODING_UTF16LE
Definition api_core.h:553
@ SG_FILE_ENCODING_UTF16BE
Definition api_core.h:554
@ SG_FILE_ENCODING_UTF8
Definition api_core.h:552
@ SG_FILE_ENCODING_UTF7
Definition api_core.h:551
@ SG_FILE_ENCODING_UNDEFINED
Definition api_core.h:557
@ SG_FILE_ENCODING_ANSI
Definition api_core.h:550
@ SG_FILE_ENCODING_UTF32BE
Definition api_core.h:556
@ SG_FILE_ENCODING_UTF32LE
Definition api_core.h:555
SAGA_API_DLL_EXPORT void SG_Swap_Bytes(void *Buffer, int nBytes)
@ SG_FILE_W
Definition api_core.h:1154
@ SG_FILE_R
Definition api_core.h:1153
CSG_String SG_Dir_Get_Temp(void)
CSG_String SG_File_Get_Name_Temp(const CSG_String &Prefix)
bool SG_File_Cmp_Path(const CSG_String &Path1, const CSG_String &Path2)
bool SG_File_Exists(const CSG_String &FileName)
bool SG_Dir_Create(const CSG_String &Directory, bool bFullPath)
Definition api_file.cpp:982
bool SG_Dir_List_Subdirectories(CSG_Strings &List, const CSG_String &Directory, bool bRecursive)
bool SG_File_Copy(const CSG_String &Source, const CSG_String &Target, bool bOverwrite)
CSG_String SG_Dir_Get_Current(void)
#define m_pStream_I
Definition api_file.cpp:76
#define m_pStream_O
Definition api_file.cpp:77
CSG_String SG_File_Get_Extension(const CSG_String &FileName)
#define m_pStream_IO
Definition api_file.cpp:78
bool SG_File_Set_Extension(CSG_String &FileName, const CSG_String &Extension)
bool SG_Set_Environment(const CSG_String &Variable, const CSG_String &Value)
CSG_String g_Dir_Temp
bool SG_Dir_Delete(const CSG_String &Directory, bool bRecursive)
Definition api_file.cpp:993
bool SG_Dir_Exists(const CSG_String &Directory)
Definition api_file.cpp:976
bool SG_File_Cmp_Extension(const CSG_String &FileName, const CSG_String &Extension)
bool SG_File_Delete(const CSG_String &FileName)
CSG_String SG_File_Get_Path(const CSG_String &full_Path)
CSG_String SG_File_Get_Path_Relative(const CSG_String &Directory, const CSG_String &full_Path)
#define m_pStream_Base
Definition api_file.cpp:75
CSG_String SG_File_Get_Name(const CSG_String &full_Path, bool bExtension)
bool SG_Get_Environment(const CSG_String &Variable, CSG_String *Value)
#define UNZIP_BUFFER
CSG_String SG_File_Get_Path_Absolute(const CSG_String &full_Path, const CSG_String &CWD)
bool SG_Dir_List_Files(CSG_Strings &List, const CSG_String &Directory, const CSG_String &Extension, bool bRecursive)
CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
bool SG_Dir_Set_Temp(const CSG_String &Directory, bool bCreate)
Set the directory path returned by SG_Dir_Get_Temp(). Defaults to the user's temporary directory....
bool Add_Directory(const SG_Char *Name)
Definition api_file.cpp:709
bool is_Zip(void) const
Definition api_core.h:1258
bool Add_File(const SG_Char *Name, bool bBinary=true)
Definition api_file.cpp:715
TSG_File_Type m_Type
Definition api_core.h:1276
bool is_Directory(size_t Index)
Definition api_file.cpp:748
bool Extract_All(const SG_Char *toDirectory=NULL)
Definition api_file.cpp:810
CSG_Archive(void)
Definition api_file.cpp:590
size_t Get_File_Count(void)
Definition api_core.h:1264
bool Get_File(const SG_Char *Name)
Definition api_file.cpp:775
virtual bool Close(void)
Definition api_file.cpp:687
virtual bool Open(const SG_Char *FileName, int Mode=SG_FILE_R, int Encoding=SG_FILE_ENCODING_ANSI)
Definition api_file.cpp:610
CSG_Array_Pointer m_Files
Definition api_core.h:1280
virtual ~CSG_Archive(void)
Definition api_file.cpp:604
bool Extract(const SG_Char *File, const SG_Char *toFile=NULL)
Definition api_file.cpp:853
CSG_String m_Archive
Definition api_core.h:1278
char * Get_Data(int Offset=0) const
Definition api_core.h:244
bool Seek(sLong Offset, int Origin=SG_FILE_START) const
Definition api_file.cpp:242
double Read_Double(bool bBigEndian=false) const
Definition api_file.cpp:479
sLong Length(void) const
Definition api_file.cpp:230
sLong Tell(void) const
Definition api_file.cpp:265
virtual bool Open(const SG_Char *FileName, int Mode=SG_FILE_R, bool bBinary=true, int Encoding=SG_FILE_ENCODING_ANSI)
Definition api_file.cpp:113
CSG_String m_FileName
Definition api_core.h:1233
int Read_Int(bool bBigEndian=false) const
Definition api_file.cpp:453
int m_Mode
Definition api_core.h:1231
bool Write_Int(int Value, bool bBigEndian=false)
Definition api_file.cpp:468
bool Set_Encoding(int Encoding)
Definition api_file.cpp:192
virtual const CSG_String & Get_File_Name(void) const
Definition api_core.h:1179
virtual bool Close(void)
Definition api_file.cpp:164
bool Seek_End(void) const
Definition api_file.cpp:262
bool is_Open(void) const
Definition api_core.h:1188
bool Read_Line(CSG_String &Line) const
Definition api_file.cpp:409
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:382
int Scan_Int(void) const
Definition api_file.cpp:567
CSG_File(void)
Definition api_file.cpp:88
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
int Printf(const char *Format,...)
Definition api_file.cpp:287
bool Flush(void)
Definition api_file.cpp:281
bool is_EOF(void) const
Definition api_file.cpp:236
CSG_String Scan_String(SG_Char Separator) const
Definition api_file.cpp:577
void * m_pStream
Definition api_core.h:1235
bool is_Writing(void) const
Definition api_core.h:1190
int Read_Char(void) const
Definition api_file.cpp:447
bool is_Reading(void) const
Definition api_core.h:1189
bool Seek_Start(void) const
Definition api_file.cpp:261
bool Scan(int &Value) const
Definition api_file.cpp:505
bool Write_Double(double Value, bool bBigEndian=false)
Definition api_file.cpp:494
virtual ~CSG_File(void)
Definition api_file.cpp:102
double Scan_Double(void) const
Definition api_file.cpp:572
void * m_pConvert
Definition api_core.h:1235
void On_Construction(void)
Definition api_file.cpp:184
int m_Encoding
Definition api_core.h:1231
size_t Length(void) const
const char * b_str(void) const
void Clear(void)
int asInt(void) const
const SG_Char * c_str(void) const
bool is_Empty(void) const
const class wxString & wx_str(void) const
Definition api_core.h:595
double asDouble(void) const
const wchar_t * w_str(void) const
int Get_Count(void) const
Definition api_core.h:719
void Clear(void)
Definition api_core.h:741
static CSG_String Uncompress(const CSG_String &File, const CSG_String &Target="")
Definition api_file.cpp:939
static bool is_GZip_Supported(void)
Definition api_file.cpp:903
static CSG_String Compress(const CSG_String &File, const CSG_String &Target="")
Definition api_file.cpp:909
CSG_ZLib(void)
Definition api_file.cpp:897