SAGA API v9.10
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
57#include "metadata.h"
58#include "table.h"
59
60
62// //
63// //
64// //
66
67//---------------------------------------------------------
69{
70 _On_Construction();
71}
72
74{
75 return( true );
76}
77
78//---------------------------------------------------------
80{
81 _On_Construction();
82
83 Create(MetaData);
84}
85
87{
88 return( Assign(MetaData) );
89}
90
91//---------------------------------------------------------
92CSG_MetaData::CSG_MetaData(const CSG_String &File, const SG_Char *Extension)
93{
94 _On_Construction();
95
96 Create(File, Extension);
97}
98
99bool CSG_MetaData::Create(const CSG_String &File, const SG_Char *Extension)
100{
101 return( Load(File, Extension) );
102}
103
104//---------------------------------------------------------
106{
107 _On_Construction();
108
109 Create(Stream);
110}
111
113{
114 return( Load(Stream) );
115}
116
117//---------------------------------------------------------
119{
120 _On_Construction();
121
122 m_pParent = pParent;
123}
124
125//---------------------------------------------------------
126void CSG_MetaData::_On_Construction(void)
127{
128 m_pParent = NULL;
129
131}
132
133//---------------------------------------------------------
138
139//---------------------------------------------------------
141{
142 CSG_MetaData **m_pChildren = (CSG_MetaData **)m_Children.Get_Array();
143
144 for(int i=0; i<Get_Children_Count(); i++)
145 {
146 delete(m_pChildren[i]);
147 }
148
149 m_Children.Destroy();
150
151// m_pParent = NULL;
152
153// m_Name .Clear();
154// m_Content .Clear();
155
156 m_Prop_Names .Clear();
157 m_Prop_Values.Clear();
158}
159
160
162// //
164
165//---------------------------------------------------------
167{
168 return( Ins_Child(-1) );
169}
170
172{
173 return( Ins_Child(Name, -1) );
174}
175
177{
178 return( Ins_Child(Name, Content, -1) );
179}
180
181CSG_MetaData * CSG_MetaData::Add_Child(const CSG_String &Name, double Content)
182{
183 return( Ins_Child(Name, SG_Get_String(Content, -16), -1) );
184}
185
187{
188 return( Ins_Child(Name, CSG_String::Format(SG_T("%d"), Content), -1) );
189}
190
192{
193 return( Ins_Child(Name, CSG_String::Format(SG_T("%lld"), Content), -1) );
194}
195
196CSG_MetaData * CSG_MetaData::Add_Child(const CSG_MetaData &MetaData, bool bAddChildren)
197{
198 return( Ins_Child(MetaData, -1, bAddChildren) );
199}
200
201
203// //
205
206//---------------------------------------------------------
208{
209 if( !m_Children.Inc_Array() )
210 {
211 return( NULL );
212 }
213
214 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
215
216 if( Position < 0 || Position >= Get_Children_Count() )
217 {
218 Position = Get_Children_Count() - 1;
219 }
220
221 for(int i=Get_Children_Count()-1; i>Position; i--)
222 {
223 pChildren[i] = pChildren[i - 1];
224 }
225
226 return( pChildren[Position] = new CSG_MetaData(this) );
227}
228
229//---------------------------------------------------------
230CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, const CSG_String &Content, int Position)
231{
232 CSG_MetaData *pChild = Ins_Child(Position);
233
234 if( pChild )
235 {
236 pChild->m_Name = Name;
237 pChild->m_Content = Content;
238 }
239
240 return( pChild );
241}
242
244{
245 return( Ins_Child(Name, CSG_String(""), Position) );
246}
247
248CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, double Content, int Position)
249{
250 return( Ins_Child(Name, SG_Get_String(Content, -16), Position) );
251}
252
253CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, int Content, int Position)
254{
255 return( Ins_Child(Name, CSG_String::Format(SG_T("%d"), Content), Position) );
256}
257
258CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_String &Name, sLong Content, int Position)
259{
260 return( Ins_Child(Name, CSG_String::Format(SG_T("%lld"), Content), Position) );
261}
262
263CSG_MetaData * CSG_MetaData::Ins_Child(const CSG_MetaData &MetaData, int Position, bool bAddChildren)
264{
265 CSG_MetaData *pChild = Ins_Child(Position);
266
267 if( pChild )
268 {
269 pChild->Assign(MetaData, bAddChildren);
270 }
271
272 return( pChild );
273}
274
275
277// //
279
280//---------------------------------------------------------
281bool CSG_MetaData::Mov_Child(int from_Index, int to_Index)
282{
283 if( from_Index < 0 || from_Index >= Get_Children_Count()
284 || to_Index < 0 || to_Index >= Get_Children_Count() )
285 {
286 return( false );
287 }
288
289 if( from_Index != to_Index )
290 {
291 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
292 CSG_MetaData *pChild = pChildren[from_Index];
293
294 if( from_Index < to_Index )
295 {
296 for(int i=from_Index; i<to_Index; i++)
297 {
298 pChildren[i] = pChildren[i + 1];
299 }
300 }
301 else // if( from_Index > to_Index )
302 {
303 for(int i=from_Index; i>to_Index; i--)
304 {
305 pChildren[i] = pChildren[i - 1];
306 }
307 }
308
309 pChildren[to_Index] = pChild;
310 }
311
312 return( true );
313}
314
315
317// //
319
320//---------------------------------------------------------
322{
323 if( Index >= 0 && Index < Get_Children_Count() )
324 {
325 CSG_MetaData **pChildren = (CSG_MetaData **)m_Children.Get_Array();
326
327 delete(pChildren[Index]);
328
329 for(int i=Index, j=Index+1; j<Get_Children_Count(); i++, j++)
330 {
331 pChildren[i] = pChildren[j];
332 }
333
334 m_Children.Dec_Array();
335
336 return( true );
337 }
338
339 return( false );
340}
341
342//---------------------------------------------------------
344{
345 if( Name.Find('.') > 0 )
346 {
347 CSG_MetaData *pParent = Get_Child(Name.BeforeLast('.'));
348
349 if( pParent )
350 {
351 return( pParent->Del_Child(Name.AfterLast('.')) );
352 }
353 }
354
355 return( Del_Child(_Get_Child(Name)) );
356}
357
358//---------------------------------------------------------
360{
361 if( &MetaData != this )
362 {
363 for(int i=0; i<MetaData.Get_Children_Count(); i++)
364 {
365 Add_Child(MetaData[i], true);
366 }
367 }
368
369 return( true );
370}
371
372//---------------------------------------------------------
380//---------------------------------------------------------
381bool CSG_MetaData::Del_Children(int Depth, const SG_Char *Name)
382{
383 if( Depth < 0 )
384 {
385 // nop
386 }
387 else if( Name && *Name )
388 {
389 for(int i=Get_Children_Count()-1; i>=0; i--)
390 {
391 if( Get_Child(i)->Get_Name().CmpNoCase(Name) )
392 {
393 Get_Child(i)->Del_Children(Depth, Name);
394 }
395 else if( Depth > 0 )
396 {
397 Get_Child(i)->Del_Children(Depth - 1, Name);
398 }
399 else
400 {
401 Del_Child(i);
402 }
403 }
404 }
405 else if( Depth > 0 )
406 {
407 for(int i=0; i<Get_Children_Count(); i++)
408 {
409 Get_Child(i)->Del_Children(Depth - 1, Name);
410 }
411 }
412 else
413 {
414 for(int i=0; i<Get_Children_Count(); i++)
415 {
416 delete(Get_Child(i));
417 }
418
419 m_Children.Destroy();
420 }
421
422 return( true );
423}
424
425//---------------------------------------------------------
427{
428 if( Name.Find('.') > 0 )
429 {
430 CSG_MetaData *pEntry = Get_Child(Name.BeforeFirst('.'));
431
432 if( pEntry )
433 {
434 return( pEntry->Get_Child(Name.AfterFirst('.')) );
435 }
436 }
437
438 return( Get_Child(_Get_Child(Name)) );
439}
440
441//---------------------------------------------------------
442int CSG_MetaData::_Get_Child(const CSG_String &Name) const
443{
444 for(int i=0; i<Get_Children_Count(); i++)
445 {
446 if( Name.CmpNoCase(Get_Child(i)->Get_Name()) == 0 )
447 {
448 return( i );
449 }
450 }
451
452 return( -1 );
453}
454
455
457// //
459
460//---------------------------------------------------------
461bool CSG_MetaData::Cmp_Name(const CSG_String &String, bool bNoCase) const
462{
463 return( bNoCase ? !m_Name.CmpNoCase(String) : !m_Name.Cmp(String) );
464}
465
466
468// //
470
471//---------------------------------------------------------
473{
474 if( Name.is_Empty() )
475 {
476 return( m_Content );
477 }
478
479 CSG_MetaData *pEntry = Get_Child(Name);
480
481 return( pEntry ? pEntry->Get_Content().c_str() : NULL );
482}
483
484//---------------------------------------------------------
485bool CSG_MetaData::Get_Content(const CSG_String &Name, CSG_String &Value) const
486{
487 const SG_Char *cString = Name.is_Empty() ? Get_Content().c_str() : Get_Content(Name);
488
489 if( cString )
490 {
491 Value = cString;
492
493 return( true );
494 }
495
496 return( false );
497}
498
499//---------------------------------------------------------
500bool CSG_MetaData::Get_Content(const CSG_String &Name, double &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asDouble (Value) ); }
501bool CSG_MetaData::Get_Content(const CSG_String &Name, int &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asInt (Value) ); }
502bool CSG_MetaData::Get_Content(const CSG_String &Name, sLong &Value) const { CSG_String s; return( Get_Content(Name, s) && s.asLongLong(Value) ); }
503
504
506// //
508
509//---------------------------------------------------------
510void CSG_MetaData::Fmt_Content(const char *Format, ...)
511{
512 wxString s; va_list argptr;
513
514#ifdef _SAGA_LINUX
515 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
516 va_start(argptr, _Format);
517 s.PrintfV(_Format, argptr);
518#else
519 va_start(argptr, Format);
520 s.PrintfV(Format, argptr);
521#endif
522
523 m_Content = CSG_String(&s);
524
525 va_end(argptr);
526}
527
528//---------------------------------------------------------
529void CSG_MetaData::Fmt_Content(const wchar_t *Format, ...)
530{
531 wxString s; va_list argptr;
532
533#ifdef _SAGA_LINUX
534 wxString _Format(Format); _Format.Replace("%s", "%ls"); // workaround as we only use wide characters since wx 2.9.4 so interpret strings as multibyte
535 va_start(argptr, _Format);
536 s.PrintfV(_Format, argptr);
537#else
538 va_start(argptr, Format);
539 s.PrintfV(Format, argptr);
540#endif
541
542 m_Content = CSG_String(&s);
543
544 va_end(argptr);
545}
546
547//---------------------------------------------------------
548bool CSG_MetaData::Cmp_Content(const CSG_String &String, bool bNoCase) const
549{
550 return( bNoCase ? !m_Content.CmpNoCase(String) : !m_Content.Cmp(String) );
551}
552
553
555// //
557
558//---------------------------------------------------------
559bool CSG_MetaData::Add_Property(const CSG_String &Name, const CSG_String &Value)
560{
561 if( !Value.is_Empty() &&_Get_Property(Name) < 0 )
562 {
563 m_Prop_Names .Add(Name );
564 m_Prop_Values.Add(Value);
565
566 return( true );
567 }
568
569 return( false );
570}
571
572bool CSG_MetaData::Add_Property(const CSG_String &Name, double Value)
573{
574 return( Add_Property(Name, CSG_String::Format(SG_T("%f"), Value)) );
575}
576
577bool CSG_MetaData::Add_Property(const CSG_String &Name, int Value)
578{
579 return( Add_Property(Name, CSG_String::Format(SG_T("%d"), Value)) );
580}
581
583{
584 return( Add_Property(Name, CSG_String::Format(SG_T("%lld"), Value)) );
585}
586
587//---------------------------------------------------------
589{
590 for(int i=0; i<Get_Property_Count(); i++)
591 {
592 if( !Get_Property_Name(i).CmpNoCase(Name) )
593 {
594 return( Del_Property(i) );
595 }
596 }
597
598 return( false );
599}
600
602{
603 if( i >= 0 && i < Get_Property_Count() )
604 {
605 m_Prop_Names .Del(i);
606 m_Prop_Values.Del(i);
607
608 return( true );
609 }
610
611 return( false );
612}
613
614//---------------------------------------------------------
615bool CSG_MetaData::Set_Property(const CSG_String &Name, const CSG_String &Value, bool bAddIfNotExists)
616{
617 int Index = _Get_Property(Name);
618
619 if( Index >= 0 )
620 {
621 m_Prop_Values[Index] = Value;
622
623 return( true );
624 }
625 else if( bAddIfNotExists )
626 {
627 m_Prop_Names .Add(Name);
628 m_Prop_Values.Add(Value);
629
630 return( true );
631 }
632
633 return( false );
634}
635
636bool CSG_MetaData::Set_Property(const CSG_String &Name, double Value, bool bAddIfNotExists)
637{
638 return( Set_Property(Name, CSG_String::Format(SG_T("%f"), Value, bAddIfNotExists)) );
639}
640
641bool CSG_MetaData::Set_Property(const CSG_String &Name, int Value, bool bAddIfNotExists)
642{
643 return( Set_Property(Name, CSG_String::Format(SG_T("%d"), Value, bAddIfNotExists)) );
644}
645
646bool CSG_MetaData::Set_Property(const CSG_String &Name, sLong Value, bool bAddIfNotExists)
647{
648 return( Set_Property(Name, CSG_String::Format(SG_T("%lld"), Value, bAddIfNotExists)) );
649}
650
651//---------------------------------------------------------
652bool CSG_MetaData::Get_Property(const CSG_String &Name, CSG_String &Value) const
653{
654 const SG_Char *cString = Get_Property(Name);
655
656 if( cString )
657 {
658 Value = cString;
659
660 return( true );
661 }
662
663 return( false );
664}
665
666bool CSG_MetaData::Get_Property(const CSG_String &Name, double &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asDouble (Value) ); }
667bool CSG_MetaData::Get_Property(const CSG_String &Name, int &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asInt (Value) ); }
668bool CSG_MetaData::Get_Property(const CSG_String &Name, sLong &Value) const { CSG_String s; return( Get_Property(Name, s) && s.asLongLong(Value) ); }
669
670//---------------------------------------------------------
671bool CSG_MetaData::Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase) const
672{
673 CSG_String s;
674
675 return( Get_Property(Name, s) && (bNoCase ? !s.CmpNoCase(String) : !s.Cmp(String)) );
676}
677
678//---------------------------------------------------------
679int CSG_MetaData::_Get_Property(const CSG_String &Name) const
680{
681 for(int i=0; i<m_Prop_Names.Get_Count(); i++)
682 {
683 if( Name.CmpNoCase(m_Prop_Names[i]) == 0 )
684 {
685 return( i );
686 }
687 }
688
689 return( -1 );
690}
691
692
694// //
696
697//---------------------------------------------------------
699{
700 CSG_String s;
701
702 if( Flags == 0 )
703 {
704 for(int i=0; i<Get_Children_Count(); i++)
705 {
706 s += Get_Child(i)->Get_Name() + ":\t" + Get_Child(i)->Get_Content() + "\n";
707 }
708 }
709 else
710 {
711 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
712
713 XML.SetRoot(pRoot);
714
715 _Save(pRoot);
716
717 wxStringOutputStream Stream;
718
719 XML.Save(Stream);
720
721 s = &Stream.GetString();
722
723 if( Flags == 2 ) // remove <xml>
724 {
725 s = s.AfterFirst('\n');
726 }
727 }
728
729 return( s );
730}
731
732//---------------------------------------------------------
734{
735 CSG_Table t;
736
737 t.Add_Field("NAME" , SG_DATATYPE_String);
738 t.Add_Field("VALUE", SG_DATATYPE_String);
739
740 for(int i=0; i<Get_Children_Count(); i++)
741 {
743
744 r->Set_Value(0, Get_Child(i)->Get_Name());
745 r->Set_Value(1, Get_Child(i)->Get_Content());
746 }
747
748 return( t );
749}
750
751
753// //
755
756//---------------------------------------------------------
757bool CSG_MetaData::Assign(const CSG_MetaData &MetaData, bool bAddChildren)
758{
759 if( &MetaData != this )
760 {
761 Destroy();
762
763 Set_Name (MetaData.Get_Name ());
764 Set_Content(MetaData.Get_Content());
765
766 for(int i=0; i<MetaData.Get_Property_Count(); i++)
767 {
768 Add_Property(MetaData.Get_Property_Name(i), MetaData.Get_Property(i));
769 }
770
771 if( bAddChildren )
772 {
773 Add_Children(MetaData);
774 }
775 }
776
777 return( true );
778}
779
780
782// //
784
785//---------------------------------------------------------
786bool CSG_MetaData::Load(const CSG_String &File, const SG_Char *Extension)
787{
788 Destroy();
789
790 //-----------------------------------------------------
791 if( File.Find("http://") == 0 )
792 {
793 CSG_String s(File.Right(File.Length() - CSG_String("http://").Length()));
794
795 return( Load_HTTP(s.BeforeFirst('/'), s.AfterFirst('/')) );
796 }
797
798 //-----------------------------------------------------
799 CSG_String _File(SG_File_Make_Path("", File, Extension));
800
801 if( !SG_File_Exists(_File) )
802 {
803 return( false );
804 }
805
806 //-----------------------------------------------------
807 if( SG_File_Cmp_Extension(_File, "json") )
808 {
809 return( Load_JSON(_File) );
810 }
811
812 //-----------------------------------------------------
813 wxXmlDocument XML;
814
815 if( XML.Load(_File.c_str()) )
816 {
817 _Load(XML.GetRoot());
818
819 return( true );
820 }
821
822 //-----------------------------------------------------
823 return( false );
824}
825
826//---------------------------------------------------------
828{
829 Destroy();
830
831 wxXmlDocument XML;
832
833 if( File.is_Reading() && XML.Load(*((wxInputStream *)File.Get_Stream())) )
834 {
835 _Load(XML.GetRoot());
836
837 return( true );
838 }
839
840 return( false );
841}
842
843//---------------------------------------------------------
844void CSG_MetaData::_Load(wxXmlNode *pNode)
845{
846 m_Name = pNode->GetName ().wc_str();
847 m_Content = pNode->GetNodeContent().wc_str();
848
849 //-----------------------------------------------------
850 wxXmlAttribute *pProperty = pNode->GetAttributes();
851
852 while( pProperty )
853 {
854 Add_Property(&pProperty->GetName(), &pProperty->GetValue());
855
856 pProperty = pProperty->GetNext();
857 }
858
859 //-----------------------------------------------------
860 wxXmlNode *pChild = pNode->GetChildren();
861
862 while( pChild )
863 {
864 if( pChild->GetType() != wxXML_TEXT_NODE )
865 {
866 Add_Child()->_Load(pChild);
867 }
868
869 pChild = pChild->GetNext();
870 }
871}
872
873
875// //
877
878//---------------------------------------------------------
879bool CSG_MetaData::Save(const CSG_String &File, const SG_Char *Extension) const
880{
881 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
882
883 XML.SetRoot(pRoot);
884
885 _Save(pRoot);
886
887 if( XML.Save(SG_File_Make_Path("", File, Extension).c_str()) )
888 {
889 return( true );
890 }
891
892 return( false );
893}
894
895//---------------------------------------------------------
897{
898 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
899
900 XML.SetRoot(pRoot);
901
902 _Save(pRoot);
903
904 if( File.is_Writing() && XML.Save(*((wxOutputStream *)File.Get_Stream())) )
905 {
906 return( true );
907 }
908
909 return( false );
910}
911
912//---------------------------------------------------------
913void CSG_MetaData::_Save(wxXmlNode *pNode) const
914{
915 CSG_String Name(Get_Name()); if( Name.is_Empty() ) { Name = "NODE"; } else { Name.Replace(" ", "_"); } // name must not contain spaces!
916
917 pNode->SetName(Name.c_str());
918
919 pNode->SetContent(Get_Content().c_str());
920
921 if( Get_Content().Length() > 0 || (Get_Property_Count() == 0 && Get_Children_Count() == 0) )
922 {
923 wxXmlNode *pChild = new wxXmlNode(pNode, wxXML_TEXT_NODE, SG_T("TEXT"));
924
925 pChild->SetContent(Get_Content().c_str());
926 }
927
928 //-----------------------------------------------------
929 for(int i=0; i<Get_Property_Count(); i++)
930 {
931 pNode->AddAttribute(Get_Property_Name(i).c_str(), Get_Property(i));
932 }
933
934 //-----------------------------------------------------
935 for(int i=Get_Children_Count()-1; i>=0; i--)
936 {
937 Get_Child(i)->_Save(new wxXmlNode(pNode, wxXML_ELEMENT_NODE, Get_Child(i)->Get_Name().c_str()));
938 }
939}
940
941
943// //
945
946//---------------------------------------------------------
947bool CSG_MetaData::from_XML(const char *_XML, size_t Length, const char *Encoding)
948{
949 Destroy();
950
951 wxXmlDocument XML; wxMemoryInputStream Stream((const void *)_XML, Length);
952
953#if wxCHECK_VERSION(3, 3, 0)
954 if( XML.Load(Stream) )
955#else
956 if( XML.Load(Stream, Encoding) )
957#endif
958 {
959 _Load(XML.GetRoot());
960
961 return( true );
962 }
963
964 return( false );
965}
966
967//---------------------------------------------------------
969{
970 Destroy();
971
972 wxXmlDocument XML; wxMemoryInputStream Stream((const void *)_XML.b_str(), (size_t)_XML.Length());
973
974 if( XML.Load(Stream) )
975 {
976 _Load(XML.GetRoot());
977
978 return( true );
979 }
980
981 return( false );
982}
983
984//---------------------------------------------------------
986{
987 wxXmlDocument XML; wxXmlNode *pRoot = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, Get_Name().c_str());
988
989 XML.SetRoot(pRoot);
990
991 _Save(pRoot);
992
993 wxMemoryOutputStream Stream;
994
995 if( XML.Save(Stream) )
996 {
997 CSG_Array s(sizeof(char), Stream.GetSize());
998
999 Stream.CopyTo(s.Get_Array(), s.Get_Size());
1000
1001 _XML = (const char *)s.Get_Array();
1002
1003 return( true );
1004 }
1005
1006 return( false );
1007}
1008
1009
1011// //
1013
1014//---------------------------------------------------------
1015bool CSG_MetaData::Load_HTTP(const CSG_String &Server, const CSG_String &Path, const SG_Char *Username, const SG_Char *Password)
1016{
1017 Destroy();
1018
1019 //-----------------------------------------------------
1020 wxHTTP HTTP;
1021
1022 if( Username && *Username ) { HTTP.SetUser (Username); }
1023 if( Password && *Password ) { HTTP.SetPassword(Password); }
1024
1025 wxString s = Server.c_str();
1026
1027 if( s.Find("http://") == 0 )
1028 {
1029 s = s.Right(s.Length() - wxString("http://").Length());
1030 }
1031
1032 if( !HTTP.Connect(s) )
1033 {
1034 return( false );
1035 }
1036
1037 //-----------------------------------------------------
1038 s = Path.c_str();
1039
1040 if( s[0] != '/' )
1041 {
1042 s.Prepend("/");
1043 }
1044
1045 wxInputStream *pStream = HTTP.GetInputStream(s);
1046
1047 if( !pStream )
1048 {
1049 return( false );
1050 }
1051
1052 wxXmlDocument XML;
1053
1054 if( XML.Load(*pStream) )
1055 {
1056 _Load(XML.GetRoot());
1057
1058 delete(pStream);
1059
1060 return( true );
1061 }
1062
1063 delete(pStream);
1064
1065 return( false );
1066}
1067
1068
1070// //
1072
1073//---------------------------------------------------------
1075{
1076 CSG_File Stream; CSG_String JSON;
1077
1078 if( Stream.Open(File, SG_FILE_R, false) && Stream.Read(JSON, (size_t)Stream.Length()) > 0 )
1079 {
1080 return( from_JSON(JSON) );
1081 }
1082
1083 return( false );
1084}
1085
1086//---------------------------------------------------------
1088{
1089 return( false );
1090}
1091
1092//---------------------------------------------------------
1094{
1095 Destroy();
1096
1097 Set_Name("root");
1098
1099 CSG_MetaData *pNode = this; const SG_Char *pc = JSON.c_str();
1100
1101 while( *pc )
1102 {
1103 CSG_String Element;
1104
1105 for(bool bQuota=false; *pc; )
1106 {
1107 SG_Char c = *pc++;
1108
1109 if( c == '\0' || c == ',' )
1110 {
1111 break;
1112 }
1113 else if( c == '{' || c == '[' )
1114 {
1115 Element += c;
1116
1117 break;
1118 }
1119 else if( c == '}' || c == ']' )
1120 {
1121 if( Element.is_Empty() )
1122 {
1123 Element = c;
1124 }
1125 else
1126 {
1127 pc--;
1128 }
1129
1130 break;
1131 }
1132 else if( c == '\"' )
1133 {
1134 Element += c; bQuota = !bQuota;
1135 }
1136 else if( bQuota || (c != ' ' && c != '\n' && c != '\t') )
1137 {
1138 Element += c;
1139 }
1140 }
1141
1142 //-------------------------------------------------
1143 if( Element.is_Empty() )
1144 {
1145 // nop
1146 }
1147 else if( Element.Find('[') >= 0 ) // array begins
1148 {
1149 pNode = pNode->Add_Child(Element.AfterFirst('\"').BeforeFirst('\"'));
1150
1151 pNode->Add_Property("array", 1);
1152 }
1153 else if( Element.Find(']') >= 0 ) // array ends
1154 {
1155 if( pNode != this )
1156 {
1157 pNode = pNode->Get_Parent();
1158 }
1159 }
1160 else if( Element.Find('{') >= 0 ) // object begins
1161 {
1162 Element = Element.AfterFirst('\"').BeforeFirst('\"');
1163
1164 if( !Element.is_Empty() )
1165 {
1166 pNode = pNode->Add_Child(Element);
1167 }
1168 else if( pNode->Get_Property("array") )
1169 {
1170 pNode = pNode->Add_Child(CSG_String::Format("%d", pNode->Get_Children_Count()));
1171 }
1172 }
1173 else if( Element.Find('}') >= 0 ) // object ends
1174 {
1175 if( pNode != this )
1176 {
1177 pNode = pNode->Get_Parent();
1178 }
1179 }
1180 else
1181 {
1182 CSG_String key(Element.AfterFirst('\"').BeforeFirst('\"'));
1183 CSG_String val(Element.AfterFirst(':')); val.Trim();
1184
1185 if( val.Find('\"') == 0 )
1186 {
1187 val = val.AfterFirst('\"').BeforeFirst('\"');
1188 }
1189
1190 pNode->Add_Child(key, val);
1191 }
1192 }
1193
1194 return( true );
1195}
1196
1197//---------------------------------------------------------
1199{
1200 if( Get_Parent() )
1201 {
1202 JSON += "\"" + Get_Name() + "\": ";
1203 }
1204
1205 if( Get_Children_Count() )
1206 {
1207 JSON += "{";
1208
1209 for(int i=0; i<Get_Children_Count(); i++)
1210 {
1211 if( i > 0 )
1212 {
1213 JSON += ",";
1214 }
1215
1216 Get_Child(i)->to_JSON(JSON);
1217 }
1218
1219 JSON += "}";
1220 }
1221 else
1222 {
1223 JSON += " \"" + Get_Content() + "\"";
1224 }
1225
1226 return( true );
1227}
1228
1229
1231// //
1232// //
1233// //
1235
1236//---------------------------------------------------------
1238{
1239 m_pHTTP = NULL;
1240}
1241
1242//---------------------------------------------------------
1244{
1245 return( Destroy() );
1246}
1247
1248//---------------------------------------------------------
1249CSG_HTTP::CSG_HTTP(const CSG_String &Server, const SG_Char *Username, const SG_Char *Password)
1250{
1251 m_pHTTP = NULL;
1252
1253 Create(Server, Username, Password);
1254}
1255
1256//---------------------------------------------------------
1257bool CSG_HTTP::Create(const CSG_String &Server, const SG_Char *Username, const SG_Char *Password)
1258{
1259 Destroy();
1260
1261 m_pHTTP = new wxHTTP;
1262
1263 if( Username && *Username ) { m_pHTTP->SetUser (Username); }
1264 if( Password && *Password ) { m_pHTTP->SetPassword(Password); }
1265
1266 wxString Host = Server.c_str();
1267
1268 unsigned short Port = 80;
1269
1270 #define SERVER_TRIM(s, p) { wxString sp(p); sp += "://"; if( s.Find(p) == 0 ) { s = s.Right(s.Length() - sp.Length()); } }
1271
1272 SERVER_TRIM(Host, "https");
1273 SERVER_TRIM(Host, "http");
1274
1275 if( Host.Find(":") >= 0 )
1276 {
1277 long _Port;
1278
1279 if( Host.AfterLast(':').ToLong(&_Port) )
1280 {
1281 Port = (unsigned short)_Port;
1282 }
1283
1284 Host = Host.BeforeLast(':');
1285 }
1286
1287 if( !m_pHTTP->Connect(Host, Port) )
1288 {
1289 Destroy();
1290
1291 return( false );
1292 }
1293
1294 return( true );
1295}
1296
1297//---------------------------------------------------------
1299{
1300 Destroy();
1301}
1302
1303//---------------------------------------------------------
1305{
1306 if( m_pHTTP )
1307 {
1308 delete(m_pHTTP);
1309
1310 m_pHTTP = NULL;
1311 }
1312
1313 return( true );
1314}
1315
1316//---------------------------------------------------------
1318{
1319 return( m_pHTTP != NULL );
1320}
1321
1322//---------------------------------------------------------
1323wxInputStream * CSG_HTTP::_Request(const CSG_String &Request)
1324{
1325 if( !is_Connected() )
1326 {
1327 return( NULL );
1328 }
1329
1330 wxString s(Request.c_str());
1331
1332 if( s[0] != '/' )
1333 {
1334 s.Prepend("/");
1335 }
1336
1337 wxInputStream *pStream = m_pHTTP->GetInputStream(s);
1338
1339 if( pStream && !pStream->CanRead() )
1340 {
1341 delete(pStream);
1342
1343 return( NULL );
1344 }
1345
1346 return( pStream );
1347}
1348
1349//---------------------------------------------------------
1351{
1352 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1353
1354 wxXmlDocument XML;
1355
1356 if( !XML.Load(*pStream) )
1357 {
1358 delete(pStream);
1359
1360 return( false );
1361 }
1362
1363 Answer.Destroy(); Answer._Load(XML.GetRoot());
1364
1365 delete(pStream);
1366
1367 return( true );
1368}
1369
1370//---------------------------------------------------------
1372{
1373 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1374
1375// if( pStream->GetSize() == ((size_t)-1) )
1376// {
1377// delete(pStream);
1378//
1379// return( false );
1380// }
1381
1382 Answer.Clear();
1383
1384 while( pStream->CanRead() )
1385 {
1386 char Byte;
1387
1388 pStream->Read(&Byte, sizeof(Byte));
1389
1390 Answer += Byte;
1391 }
1392
1393 delete(pStream);
1394
1395 return( true );
1396}
1397
1398//---------------------------------------------------------
1400{
1401 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1402
1403 //if( pStream->GetSize() == ((size_t)-1) )
1404 //{
1405 // delete(pStream);
1406
1407 // return( false );
1408 //}
1409
1410 Answer.Clear();
1411
1412 while( pStream->CanRead() )
1413 {
1414 char Byte;
1415
1416 pStream->Read(&Byte, sizeof(Byte));
1417
1418 Answer += Byte;
1419 }
1420
1421 delete(pStream);
1422
1423 return( true );
1424}
1425
1426//---------------------------------------------------------
1428{
1429 wxInputStream *pStream = _Request(Request); if( !pStream ) { return( false ); }
1430
1431 wxFileOutputStream *pFile = new wxFileOutputStream(File);
1432
1433 if( !pFile )
1434 {
1435 delete(pStream);
1436
1437 return( false );
1438 }
1439
1440 pFile->Write(*pStream);
1441
1442 delete(pFile);
1443
1444 delete(pStream);
1445
1446 return( true );
1447}
1448
1449
1451// //
1452// //
1453// //
1455
1456//---------------------------------------------------------
1457#include <wx/protocol/ftp.h>
1458
1459//---------------------------------------------------------
1460bool SG_FTP_Download(const CSG_String &Target_Directory, const CSG_String &Source, const SG_Char *Username, const SG_Char *Password, unsigned short Port, bool bBinary, bool bVerbose)
1461{
1462 CSG_String _Source(Source); _Source.Trim();
1463
1464 if( _Source.Find("ftp://") == 0 )
1465 {
1466 _Source = _Source.Right(_Source.Length() - CSG_String("ftp://").Length());
1467 }
1468
1469 CSG_String ftpHost = _Source.BeforeFirst('/');
1470 CSG_String ftpDir = _Source.AfterFirst ('/').BeforeLast('/'); // ftpDir.Prepend("/");
1471 CSG_String ftpFile = _Source.AfterLast ('/');
1472
1473 //-----------------------------------------------------
1474 wxFTP ftp;
1475
1476 if( Username && *Username ) { ftp.SetUser (Username); }
1477 if( Password && *Password ) { ftp.SetPassword(Password); }
1478
1479 if( !ftp.Connect(ftpHost.c_str(), Port) )
1480 {
1481 if( bVerbose )
1482 {
1483 SG_UI_Msg_Add_Error(_TL("Couldn't connect"));
1484 }
1485
1486 return( false );
1487 }
1488
1489 //-----------------------------------------------------
1490 if( !ftpDir.is_Empty() && !ftp.ChDir(ftpDir.c_str()) )
1491 {
1492 if( bVerbose )
1493 {
1494 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't change to directory"), ftpDir.c_str()));
1495 }
1496
1497 return( false );
1498 }
1499
1500 if( ftp.GetFileSize(ftpFile.c_str()) == -1 )
1501 {
1502 if( bVerbose )
1503 {
1504 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file size"), ftpFile.c_str()));
1505 }
1506 }
1507
1508 //-----------------------------------------------------
1509 wxInputStream *pStream = ftp.GetInputStream(ftpFile.c_str());
1510
1511 if( !pStream )
1512 {
1513 if( bVerbose )
1514 {
1515 SG_UI_Msg_Add_Error(CSG_String::Format("%s [%s]", _TL("Couldn't get the file"), ftpFile.c_str()));
1516 }
1517
1518 return( false );
1519 }
1520
1521 //-----------------------------------------------------
1522 wxFileOutputStream *pFile = new wxFileOutputStream(SG_File_Make_Path(Target_Directory, ftpFile).c_str());
1523
1524 if( !pFile )
1525 {
1526 if( bVerbose )
1527 {
1528 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()));
1529 }
1530
1531 delete(pStream);
1532
1533 return( false );
1534 }
1535
1536 //-----------------------------------------------------
1537 pFile->Write(*pStream);
1538
1539 delete(pFile);
1540 delete(pStream);
1541
1542 return( true );
1543}
1544
1545
1547// //
1548// //
1549// //
1551
1552//---------------------------------------------------------
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)
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)
@ SG_DATATYPE_String
Definition api_core.h:1009
#define SG_Char
Definition api_core.h:536
#define _TL(s)
Definition api_core.h:1568
SAGA_API_DLL_EXPORT CSG_String SG_Get_String(double Value, int Precision=-99)
@ SG_FILE_R
Definition api_core.h:1114
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 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:1144
bool is_Writing(void) const
Definition api_core.h:1151
bool is_Reading(void) const
Definition api_core.h:1150
virtual ~CSG_HTTP(void)
bool is_Connected(void) const
class wxHTTP * m_pHTTP
Definition metadata.h:257
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:281
void Fmt_Content(const char *Format,...)
Definition metadata.cpp:510
bool to_XML(CSG_String &XML) const
Definition metadata.cpp:985
bool Cmp_Name(const CSG_String &String, bool bNoCase=true) const
Definition metadata.cpp:461
bool Save(const CSG_String &File, const SG_Char *Extension=NULL) const
Definition metadata.cpp:879
const CSG_String & Get_Name(void) const
Definition metadata.h:132
bool Create(void)
Definition metadata.cpp:73
bool Assign(const CSG_MetaData &MetaData, bool bAddChildren=true)
Definition metadata.cpp:757
bool Del_Children(int Depth=0, const SG_Char *Name=NULL)
Definition metadata.cpp:381
class CSG_Table Get_Table(int Flags=0) const
Definition metadata.cpp:733
int Get_Children_Count(void) const
Definition metadata.h:148
CSG_MetaData * Get_Child(int Index) const
Definition metadata.h:149
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:615
bool Cmp_Content(const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:548
bool Cmp_Property(const CSG_String &Name, const CSG_String &String, bool bNoCase=false) const
Definition metadata.cpp:671
bool Add_Children(const CSG_MetaData &MetaData)
Definition metadata.cpp:359
CSG_MetaData * Get_Parent(void) const
Definition metadata.h:145
CSG_MetaData(void)
Definition metadata.cpp:68
const CSG_String & Get_Property_Name(int Index) const
Definition metadata.h:180
virtual ~CSG_MetaData(void)
Definition metadata.cpp:134
const CSG_String & Get_Content(void) const
Definition metadata.h:133
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:181
bool Del_Child(int Index)
Definition metadata.cpp:321
void Set_Name(const CSG_String &Name)
Definition metadata.h:130
CSG_String asText(int Flags=0) const
Definition metadata.cpp:698
void Set_Content(const CSG_String &Content)
Definition metadata.h:140
bool from_JSON(const CSG_String &JSON)
CSG_MetaData * Add_Child(void)
Definition metadata.cpp:166
bool Load(const CSG_String &File, const SG_Char *Extension=NULL)
Definition metadata.cpp:786
void Destroy(void)
Definition metadata.cpp:140
bool Del_Property(const CSG_String &Name)
Definition metadata.cpp:588
bool from_XML(const char *XML, size_t Length, const char *Encoding="UTF-8")
Definition metadata.cpp:947
bool to_JSON(CSG_String &JSON) const
int Get_Property_Count(void) const
Definition metadata.h:179
CSG_MetaData * Ins_Child(int Position)
Definition metadata.cpp:207
bool Add_Property(const CSG_String &Name, const CSG_String &Value)
Definition metadata.cpp:559
size_t Length(void) const
CSG_String AfterFirst(char Character) const
const char * b_str(void) 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
CSG_String Right(size_t count) const
int asInt(void) const
const SG_Char * c_str(void) const
bool is_Empty(void) const
double asDouble(void) const
sLong asLongLong(void) const
int Get_Count(void) const
Definition api_core.h:714
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 SG_FTP_Download(const CSG_String &Target_Directory, const CSG_String &Source, const SG_Char *Username, const SG_Char *Password, unsigned short Port, bool bBinary, bool bVerbose)
#define SERVER_TRIM(s, p)