SAGA API Version 9.14
Loading...
Searching...
No Matches
metadata.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// metadata.cpp //
15// //
16// Copyright (C) 2009 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 Hamburg //
44// Germany //
45// //
46// e-mail: oconrad@saga-gis.org //
47// //
49
50//---------------------------------------------------------
51#include <wx/xml/xml.h>
52#include <wx/wfstream.h>
53#include <wx/sstream.h>
54#include <wx/mstream.h>
55#include <wx/protocol/http.h>
56#include <wx/protocol/ftp.h>
57#include <wx/webrequest.h>
58#include <wx/mimetype.h>
59
60#include "metadata.h"
61#include "table.h"
62
63
65// //
66// //
67// //
69
70//---------------------------------------------------------
72{
73 _On_Construction();
74}
75
77{
78 return( true );
79}
80
81//---------------------------------------------------------
83{
84 _On_Construction();
85
86 Create(MetaData);
87}
88
90{
91 return( Assign(MetaData) );
92}
93
94//---------------------------------------------------------
95CSG_MetaData::CSG_MetaData(const CSG_String &File, const SG_Char *Extension)
96{
97 _On_Construction();
98
99 Create(File, Extension);
100}
101
102bool CSG_MetaData::Create(const CSG_String &File, const SG_Char *Extension)
103{
104 return( Load(File, Extension) );
105}
106
107//---------------------------------------------------------
109{
110 _On_Construction();
111
112 Create(Stream);
113}
114
116{
117 return( Load(Stream) );
118}
119
120//---------------------------------------------------------
122{
123 _On_Construction();
124
125 m_pParent = pParent;
126}
127
128//---------------------------------------------------------
129void CSG_MetaData::_On_Construction(void)
130{
131 m_pParent = NULL;
132
134}
135
136//---------------------------------------------------------
141
142//---------------------------------------------------------
144{
145 CSG_MetaData **m_pChildren = (CSG_MetaData **)m_Children.Get_Array();
146
147 for(int i=0; i<Get_Children_Count(); i++)
148 {
149 delete(m_pChildren[i]);
150 }
151
152 m_Children.Destroy();
153
154// m_pParent = NULL;
155
156// m_Name .Clear();
157// m_Content .Clear();
158
159 m_Prop_Names .Clear();
160 m_Prop_Values.Clear();
161}
162
163
165// //
167
168//---------------------------------------------------------
170{
171 return( Ins_Child(-1) );
172}
173
175{
176 return( Ins_Child(Name, -1) );
177}
178
180{
181 return( Ins_Child(Name, Content, -1) );
182}
183
184CSG_MetaData * CSG_MetaData::Add_Child(const CSG_String &Name, double Content)
185{
186 return( Ins_Child(Name, SG_Get_String(Content, -16), -1) );
187}
188
190{
191 return( Ins_Child(Name, CSG_String::Format(SG_T("%d"), Content), -1) );
192}
193
195{
196 return( Ins_Child(Name, CSG_String::Format(SG_T("%lld"), Content), -1) );
197}
198
199CSG_MetaData * CSG_MetaData::Add_Child(const CSG_MetaData &MetaData, bool bAddChildren)
200{
201 return( Ins_Child(MetaData, -1, bAddChildren) );
202}
203
204
206// //
208
209//---------------------------------------------------------
211{
212 if( !m_Children.Inc_Array() )
213 {
214 return( NULL );
215 }
216
217 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
218
219 if( Position < 0 || Position >= Get_Children_Count() )
220 {
221 Position = Get_Children_Count() - 1;
222 }
223
224 for(int i=Get_Children_Count()-1; i>Position; i--)
225 {
226 pChildren[i] = pChildren[i - 1];
227 }
228
229 return( pChildren[Position] = new CSG_MetaData(this) );
230}
231
232//---------------------------------------------------------
233CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, const CSG_String &Content, int Position)
234{
235 CSG_MetaData *pChild = Ins_Child(Position);
236
237 if( pChild )
238 {
239 pChild->m_Name = Name;
240 pChild->m_Content = Content;
241 }
242
243 return( pChild );
244}
245
247{
248 return( Ins_Child(Name, CSG_String(""), Position) );
249}
250
251CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, double Content, int Position)
252{
253 return( Ins_Child(Name, SG_Get_String(Content, -16), Position) );
254}
255
256CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, int Content, int Position)
257{
258 return( Ins_Child(Name, CSG_String::Format(SG_T("%d"), Content), Position) );
259}
260
261CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, sLong Content, int Position)
262{
263 return( Ins_Child(Name, CSG_String::Format(SG_T("%lld"), Content), Position) );
264}
265
266CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_MetaData &MetaData, int Position, bool bAddChildren)
267{
268 CSG_MetaData *pChild = Ins_Child(Position);
269
270 if( pChild )
271 {
272 pChild->Assign(MetaData, bAddChildren);
273 }
274
275 return( pChild );
276}
277
278
280// //
282
283//---------------------------------------------------------
284bool CSG_MetaData::Mov_Child(int from_Index, int to_Index)
285{
286 if( from_Index < 0 || from_Index >= Get_Children_Count()
287 || to_Index < 0 || to_Index >= Get_Children_Count() )
288 {
289 return( false );
290 }
291
292 if( from_Index != to_Index )
293 {
294 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
295 CSG_MetaData *pChild = pChildren[from_Index];
296
297 if( from_Index < to_Index )
298 {
299 for(int i=from_Index; i<to_Index; i++)
300 {
301 pChildren[i] = pChildren[i + 1];
302 }
303 }
304 else // if( from_Index > to_Index )
305 {
306 for(int i=from_Index; i>to_Index; i--)
307 {
308 pChildren[i] = pChildren[i - 1];
309 }
310 }
311
312 pChildren[to_Index] = pChild;
313 }
314
315 return( true );
316}
317
318
320// //
322
323//---------------------------------------------------------
325{
326 if( Index >= 0 && Index < Get_Children_Count() )
327 {
328 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
329
330 delete(pChildren[Index]);
331
332 for(int i=Index, j=Index+1; j<Get_Children_Count(); i++, j++)
333 {
334 pChildren[i] = pChildren[j];
335 }
336
337 m_Children.Dec_Array();
338
339 return( true );
340 }
341
342 return( false );
343}
344
345//---------------------------------------------------------
347{
348 if( Name.Find('.') > 0 )
349 {
350 CSG_MetaData *pParent = Get_Child(Name.BeforeLast('.'));
351
352 if( pParent )
353 {
354 return( pParent->Del_Child(Name.AfterLast('.')) );
355 }
356 }
357
358 return( Del_Child(_Get_Child(Name)) );
359}
360
361//---------------------------------------------------------
363{
364 if( &MetaData != this )
365 {
366 for(int i=0; i<MetaData.Get_Children_Count(); i++)
367 {
368 Add_Child(MetaData[i], true);
369 }
370 }
371
372 return( true );
373}
374
375//---------------------------------------------------------
383//---------------------------------------------------------
384bool CSG_MetaData::Del_Children(int Depth, const SG_Char *Name)
385{
386 if( Depth < 0 )
387 {
388 // nop
389 }
390 else if( Name && *Name )
391 {
392 for(int i=Get_Children_Count()-1; i>=0; i--)
393 {
394 if( Get_Child(i)->Get_Name().CmpNoCase(Name) )
395 {
396 Get_Child(i)->Del_Children(Depth, Name);
397 }
398 else if( Depth > 0 )
399 {
400 Get_Child(i)->Del_Children(Depth - 1, Name);
401 }
402 else
403 {
404 Del_Child(i);
405 }
406 }
407 }
408 else if( Depth > 0 )
409 {
410 for(int i=0; i<Get_Children_Count(); i++)
411 {
412 Get_Child(i)->Del_Children(Depth - 1, Name);
413 }
414 }
415 else
416 {
417 for(int i=0; i<Get_Children_Count(); i++)
418 {
419 delete(Get_Child(i));
420 }
421
422 m_Children.Destroy();
423 }
424
425 return( true );
426}
427
428//---------------------------------------------------------
430{
431 if( Name.Find('.') > 0 )
432 {
433 CSG_MetaData *pEntry = Get_Child(Name.BeforeFirst('.'));
434
435 if( pEntry )
436 {
437 return( pEntry->Get_Child(Name.AfterFirst('.')) );
438 }
439 }
440
441 return( Get_Child(_Get_Child(Name)) );
442}
443
444//---------------------------------------------------------
446{
447 if( JSON_Pointer.Find('/') > 0 )
448 {
449 CSG_String Child_Name = JSON_Pointer.BeforeFirst('/');
450 Child_Name.Replace("~0", "~");
451 Child_Name.Replace("~1", "/");
452 int Index = -1;
453 CSG_MetaData *pEntry = Child_Name.asInt(Index) ? Get_Child(Index) : Get_Child(Child_Name);
454 if( pEntry )
455 {
456 return( pEntry->Get_Child_by_JSON_Pointer(JSON_Pointer.AfterFirst('/')) );
457 }
458 }
459 else
460 {
461 int Index = -1;
462 return( JSON_Pointer.asInt(Index) ? Get_Child(Index) : Get_Child(_Get_Child(JSON_Pointer)) );
463 }
464 return( nullptr );
465}
466
467//---------------------------------------------------------
468int CSG_MetaData::_Get_Child(const CSG_String &Name) const
469{
470 for(int i=0; i<Get_Children_Count(); i++)
471 {
472 if( Name.CmpNoCase(Get_Child(i)->Get_Name()) == 0 )
473 {
474 return( i );
475 }
476 }
477
478 return( -1 );
479}
480
481
483// //
485
486//---------------------------------------------------------
487bool CSG_MetaData::Cmp_Name(const CSG_String &String, bool bNoCase) const
488{
489 return( bNoCase ? !m_Name.CmpNoCase(String) : !m_Name.Cmp(String) );
490}
491
492
494// //
496
497//---------------------------------------------------------
499{
500 if( Name.is_Empty() )
501 {
502 return( m_Content );
503 }
504
505 CSG_MetaData *pEntry = Get_Child(Name);
506
507 return( pEntry ? pEntry->Get_Content().c_str() : NULL );
508}
509
510//---------------------------------------------------------
511bool CSG_MetaData::Get_Content(const CSG_String &Name, CSG_String &Value) const
512{
513 const SG_Char *cString = Name.is_Empty() ? Get_Content().c_str() : Get_Content(Name);
514
515 if( cString )
516 {
517 Value = cString;
518
519 return( true );
520 }
521
522 return( false );
523}
524
525//---------------------------------------------------------
526bool CSG_MetaData::Get_Content(const CSG_String &Name, double &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asDouble (Value) ); }
527bool CSG_MetaData::Get_Content(const CSG_String &Name, int &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asInt (Value) ); }
528bool CSG_MetaData::Get_Content(const CSG_String &Name, sLong &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asLongLong(Value) ); }
529
530
532// //
534
535//---------------------------------------------------------
536void CSG_MetaData::Fmt_Content(const char *Format, ...)
537{
538 wxString s; va_list argptr;
539
540#ifdef _SAGA_LINUX
541 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
542 va_start(argptr, _Format);
543 s.PrintfV(_Format, argptr);
544#else
545 va_start(argptr, Format);
546 s.PrintfV(Format, argptr);
547#endif
548
549 m_Content = CSG_String(&s);
550
551 va_end(argptr);
552}
553
554//---------------------------------------------------------
555void CSG_MetaData::Fmt_Content(const wchar_t *Format, ...)
556{
557 wxString s; va_list argptr;
558
559#ifdef _SAGA_LINUX
560 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
561 va_start(argptr, _Format);
562 s.PrintfV(_Format, argptr);
563#else
564 va_start(argptr, Format);
565 s.PrintfV(Format, argptr);
566#endif
567
568 m_Content = CSG_String(&s);
569
570 va_end(argptr);
571}
572
573//---------------------------------------------------------
574bool CSG_MetaData::Cmp_Content(const CSG_String &String, bool bNoCase) const
575{
576 return( bNoCase ? !m_Content.CmpNoCase(String) : !m_Content.Cmp(String) );
577}
578
579
581// //
583
584//---------------------------------------------------------
585bool CSG_MetaData::Add_Property(const CSG_String &Name, const CSG_String &Value)
586{
587 if( !Value.is_Empty() &&_Get_Property(Name) < 0 )
588 {
589 m_Prop_Names .Add(Name );
590 m_Prop_Values.Add(Value);
591
592 return( true );
593 }
594
595 return( false );
596}
597
598bool CSG_MetaData::Add_Property(const CSG_String &Name, double Value)
599{
600 return( Add_Property(Name, CSG_String::Format(SG_T("%f"), Value)) );
601}
602
603bool CSG_MetaData::Add_Property(const CSG_String &Name, int Value)
604{
605 return( Add_Property(Name, CSG_String::Format(SG_T("%d"), Value)) );
606}
607
609{
610 return( Add_Property(Name, CSG_String::Format(SG_T("%lld"), Value)) );
611}
612
613//---------------------------------------------------------
615{
616 for(int i=0; i<Get_Property_Count(); i++)
617 {
618 if( !Get_Property_Name(i).CmpNoCase(Name) )
619 {
620 return( Del_Property(i) );
621 }
622 }
623
624 return( false );
625}
626
628{
629 if( i >= 0 && i < Get_Property_Count() )
630 {
631 m_Prop_Names .Del(i);
632 m_Prop_Values.Del(i);
633
634 return( true );
635 }
636
637 return( false );
638}
639
640//---------------------------------------------------------
641bool CSG_MetaData::Set_Property(const CSG_String &Name, const CSG_String &Value, bool bAddIfNotExists)
642{
643 int Index = _Get_Property(Name);
644
645 if( Index >= 0 )
646 {
647 m_Prop_Values[Index] = Value;
648
649 return( true );
650 }
651 else if( bAddIfNotExists )
652 {
653 m_Prop_Names .Add(Name);
654 m_Prop_Values.Add(Value);
655
656 return( true );
657 }
658
659 return( false );
660}
661
662bool CSG_MetaData::Set_Property(const CSG_String &Name, double Value, bool bAddIfNotExists)
663{
664 return( Set_Property(Name, CSG_String::Format(SG_T("%f"), Value, bAddIfNotExists)) );
665}
666
667bool CSG_MetaData::Set_Property(const CSG_String &Name, int Value, bool bAddIfNotExists)
668{
669 return( Set_Property(Name, CSG_String::Format(SG_T("%d"), Value, bAddIfNotExists)) );
670}
671
672bool CSG_MetaData::Set_Property(const CSG_String &Name, sLong Value, bool bAddIfNotExists)
673{
674 return( Set_Property(Name, CSG_String::Format(SG_T("%lld"), Value, bAddIfNotExists)) );
675}
676
677//---------------------------------------------------------
678bool CSG_MetaData::Get_Property(const CSG_String &Name, CSG_String &Value) const
679{
680 const SG_Char *cString = Get_Property(Name);
681
682 if( cString )
683 {
684 Value = cString;
685
686 return( true );
687 }
688
689 return( false );
690}
691
692bool CSG_MetaData::Get_Property(const CSG_String &Name, double &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asDouble (Value) ); }
693bool CSG_MetaData::Get_Property(const CSG_String &Name, int &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asInt (Value) ); }
694bool CSG_MetaData::Get_Property(const CSG_String &Name, sLong &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asLongLong(Value) ); }
695
696//---------------------------------------------------------
697bool CSG_MetaData::Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase) const
698{
699 CSG_String s;
700
701 return( Get_Property(Name, s) && (bNoCase ? !s.CmpNoCase(String) : !s.Cmp(String)) );
702}
703
704//---------------------------------------------------------
705int CSG_MetaData::_Get_Property(const CSG_String &Name) const
706{
707 for(int i=0; i<m_Prop_Names.Get_Count(); i++)
708 {
709 if( Name.CmpNoCase(m_Prop_Names[i]) == 0 )
710 {
711 return( i );
712 }
713 }
714
715 return( -1 );
716}
717
718
720// //
722
723//---------------------------------------------------------
725{
726 CSG_String s;
727
728 if( Flags == 0 )
729 {
730 for(int i=0; i<Get_Children_Count(); i++)
731 {
732 s += Get_Child(i)->Get_Name() + ":\t" + Get_Child(i)->Get_Content() + "\n";
733 }
734 }
735 else
736 {
737 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
738
739 XML.SetRoot(pRoot);
740
741 Save(pRoot);
742
743 wxStringOutputStream Stream;
744
745 XML.Save(Stream);
746
747 s = &Stream.GetString();
748
749 if( Flags == 2 ) // remove <xml>
750 {
751 s = s.AfterFirst('\n');
752 }
753 }
754
755 return( s );
756}
757
758//---------------------------------------------------------
760{
761 CSG_Table t;
762
763 t.Add_Field("NAME" , SG_DATATYPE_String);
764 t.Add_Field("VALUE", SG_DATATYPE_String);
765
766 for(int i=0; i<Get_Children_Count(); i++)
767 {
769
770 r->Set_Value(0, Get_Child(i)->Get_Name());
771 r->Set_Value(1, Get_Child(i)->Get_Content());
772 }
773
774 return( t );
775}
776
777
779// //
781
782//---------------------------------------------------------
783bool CSG_MetaData::Assign(const CSG_MetaData &MetaData, bool bAddChildren)
784{
785 if( &MetaData != this )
786 {
787 Destroy();
788
789 Set_Name (MetaData.Get_Name ());
790 Set_Content(MetaData.Get_Content());
791
792 for(int i=0; i<MetaData.Get_Property_Count(); i++)
793 {
794 Add_Property(MetaData.Get_Property_Name(i), MetaData.Get_Property(i));
795 }
796
797 if( bAddChildren )
798 {
799 Add_Children(MetaData);
800 }
801 }
802
803 return( true );
804}
805
806
808// //
810
811//---------------------------------------------------------
812bool CSG_MetaData::Load(const CSG_String &File, const SG_Char *Extension)
813{
814 Destroy();
815
816 //-----------------------------------------------------
817 if( File.Find("http://") == 0 )
818 {
819 CSG_String s(File.Right(File.Length() - CSG_String("http://").Length()));
820
821 return( Load_HTTP(s.BeforeFirst('/'), s.AfterFirst('/')) );
822 }
823
824 //-----------------------------------------------------
825 CSG_String _File(SG_File_Make_Path("", File, Extension));
826
827 if( !SG_File_Exists(_File) )
828 {
829 return( false );
830 }
831
832 //-----------------------------------------------------
833 if( SG_File_Cmp_Extension(_File, "json") )
834 {
835 return( Load_JSON(_File) );
836 }
837
838 //-----------------------------------------------------
839 wxXmlDocument XML;
840
841 if( XML.Load(_File.c_str()) )
842 {
843 Load(XML.GetRoot());
844
845 return( true );
846 }
847
848 //-----------------------------------------------------
849 return( false );
850}
851
852//---------------------------------------------------------
854{
855 Destroy();
856
857 wxXmlDocument XML;
858
859 if( File.is_Reading() && XML.Load(*((wxInputStream *)File.Get_Stream())) )
860 {
861 Load(XML.GetRoot());
862
863 return( true );
864 }
865
866 return( false );
867}
868
869//---------------------------------------------------------
870bool CSG_MetaData::Load(wxXmlNode *pNode)
871{
872 m_Name = pNode->GetName ().wc_str();
873 m_Content = pNode->GetNodeContent().wc_str();
874
875 //-----------------------------------------------------
876 wxXmlAttribute *pProperty = pNode->GetAttributes();
877
878 while( pProperty )
879 {
880 Add_Property(&pProperty->GetName(), &pProperty->GetValue());
881
882 pProperty = pProperty->GetNext();
883 }
884
885 //-----------------------------------------------------
886 wxXmlNode *pChild = pNode->GetChildren();
887
888 while( pChild )
889 {
890 if( pChild->GetType() != wxXML_TEXT_NODE )
891 {
892 Add_Child()->Load(pChild);
893 }
894
895 pChild = pChild->GetNext();
896 }
897
898 return( true );
899}
900
901
903// //
905
906//---------------------------------------------------------
907bool CSG_MetaData::Save(const CSG_String &File, const SG_Char *Extension) const
908{
909 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
910
911 XML.SetRoot(pRoot);
912
913 Save(pRoot);
914
915 if( XML.Save(SG_File_Make_Path("", File, Extension).c_str()) )
916 {
917 return( true );
918 }
919
920 return( false );
921}
922
923//---------------------------------------------------------
925{
926 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
927
928 XML.SetRoot(pRoot);
929
930 Save(pRoot);
931
932 if( File.is_Writing() && XML.Save(*((wxOutputStream *)File.Get_Stream())) )
933 {
934 return( true );
935 }
936
937 return( false );
938}
939
940//---------------------------------------------------------
941bool CSG_MetaData::Save(wxXmlNode *pNode) const
942{
943 CSG_String Name(Get_Name()); if( Name.is_Empty() ) { Name = "NODE"; } else { Name.Replace(" ", "_"); } // name must not contain spaces!
944
945 pNode->SetName(Name.c_str());
946
947 pNode->SetContent(Get_Content().c_str());
948
949 if( Get_Content().Length() > 0 || (Get_Property_Count() == 0 && Get_Children_Count() == 0) )
950 {
951 wxXmlNode *pChild = new wxXmlNode(pNode, wxXML_TEXT_NODE, SG_T("TEXT"));
952
953 pChild->SetContent(Get_Content().c_str());
954 }
955
956 //-----------------------------------------------------
957 for(int i=0; i<Get_Property_Count(); i++)
958 {
959 pNode->AddAttribute(Get_Property_Name(i).c_str(), Get_Property(i));
960 }
961
962 //-----------------------------------------------------
963 for(int i=Get_Children_Count()-1; i>=0; i--)
964 {
965 Get_Child(i)->Save(new wxXmlNode(pNode, wxXML_ELEMENT_NODE, Get_Child(i)->Get_Name().c_str()));
966 }
967
968 return( true );
969}
970
971
973// //
975
976//---------------------------------------------------------
977bool CSG_MetaData::from_XML(const char *_XML, size_t Length, const char *Encoding)
978{
979 Destroy();
980
981 wxXmlDocument XML; wxMemoryInputStream Stream((const void *)_XML, Length);
982
983#if wxCHECK_VERSION(3, 3, 0)
984 if( XML.Load(Stream) )
985#else
986 if( XML.Load(Stream, Encoding) )
987#endif
988 {
989 Load(XML.GetRoot());
990
991 return( true );
992 }
993
994 return( false );
995}
996
997//---------------------------------------------------------
999{
1000 Destroy();
1001
1002 wxXmlDocument XML; wxMemoryInputStream Stream((const void *)_XML.c_str(), sizeof(SG_Char) * _XML.Length());
1003
1004 if( XML.Load(Stream) )
1005 {
1006 Load(XML.GetRoot());
1007
1008 return( true );
1009 }
1010
1011 return( false );
1012}
1013
1014//---------------------------------------------------------
1016{
1017 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
1018
1019 XML.SetRoot(pRoot);
1020
1021 Save(pRoot);
1022
1023 wxMemoryOutputStream Stream;
1024
1025 if( XML.Save(Stream) )
1026 {
1027 CSG_Array s(sizeof(char), Stream.GetSize());
1028
1029 Stream.CopyTo(s.Get_Array(), s.Get_Size());
1030
1031 _XML = (const char *)s.Get_Array();
1032
1033 return( true );
1034 }
1035
1036 return( false );
1037}
1038
1039
1041// //
1043
1044//---------------------------------------------------------
1045bool CSG_MetaData::Load_HTTP(const CSG_String &Server, const CSG_String &Path, const SG_Char *Username, const SG_Char *Password)
1046{
1047 Destroy();
1048
1049 //-----------------------------------------------------
1050 wxHTTP HTTP;
1051
1052 if( Username && *Username ) { HTTP.SetUser (Username); }
1053 if( Password && *Password ) { HTTP.SetPassword(Password); }
1054
1055 wxString s = Server.c_str();
1056
1057 if( s.Find("http://") == 0 )
1058 {
1059 s = s.Right(s.Length() - wxString("http://").Length());
1060 }
1061
1062 if( !HTTP.Connect(s) )
1063 {
1064 return( false );
1065 }
1066
1067 //-----------------------------------------------------
1068 s = Path.c_str();
1069
1070 if( s[0] != '/' )
1071 {
1072 s.Prepend("/");
1073 }
1074
1075 wxInputStream *pStream = HTTP.GetInputStream(s);
1076
1077 if( !pStream )
1078 {
1079 return( false );
1080 }
1081
1082 wxXmlDocument XML;
1083
1084 if( XML.Load(*pStream) )
1085 {
1086 Load(XML.GetRoot());
1087
1088 delete(pStream);
1089
1090 return( true );
1091 }
1092
1093 delete(pStream);
1094
1095 return( false );
1096}
1097
1098
1100// //
1102
1103//---------------------------------------------------------
1105{
1106 CSG_File Stream; CSG_String JSON;
1107
1108 if( Stream.Open(File, SG_FILE_R, false) && Stream.Read(JSON, (size_t)Stream.Length()) > 0 )
1109 {
1110 return( from_JSON(JSON) );
1111 }
1112
1113 return( false );
1114}
1115
1116//---------------------------------------------------------
1118{
1119 CSG_File Stream; CSG_String JSON;
1120
1121 if( Stream.Open(File, SG_FILE_W, false, SG_FILE_ENCODING_UTF8) && to_JSON(JSON) && Stream.Write(JSON) )
1122 {
1123 return( true );
1124 }
1125
1126 return( false );
1127}
1128
1129//---------------------------------------------------------
1131{
1132 Destroy();
1133 Create();
1134
1135 Set_Name("root");
1136
1137 picojson::value root;
1138 std::string err = picojson::parse(root, JSON.b_str());
1139
1140 if( !err.empty() )
1141 {
1142 return false;
1143 }
1144
1145 _JSON_To_MetaData(root, this);
1146
1147
1148 return( true );
1149}
1150
1151//---------------------------------------------------------
1153{
1154 if( Get_Parent() && !Get_Parent()->Cmp_Property("type", "array") )
1155 {
1156 JSON += "\"";
1157 JSON += _JSON_Escape_String(Get_Name());
1158 JSON += "\": ";
1159 }
1160
1161 if( Cmp_Property("type", "array") )
1162 {
1163 JSON += "[";
1164 for(int i=0; i<Get_Children_Count(); ++i)
1165 {
1166 if( i > 0 )
1167 {
1168 JSON += ",";
1169 }
1170 Get_Child(i)->to_JSON(JSON);
1171 }
1172 JSON += "]";
1173 }
1174 else if( Get_Children_Count() > 0 )
1175 {
1176 JSON += "{";
1177 for(int i=0; i<Get_Children_Count(); ++i)
1178 {
1179 if( i > 0 )
1180 {
1181 JSON += ",";
1182 }
1183 Get_Child(i)->to_JSON(JSON);
1184 }
1185 JSON += "}";
1186 }
1187 else
1188 {
1189 if( Cmp_Property("type","string") )
1190 {
1191 JSON += "\"";
1192 JSON += _JSON_Escape_String(Get_Content());
1193 JSON += "\"";
1194 }
1195 if( Cmp_Property("type","number") )
1196 {
1197 JSON += Get_Content();
1198 }
1199 if( Cmp_Property("type","boolean") )
1200 {
1201 JSON += Get_Content();
1202 }
1203 if( Cmp_Property("type","null") )
1204 {
1205 JSON += "null";
1206 }
1207 }
1208 return( true );
1209}
1210
1211//---------------------------------------------------------
1212void CSG_MetaData::_JSON_To_MetaData(const picojson::value &j, CSG_MetaData *pNode)
1213{
1214 if( j.is<picojson::object>() )
1215 {
1216 const picojson::object &obj = j.get<picojson::object>();
1217
1218 for( auto it = obj.begin(); it != obj.end(); ++it )
1219 {
1220 CSG_MetaData *pChild = pNode->Add_Child(it->first.c_str());
1221 _JSON_To_MetaData(it->second, pChild);
1222 }
1223 }
1224
1225 else if( j.is<picojson::array>() )
1226 {
1227 const picojson::array &arr = j.get<picojson::array>();
1228
1229 pNode->Add_Property("type", "array");
1230
1231 for( size_t i = 0; i < arr.size(); ++i )
1232 {
1233 CSG_MetaData *pItem = pNode->Add_Child("item");
1234 _JSON_To_MetaData(arr[i], pItem);
1235 }
1236 }
1237
1238 else
1239 {
1240 if( j.is<std::string>() )
1241 {
1242 pNode->Set_Content(j.get<std::string>().c_str());
1243 pNode->Add_Property("type", "string");
1244 }
1245 else if( j.is<double>() )
1246 {
1247 pNode->Set_Content(CSG_String::Format("%g", j.get<double>()));
1248 pNode->Add_Property("type", "number");
1249 }
1250
1251 else if( j.is<bool>() )
1252 {
1253 pNode->Set_Content(j.get<bool>() ? "true" : "false");
1254 pNode->Add_Property("type", "boolean");
1255 }
1256 else
1257 {
1258 pNode->Set_Content("null");
1259 pNode->Add_Property("type", "null");
1260 }
1261 }
1262}
1263
1264
1265//---------------------------------------------------------
1266CSG_String CSG_MetaData::_JSON_Escape_String(const CSG_String &s) const
1267{
1268 CSG_String out;
1269
1270 for(size_t i=0; i<s.Length(); ++i)
1271 {
1272 switch( s[i] )
1273 {
1274 case '\"': out += "\\\""; break;
1275 case '\\': out += "\\\\"; break;
1276 case '\b': out += "\\b" ; break;
1277 case '\f': out += "\\f" ; break;
1278 case '\n': out += "\\n" ; break;
1279 case '\r': out += "\\r" ; break;
1280 case '\t': out += "\\t" ; break;
1281 default: out += s[i] ; break;
1282 }
1283 }
1284 return( out );
1285}
1286
1287
1289// //
1290// //
1291// //
1293
1294//---------------------------------------------------------
1296{
1297 m_pHTTP = NULL;
1298}
1299
1301{
1302 return( Destroy() );
1303}
1304
1305//---------------------------------------------------------
1306CSG_HTTP::CSG_HTTP(const CSG_String &Server, const CSG_String &User, const CSG_String &Password)
1307{
1308 m_pHTTP = NULL;
1309
1310 Create(Server, User, Password);
1311}
1312
1313bool CSG_HTTP::Create(const CSG_String &Server, const CSG_String &User, const CSG_String &Password)
1314{
1315 Destroy();
1316
1317 m_pHTTP = new wxHTTP;
1318
1319 if( !User .is_Empty() ) { m_pHTTP->SetUser (User .wx_str()); }
1320 if( !Password.is_Empty() ) { m_pHTTP->SetPassword(Password.wx_str()); }
1321
1322 wxString Host= Server.wx_str(); unsigned short Port = 80;
1323
1324 #define SERVER_TRIM(s, p) { wxString sp(p); sp += "://"; if( s.Find(p) == 0 ) { s = s.Right(s.Length() - sp.Length()); } }
1325
1326 SERVER_TRIM(Host, "https");
1327 SERVER_TRIM(Host, "http" );
1328
1329 if( Host.Find(":") >= 0 )
1330 {
1331 long _Port;
1332
1333 if( Host.AfterLast(':').ToLong(&_Port) )
1334 {
1335 Port = (unsigned short)_Port;
1336 }
1337
1338 Host = Host.BeforeLast(':');
1339 }
1340
1341 if( !m_pHTTP->Connect(Host, Port) )
1342 {
1343 Destroy();
1344
1345 return( false );
1346 }
1347
1348 return( true );
1349}
1350
1351//---------------------------------------------------------
1353{
1354 Destroy();
1355}
1356
1358{
1359 if( m_pHTTP )
1360 {
1361 delete(m_pHTTP);
1362
1363 m_pHTTP = NULL;
1364 }
1365
1366 return( true );
1367}
1368
1369//---------------------------------------------------------
1370wxInputStream * CSG_HTTP::_Request(const CSG_String &Request)
1371{
1372 if( !is_Connected() )
1373 {
1374 wxString s(Request.c_str()); if( s[0] != '/' ) { s.Prepend("/"); }
1375
1376 wxInputStream *pStream = m_pHTTP->GetInputStream(s);
1377
1378 if( pStream )
1379 {
1380 if( pStream->CanRead() )
1381 {
1382 return( pStream );
1383 }
1384
1385 delete(pStream);
1386 }
1387 }
1388
1389 return( NULL );
1390}
1391
1392//---------------------------------------------------------
1394{
1395 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1396
1397 wxXmlDocument XML;
1398
1399 if( !XML.Load(*pStream) )
1400 {
1401 delete(pStream);
1402
1403 return( false );
1404 }
1405
1406 Answer.Destroy(); Answer.Load(XML.GetRoot());
1407
1408 delete(pStream);
1409
1410 return( true );
1411}
1412
1413//---------------------------------------------------------
1415{
1416 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1417
1418 Answer.Clear();
1419
1420 while( pStream->CanRead() )
1421 {
1422 char Byte; pStream->Read(&Byte, sizeof(Byte)); Answer += Byte;
1423 }
1424
1425 delete(pStream);
1426
1427 return( true );
1428}
1429
1430//---------------------------------------------------------
1432{
1433 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1434
1435 Answer.Clear();
1436
1437 while( pStream->CanRead() )
1438 {
1439 char Byte; pStream->Read(&Byte, sizeof(Byte)); Answer += Byte;
1440 }
1441
1442 delete(pStream);
1443
1444 return( true );
1445}
1446
1447//---------------------------------------------------------
1449{
1450 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1451
1452 wxFileOutputStream *pFile = new wxFileOutputStream(File);
1453
1454 if( !pFile )
1455 {
1456 delete(pStream);
1457
1458 return( false );
1459 }
1460
1461 pFile->Write(*pStream);
1462
1463 delete(pFile);
1464
1465 delete(pStream);
1466
1467 return( true );
1468}
1469
1470
1472// //
1473// //
1474// //
1476
1477//---------------------------------------------------------
1479{
1480 Create();
1481}
1482
1484{
1485 Destroy();
1486
1487 return( true );
1488}
1489
1490//---------------------------------------------------------
1491CSG_WebRequest::CSG_WebRequest(const CSG_String &Server, const CSG_String &User, const CSG_String &Password)
1492{
1493 Create(Server, User, Password);
1494}
1495
1496bool CSG_WebRequest::Create(const CSG_String &Server, const CSG_String &User, const CSG_String &Password)
1497{
1498 Destroy();
1499
1500 m_Server = Server;
1501
1502 if( !User.is_Empty() || !Password.is_Empty() )
1503 {
1504 #if !wxCHECK_VERSION(3, 3, 0)
1505 m_User = User; m_Password = Password;
1506 #else
1507 wxURI URI; URI.SetUserAndPassword(User.wx_str(), Password.wx_str());
1508
1509 m_User = URI.GetUser().wx_str(); m_Password = URI.GetPassword().wx_str();
1510 #endif
1511 }
1512
1513 return( true );
1514}
1515
1516//---------------------------------------------------------
1518{
1519 m_Server.Clear(); m_User.Clear(), m_Password.Clear();
1520
1521 return( true );
1522}
1523
1524
1526// //
1528
1529//---------------------------------------------------------
1530#if !wxCHECK_VERSION(3, 3, 0)
1531bool CSG_WebRequest::Request( const CSG_String &Request, CSG_Bytes &Answer ) { return( false ); }
1532bool CSG_WebRequest::Request( const CSG_String &Request, CSG_MetaData &Answer ) { return( false ); }
1533bool CSG_WebRequest::Request( const CSG_String &Request, CSG_String &Answer ) { return( false ); }
1534bool CSG_WebRequest::Request( const CSG_String &Request, const SG_Char *File ) { return( false ); }
1535bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_Bytes &Answer ) { return( false ); }
1536bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_MetaData &Answer ) { return( false ); }
1537bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_String &Answer ) { return( false ); }
1538bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, const SG_Char *File ) { return( false ); }
1539bool CSG_WebRequest::Post ( const CSG_String &Request, const CSG_String &Body, CSG_Bytes &Answer, const CSG_String &ContentType) { return( false ); }
1540bool CSG_WebRequest::Post ( const CSG_String &Request, const CSG_String &Body, CSG_MetaData &Answer, const CSG_String &ContentType) { return( false ); }
1541bool CSG_WebRequest::Post ( const CSG_String &Request, const CSG_String &Body, CSG_String &Answer, const CSG_String &ContentType) { return( false ); }
1542bool CSG_WebRequest::Post ( const CSG_String &Request, const CSG_String &Body, const SG_Char *File, const CSG_String &ContentType) { return( false ); }
1543bool CSG_WebRequest::Post (const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_Bytes &Answer, const CSG_String &ContentType) { return( false ); }
1544bool CSG_WebRequest::Post (const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_MetaData &Answer, const CSG_String &ContentType) { return( false ); }
1545bool CSG_WebRequest::Post (const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_String &Answer, const CSG_String &ContentType) { return( false ); }
1546bool CSG_WebRequest::Post (const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, const SG_Char *File, const CSG_String &ContentType) { return( false ); }
1547#else
1548
1549//---------------------------------------------------------
1550static wxWebRequestSync _Create_Request(const CSG_String &Server, const CSG_String &User, const CSG_String &Password, const CSG_String &Request)
1551{
1552 if( !Server.is_Empty() && !Request.is_Empty() )
1553 {
1554 wxWebSessionSync::GetDefault().SetBaseURL(Server.wx_str());
1555 }
1556
1557 CSG_String URL = Request.is_Empty() ? Server : Request;
1558
1559 auto request = wxWebSessionSync::GetDefault().CreateRequest(URL.wx_str());
1560
1561 #if wxCHECK_VERSION(3, 3, 2)
1562 if( !User.is_Empty() || !Password.is_Empty() )
1563 {
1564 request.UseBasicAuth(wxWebCredentials(User.wx_str(), wxSecretValue(Password.wx_str())));
1565 }
1566 #endif
1567
1568 return( request );
1569}
1570
1571//---------------------------------------------------------
1572static bool _Response_to_Bytes(const wxWebResponse &Response, CSG_Bytes &Answer)
1573{
1574 wxInputStream *pStream = Response.GetStream();
1575
1576 if( pStream->IsOk() )
1577 {
1578 int Byte = pStream->GetC();
1579
1580 while( Byte != wxEOF )
1581 {
1582 Answer += (BYTE)Byte;
1583
1584 Byte = pStream->GetC();
1585 }
1586
1587 return( true );
1588 }
1589
1590 return( false );
1591}
1592
1593//---------------------------------------------------------
1594static bool _Response_to_MetaData(const wxWebResponse &Response, CSG_MetaData &Answer)
1595{
1596 wxString MimeType = Response.GetMimeType();
1597 CSG_String String = Response.AsString().wx_str();
1598
1599 if( MimeType.Contains("xml") )
1600 {
1601 wxXmlDocument XML;
1602
1603 if( XML.Load(*Response.GetStream()) )
1604 {
1605 Answer.Load(XML.GetRoot());
1606
1607 return( true );
1608 }
1609 }
1610 else if( MimeType.Contains("json") )
1611 {
1612 return( Answer.from_JSON(String) );
1613 }
1614
1615 return( false );
1616}
1617
1618//---------------------------------------------------------
1619static bool _Response_to_String(const wxWebResponse &Response, CSG_String &Answer)
1620{
1621 Answer = Response.AsString().wx_str();
1622
1623 return( true );
1624}
1625
1626//---------------------------------------------------------
1627static bool _Response_to_File(const wxWebResponse &Response, const SG_Char *File)
1628{
1629 wxFileOutputStream Output(File);
1630
1631 if( Output.IsOk() )
1632 {
1633 Output.Write(*Response.GetStream());
1634
1635 return( true );
1636 }
1637
1638 return( false );
1639}
1640
1641
1643// //
1645
1646//---------------------------------------------------------
1647bool CSG_WebRequest::Request(const CSG_String &Request, CSG_Bytes &Answer)
1648{
1649 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1650 if( !request.Execute() ) { return( false ); }
1651
1652 //-----------------------------------------------------
1653 return( _Response_to_Bytes(request.GetResponse(), Answer) );
1654}
1655
1656//---------------------------------------------------------
1657bool CSG_WebRequest::Request(const CSG_String &Request, CSG_MetaData &Answer)
1658{
1659 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1660 if( !request.Execute() ) { return( false ); }
1661
1662 //-----------------------------------------------------
1663 return( _Response_to_MetaData(request.GetResponse(), Answer) );
1664}
1665
1666//---------------------------------------------------------
1667bool CSG_WebRequest::Request(const CSG_String &Request, CSG_String &Answer)
1668{
1669 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1670 if( !request.Execute() ) { return( false ); }
1671
1672 //-----------------------------------------------------
1673 return( _Response_to_String(request.GetResponse(), Answer) );
1674}
1675
1676//---------------------------------------------------------
1677bool CSG_WebRequest::Request(const CSG_String &Request, const SG_Char *File)
1678{
1679 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1680 if( !request.Execute() ) { return( false ); }
1681
1682 //-----------------------------------------------------
1683 return( _Response_to_File(request.GetResponse(), File) );
1684}
1685
1686
1688// //
1690
1691//---------------------------------------------------------
1692bool CSG_WebRequest::Post(const CSG_String &Request, const CSG_String &Body, CSG_Bytes &Answer, const CSG_String &ContentType )
1693{
1694 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1695 request.SetMethod("POST");
1696 request.SetData(Body.wx_str(), ContentType.wx_str());
1697 if( !request.Execute() ) { return false; }
1698
1699 //-----------------------------------------------------
1700 return( _Response_to_Bytes(request.GetResponse(), Answer) );
1701}
1702
1703//---------------------------------------------------------
1704bool CSG_WebRequest::Post(const CSG_String &Request, const CSG_String &Body, CSG_MetaData &Answer, const CSG_String &ContentType )
1705{
1706 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1707 request.SetMethod("POST");
1708 request.SetData(Body.wx_str(), ContentType.wx_str());
1709 if( !request.Execute() ) { return false; }
1710
1711 //-----------------------------------------------------
1712 return( _Response_to_MetaData(request.GetResponse(), Answer) );
1713}
1714
1715//---------------------------------------------------------
1716bool CSG_WebRequest::Post(const CSG_String &Request, const CSG_String &Body, CSG_String &Answer, const CSG_String &ContentType )
1717{
1718 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1719 request.SetMethod("POST");
1720 request.SetData(Body.wx_str(), ContentType.wx_str());
1721 if( !request.Execute() ) { return false; }
1722
1723 //-----------------------------------------------------
1724 return( _Response_to_String(request.GetResponse(), Answer) );
1725}
1726
1727//---------------------------------------------------------
1728bool CSG_WebRequest::Post(const CSG_String &Request, const CSG_String &Body, const SG_Char *File, const CSG_String &ContentType )
1729{
1730 auto request = _Create_Request(m_Server, m_User, m_Password, Request);
1731 request.SetMethod("POST");
1732 request.SetData(Body.wx_str(), ContentType.wx_str());
1733 if( !request.Execute() ) { return false; }
1734
1735 //-----------------------------------------------------
1736 return( _Response_to_File(request.GetResponse(), File) );
1737}
1738
1739
1741// //
1743
1744//---------------------------------------------------------
1745bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_Bytes &Answer)
1746{
1747 auto request = _Create_Request(Server, "", "", Request);
1748 if( !request.Execute() ) { return( false ); }
1749
1750 //-----------------------------------------------------
1751 return( _Response_to_Bytes(request.GetResponse(), Answer) );
1752}
1753
1754//---------------------------------------------------------
1755bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_MetaData &Answer)
1756{
1757 auto request = _Create_Request(Server, "", "", Request);
1758 if( !request.Execute() ) { return( false ); }
1759
1760 //-----------------------------------------------------
1761 return( _Response_to_MetaData(request.GetResponse(), Answer) );
1762}
1763
1764//---------------------------------------------------------
1765bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, CSG_String &Answer)
1766{
1767 auto request = _Create_Request(Server, "", "", Request);
1768 if( !request.Execute() ) { return( false ); }
1769
1770 //-----------------------------------------------------
1771 return( _Response_to_String(request.GetResponse(), Answer) );
1772}
1773
1774
1775//---------------------------------------------------------
1776bool CSG_WebRequest::Request(const CSG_String &Server, const CSG_String &Request, const SG_Char *File)
1777{
1778 auto request = _Create_Request(Server, "", "", Request);
1779 if( !request.Execute() ) { return( false ); }
1780
1781 //-----------------------------------------------------
1782 return( _Response_to_File(request.GetResponse(), File) );
1783}
1784
1785
1787// //
1789
1790//---------------------------------------------------------
1791bool CSG_WebRequest::Post(const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_Bytes &Answer, const CSG_String &ContentType)
1792{
1793 auto request = _Create_Request(Server, "", "", Request);
1794 request.SetMethod("POST");
1795 request.SetData(Body.wx_str(), ContentType.wx_str());
1796 if( !request.Execute() ) { return false; }
1797
1798 //-----------------------------------------------------
1799 return( _Response_to_Bytes(request.GetResponse(), Answer) );
1800}
1801
1802
1803//---------------------------------------------------------
1804bool CSG_WebRequest::Post(const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_MetaData &Answer, const CSG_String &ContentType)
1805{
1806 auto request = _Create_Request(Server, "", "", Request);
1807 request.SetMethod("POST");
1808 request.SetData(Body.wx_str(), ContentType.wx_str());
1809 if( !request.Execute() ) { return false; }
1810
1811 //-----------------------------------------------------
1812 return( _Response_to_MetaData(request.GetResponse(), Answer) );
1813}
1814
1815//---------------------------------------------------------
1816bool CSG_WebRequest::Post(const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, CSG_String &Answer, const CSG_String &ContentType)
1817{
1818 auto request = _Create_Request(Server, "", "", Request);
1819 request.SetMethod("POST");
1820 request.SetData(Body.wx_str(), ContentType.wx_str());
1821 if( !request.Execute() ) { return false; }
1822
1823 //-----------------------------------------------------
1824 return( _Response_to_String(request.GetResponse(), Answer) );
1825}
1826
1827//---------------------------------------------------------
1828bool CSG_WebRequest::Post(const CSG_String &Server, const CSG_String &Request, const CSG_String &Body, const SG_Char *File, const CSG_String &ContentType)
1829{
1830 auto request = _Create_Request(Server, "", "", Request);
1831 request.SetMethod("POST");
1832 request.SetData(Body.wx_str(), ContentType.wx_str());
1833 if( !request.Execute() ) { return false; }
1834
1835 //-----------------------------------------------------
1836 return( _Response_to_File(request.GetResponse(), File) );
1837}
1838
1839//---------------------------------------------------------
1840#endif // #if wxCHECK_VERSION(3, 3, 0)
1841
1842
1844// //
1846
1847//---------------------------------------------------------
1848bool SG_FTP_Download(const CSG_String &Target_Directory, const CSG_String &Source, const CSG_String &User, const CSG_String &Password, unsigned short Port, bool bBinary, bool bVerbose)
1849{
1850 CSG_String _Source(Source); _Source.Trim();
1851
1852 if( _Source.Find("ftp://") == 0 )
1853 {
1854 _Source = _Source.Right(_Source.Length() - CSG_String("ftp://").Length());
1855 }
1856
1857 CSG_String ftpHost = _Source.BeforeFirst('/');
1858 CSG_String ftpDir = _Source.AfterFirst ('/').BeforeLast('/'); // ftpDir.Prepend("/");
1859 CSG_String ftpFile = _Source.AfterLast ('/');
1860
1861 //-----------------------------------------------------
1862 wxFTP ftp;
1863
1864 if( !User .is_Empty() ) { ftp.SetUser (User .wx_str()); }
1865 if( !Password.is_Empty() ) { ftp.SetPassword(Password.wx_str()); }
1866
1867 if( !ftp.Connect(ftpHost.c_str(), Port) )
1868 {
1869 if( bVerbose )
1870 {
1871 SG_UI_Msg_Add_Error(_TL("Couldn't connect"));
1872 }
1873
1874 return( false );
1875 }
1876
1877 //-----------------------------------------------------
1878 if( !ftpDir.is_Empty() && !ftp.ChDir(ftpDir.c_str()) )
1879 {
1880 if( bVerbose )
1881 {
1882 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't change to directory"), ftpDir.c_str()));
1883 }
1884
1885 return( false );
1886 }
1887
1888 if( ftp.GetFileSize(ftpFile.c_str()) == -1 )
1889 {
1890 if( bVerbose )
1891 {
1892 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file size"), ftpFile.c_str()));
1893 }
1894 }
1895
1896 //-----------------------------------------------------
1897 wxInputStream *pStream = ftp.GetInputStream(ftpFile.c_str());
1898
1899 if( !pStream )
1900 {
1901 if( bVerbose )
1902 {
1903 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file"), ftpFile.c_str()));
1904 }
1905
1906 return( false );
1907 }
1908
1909 //-----------------------------------------------------
1910 wxFileOutputStream *pFile = new wxFileOutputStream(SG_File_Make_Path(Target_Directory, ftpFile).c_str());
1911
1912 if( !pFile )
1913 {
1914 if( bVerbose )
1915 {
1916 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't create target file"), SG_File_Make_Path(Target_Directory, ftpFile).c_str()));
1917 }
1918
1919 delete(pStream);
1920
1921 return( false );
1922 }
1923
1924 //-----------------------------------------------------
1925 pFile->Write(*pStream);
1926
1927 delete(pFile);
1928 delete(pStream);
1929
1930 return( true );
1931}
1932
1933
1935// //
1937
1938//---------------------------------------------------------
1940{
1941 return( wxLaunchDefaultBrowser(URL.c_str()) );
1942}
1943
1944
1946// //
1948
1949//---------------------------------------------------------
1950bool SG_Open_Application(const CSG_String &_Reference, const CSG_String &Mime_Extension)
1951{
1952 CSG_String Reference(_Reference); Reference.Trim_Both();
1953
1954 if( Reference.is_Empty() )
1955 {
1956 return( false );
1957 }
1958
1959 if( Reference.Find("ftp:" ) == 0
1960 || Reference.Find("file:" ) == 0
1961 || Reference.Find("http:" ) == 0
1962 || Reference.Find("https:" ) == 0
1963 || Reference.Find("mailto:") == 0 )
1964 {
1965 return( wxLaunchDefaultBrowser(Reference.c_str()) );
1966 }
1967
1968 //-----------------------------------------------------
1969 if( SG_File_is_Relative(Reference) ) // very likely that this will not work
1970 {
1971 Reference = SG_File_Get_Path_Absolute(Reference); // this might not work either, but give it a try
1972 }
1973
1974 //-----------------------------------------------------
1975 bool bResult = false;
1976
1977 if( Mime_Extension.is_Empty() )
1978 {
1979 if( (bResult = wxLaunchDefaultApplication(Reference.c_str())) == false )
1980 {
1981 SG_UI_Msg_Add_Error(CSG_String::Format("%s:\n%s\n", _TL("failed to launch default application"), Reference.c_str()));
1982 }
1983 }
1984
1985 //-----------------------------------------------------
1986 else
1987 {
1988 wxFileType *pFileType = wxTheMimeTypesManager->GetFileTypeFromExtension(Mime_Extension.c_str());
1989
1990 if( pFileType )
1991 {
1992 wxString Command;
1993
1994 if( !pFileType->GetOpenCommand(&Command, wxFileType::MessageParameters(Reference.c_str(), "")) || !(bResult = wxExecute(Command) == 0) )
1995 {
1996 SG_UI_Msg_Add_Error(CSG_String::Format("%s:\n%s\n", _TL("command execution failed"), Command.wx_str()));
1997 }
1998
1999 delete(pFileType);
2000 }
2001 }
2002
2003 return( bResult );
2004}
2005
2006
2008// //
2009// //
2010// //
2012
2013//---------------------------------------------------------
void SG_UI_Msg_Add_Error(const char *Message)
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)
SAGA_API_DLL_EXPORT CSG_String SG_File_Get_Path_Absolute(const CSG_String &full_Path, const CSG_String &CWD="")
signed long long sLong
Definition api_core.h:158
#define SG_T(s)
Definition api_core.h:537
SAGA_API_DLL_EXPORT CSG_String SG_File_Make_Path(const CSG_String &Directory, const CSG_String &Name)
SAGA_API_DLL_EXPORT bool SG_File_is_Relative(const CSG_String &full_Path)
@ SG_DATATYPE_String
Definition api_core.h:1055
#define SG_Char
Definition api_core.h:536
#define _TL(s)
Definition api_core.h:1619
@ SG_FILE_ENCODING_UTF8
Definition api_core.h:552
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
@ SG_FILE_W
Definition api_core.h:1161
@ SG_FILE_R
Definition api_core.h:1160
void * Get_Array(void) const
Definition api_core.h:336
sLong Get_Size(void) const
Definition api_core.h:327
bool Clear(void)
sLong Length(void) const
Definition api_file.cpp:230
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
size_t Write(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:382
size_t Read(void *Buffer, size_t Size, size_t Count=1) const
Definition api_file.cpp:338
class wxStreamBase * Get_Stream(void) const
Definition api_core.h:1190
bool is_Writing(void) const
Definition api_core.h:1197
bool is_Reading(void) const
Definition api_core.h:1196
virtual ~CSG_HTTP(void)
bool is_Connected(void) const
Definition metadata.h:254
bool Request(const CSG_String &Request, CSG_Bytes &Answer)
bool Destroy(void)
CSG_HTTP(void)
bool Create(void)
bool Mov_Child(int from_Index, int to_Index)
Definition metadata.cpp:284
void Fmt_Content(const char *Format,...)
Definition metadata.cpp:536
bool to_XML(CSG_String &XML) const
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition metadata.cpp:487
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition metadata.cpp:907
const CSG_String & Get_Name(void) const
Definition metadata.h:138
bool Create(void)
Definition metadata.cpp:76
bool Assign(const CSG_MetaData &MetaData, bool bAddChildren=true)
Definition metadata.cpp:783
bool Del_Children(int Depth=0, const SG_Char *Name=NULL)
Definition metadata.cpp:384
class CSG_Table Get_Table(int Flags=0) const
Definition metadata.cpp:759
int Get_Children_Count(void) const
Definition metadata.h:154
CSG_MetaData * Get_Child(int Index) const
Definition metadata.h:155
bool Load_JSON(const CSG_String &File)
bool Save_JSON(const CSG_String &File) const
bool Set_Property(const CSG_String &Name, const CSG_String &Value, bool bAddIfNotExists=true)
Definition metadata.cpp:641
bool Cmp_Content(const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:574
CSG_MetaData * Get_Child_by_JSON_Pointer(const CSG_String &JSON_Pointer) const
Definition metadata.cpp:445
bool Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:697
bool Add_Children(const CSG_MetaData &MetaData)
Definition metadata.cpp:362
CSG_MetaData * Get_Parent(void) const
Definition metadata.h:151
CSG_MetaData(void)
Definition metadata.cpp:71
const CSG_String & Get_Property_Name(int Index) const
Definition metadata.h:187
virtual ~CSG_MetaData(void)
Definition metadata.cpp:137
const CSG_String & Get_Content(void) const
Definition metadata.h:139
bool Load_HTTP(const CSG_String &Server, const CSG_String &Path, const SG_Char *Username=NULL, const SG_Char *Password=NULL)
const SG_Char * Get_Property(int Index) const
Definition metadata.h:188
bool Del_Child(int Index)
Definition metadata.cpp:324
void Set_Name(const CSG_String &Name)
Definition metadata.h:136
CSG_String asText(int Flags=0) const
Definition metadata.cpp:724
void Set_Content(const CSG_String &Content)
Definition metadata.h:146
bool from_JSON(const CSG_String &JSON)
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:169
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition metadata.cpp:812
void Destroy(void)
Definition metadata.cpp:143
bool Del_Property(const CSG_String &Name)
Definition metadata.cpp:614
bool from_XML(const char *XML, size_t Length, const char *Encoding="UTF-8")
Definition metadata.cpp:977
bool to_JSON(CSG_String &JSON) const
int Get_Property_Count(void) const
Definition metadata.h:186
CSG_MetaData * Ins_Child(int Position)
Definition metadata.cpp:210
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:585
size_t Length(void) const
CSG_String AfterFirst(char Character) const
bool asInt(int &Value) const
int CmpNoCase(const CSG_String &String) const
CSG_String AfterLast(char Character) const
int Cmp(const CSG_String &String) const
void Clear(void)
CSG_String BeforeFirst(char Character) const
size_t Replace(const CSG_String &Old, const CSG_String &New, bool bReplaceAll=true)
CSG_String BeforeLast(char Character) const
static CSG_String Format(const char *Format,...)
int Trim(bool fromRight=false)
int Find(char Character, bool fromEnd=false) const
bool asDouble(double &Value) const
CSG_String Right(size_t count) const
const SG_Char * c_str(void) const
int Trim_Both(void)
bool is_Empty(void) const
const class wxString & wx_str(void) const
Definition api_core.h:595
CSG_String & Prepend(const CSG_String &String)
sLong asLongLong(void) const
Definition api_core.h:684
int Get_Count(void) const
Definition api_core.h:725
bool Set_Value(int Field, const CSG_String &Value)
virtual CSG_Table_Record * Add_Record(CSG_Table_Record *pCopy=NULL)
Definition table.cpp:823
virtual bool Add_Field(const CSG_String &Name, TSG_Data_Type Type, int Position=-1)
Definition table.cpp:479
bool Post(const CSG_String &Request, const CSG_String &Body, CSG_Bytes &Answer, const CSG_String &ContentType="application/json")
bool Destroy(void)
bool Create(void)
bool Request(const CSG_String &Request, CSG_Bytes &Answer)
bool SG_Open_Application(const CSG_String &_Reference, const CSG_String &Mime_Extension)
bool SG_FTP_Download(const CSG_String &Target_Directory, const CSG_String &Source, const CSG_String &User, const CSG_String &Password, unsigned short Port, bool bBinary, bool bVerbose)
bool SG_Open_WebBrowser(const CSG_String &URL)
#define SERVER_TRIM(s, p)