1 /*
2  * hunt-proton: AMQP Protocol library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.proton.codec.impl.DataImpl;
13 
14 import hunt.Exceptions;
15 import hunt.io.ByteBuffer;
16 import std.datetime.date;
17 import hunt.collection.List;
18 import hunt.collection.Map;
19 import hunt.proton.codec.impl.Element;
20 import hunt.proton.codec.Data;
21 import hunt.proton.amqp.Binary;
22 import hunt.io.BufferUtils;
23 import hunt.proton.codec.impl.DataDecoder;
24 import hunt.proton.codec.impl.ListElement;
25 import hunt.proton.codec.impl.MapElement;
26 import hunt.proton.codec.impl.ArrayElement;
27 import hunt.proton.codec.impl.NullElement;
28 import hunt.proton.codec.impl.BooleanElement;
29 import hunt.proton.codec.impl.IntegerElement;
30 import hunt.proton.codec.impl.UnsignedShortElement;
31 import hunt.proton.codec.impl.UnsignedIntegerElement;
32 import hunt.proton.codec.impl.DescribedTypeElement;
33 import hunt.proton.codec.impl.UnsignedByteElement;
34 import hunt.proton.codec.impl.ByteElement;
35 import hunt.proton.codec.impl.ShortElement;
36 import hunt.proton.codec.impl.CharElement;
37 import hunt.proton.codec.impl.UnsignedLongElement;
38 import hunt.proton.codec.impl.TimestampElement;
39 import hunt.proton.codec.impl.LongElement;
40 import hunt.proton.codec.impl.DoubleElement;
41 import hunt.proton.codec.impl.FloatElement;
42 import hunt.proton.codec.impl.Decimal32Element;
43 import hunt.proton.codec.impl.Decimal64Element;
44 import hunt.proton.codec.impl.Decimal128Element;
45 import hunt.proton.codec.impl.UUIDElement;
46 import hunt.proton.codec.impl.BinaryElement;
47 import hunt.proton.codec.impl.StringElement;
48 import hunt.proton.codec.impl.SymbolElement;
49 
50 import std.uuid;
51 
52 import hunt.proton.amqp.DescribedType;
53 import hunt.proton.amqp.Symbol;
54 import hunt.proton.amqp.Decimal32;
55 import hunt.proton.amqp.Decimal64;
56 import hunt.proton.amqp.Decimal128;
57 import hunt.proton.amqp.UnsignedLong;
58 import hunt.proton.amqp.UnsignedByte;
59 import hunt.proton.amqp.UnsignedInteger;
60 import hunt.proton.amqp.UnsignedShort;
61 
62 import std.conv : to;
63 import hunt.Integer;
64 import hunt.Long;
65 import hunt.Short;
66 import hunt.Long;
67 import hunt.Boolean;
68 import hunt.Byte;
69 import hunt.Float;
70 import hunt.Double;
71 import hunt.String;
72 import hunt.Char;
73 
74 import hunt.time.LocalDateTime;
75 import hunt.logging;
76 
77 alias Date = LocalDateTime;
78 
79 class DataImpl : Data
80 {
81 
82     private IElement _first;
83     private IElement _current;
84     private IElement _parent;
85 
86 
87     this()
88     {
89     }
90 
91     override
92     public void free()
93     {
94         _first = null;
95         _current = null;
96     }
97 
98     override
99     public void clear()
100     {
101         _first=null;
102         _current=null;
103         _parent=null;
104     }
105 
106     override
107     public long size()
108     {
109         return _first is null ? 0 : _first.size();
110     }
111 
112     override
113     public void rewind()
114     {
115         _current = null;
116         _parent = null;
117     }
118 
119     override
120     public DataType next()
121     {
122         IElement next = _current is null ? (_parent is null ? _first : _parent.child()) : _current.next();
123 
124         if(next !is null)
125         {
126             _current = next;
127         }
128         return next is null ? Data.DataType.NULL : next.getDataType();
129     }
130 
131     override
132     public DataType prev()
133     {
134         IElement prev = _current is null ? null : _current.prev();
135 
136         _current = prev;
137         return prev is null ? Data.DataType.NULL : prev.getDataType();
138     }
139 
140     override
141     public bool enter()
142     {
143         if(_current !is null && _current.canEnter())
144         {
145 
146             _parent = _current;
147             _current = null;
148             return true;
149         }
150         return false;
151     }
152 
153     override
154     public bool exit()
155     {
156         if(_parent !is null)
157         {
158             IElement parent = _parent;
159             _current = parent;
160             _parent = _current.parent();
161             return true;
162 
163         }
164         return false;
165     }
166 
167     override
168     public DataType type()
169     {
170         return _current is null ? Data.DataType.NULL : _current.getDataType();
171     }
172 
173     override
174     public long encodedSize()
175     {
176         int size = 0;
177         IElement elt = _first;
178         while(elt !is null)
179         {
180             size += elt.size();
181             elt = elt.next();
182         }
183         return size;
184     }
185 
186     override
187     public Binary encode()
188     {
189         byte[] data = new byte[cast(int)(encodedSize())];
190         ByteBuffer buf = BufferUtils.toBuffer(data);
191         encode(buf);
192         return new Binary(data);
193     }
194 
195     override
196     public long encode(ByteBuffer buf)
197     {
198         IElement elt = _first;
199         int size = 0;
200         while(elt !is null )
201         {
202             int eltSize = elt.size();
203             if(eltSize <= buf.remaining())
204             {
205                 size += elt.encode(buf);
206             }
207             else
208             {
209                 size+= eltSize;
210             }
211             elt = elt.next();
212         }
213         return size;
214     }
215 
216     override
217     public long decode(ByteBuffer buf)
218     {
219         return DataDecoder.decode(buf, this);
220     }
221 
222 
223     private void putElement(IElement element)
224     {
225         if(_first is null)
226         {
227             _first = element;
228         }
229         else
230         {
231             if(_current is null)
232             {
233                 if (_parent is null) {
234                     _first = _first.replaceWith(element);
235                     element = _first;
236                 } else {
237                     element = _parent.addChild(element);
238                 }
239             }
240             else
241             {
242                 if(_parent !is null)
243                 {
244                     element = _parent.checkChild(element);
245                 }
246                 _current.setNext(element);
247             }
248         }
249 
250         _current = element;
251     }
252 
253     override
254     public void putList()
255     {
256         putElement(cast(IElement)(new ListElement(_parent, _current)));
257     }
258 
259     override
260     public void putMap()
261     {
262         putElement(cast(IElement)(new MapElement(_parent, _current)));
263     }
264 
265     override
266     public void putArray(bool described, DataType type)
267     {
268         putElement(cast(IElement)(new ArrayElement(_parent,_current, described, type)));
269 
270     }
271 
272     override
273     public void putDescribed()
274     {
275         putElement(cast(IElement)(new DescribedTypeElement(cast(Element!(DescribedType))_parent, cast(Element!(DescribedType))_current)));
276     }
277 
278     override
279     public void putNull()
280     {
281         putElement(cast(IElement)(new NullElement(_parent, _current)));
282 
283     }
284 
285     override
286     public void putBoolean(bool b)
287     {
288         putElement(cast(IElement)(new BooleanElement(_parent,_current, b)));
289     }
290 
291     override
292     public void putUnsignedByte(UnsignedByte ub)
293     {
294         putElement(cast(IElement)(new UnsignedByteElement(_parent, _current, ub)));
295 
296     }
297 
298     override
299     public void putByte(byte b)
300     {
301         putElement(cast(IElement)(new ByteElement(_parent, _current, b)));
302     }
303 
304     override
305     public void putUnsignedShort(UnsignedShort us)
306     {
307         putElement(cast(IElement)(new UnsignedShortElement(_parent, _current, us)));
308 
309     }
310 
311     override
312     public void putShort(short s)
313     {
314         putElement(cast(IElement)(new ShortElement(cast(Element!Short)_parent, cast(Element!Short)_current, s)));
315     }
316 
317     override
318     public void putUnsignedInteger(UnsignedInteger ui)
319     {
320         putElement(cast(IElement)(new UnsignedIntegerElement(_parent, _current, ui)));
321     }
322 
323     override
324     public void putInt(int i)
325     {
326         putElement(cast(IElement)(new IntegerElement(_parent, _current, i)));
327     }
328 
329     override
330     public void putChar(int c)
331     {
332         putElement(cast(IElement)(new CharElement(_parent, _current, c)));
333     }
334 
335     override
336     public void putUnsignedLong(UnsignedLong ul)
337     {
338         putElement(cast(IElement)(new UnsignedLongElement(_parent, _current, ul)));
339     }
340 
341     override
342     public void putLong(long l)
343     {
344         putElement(cast(IElement)(new LongElement(_parent, _current, l)));
345     }
346 
347     override
348     public void putTimestamp(Date t)
349     {
350         putElement(cast(IElement)(new TimestampElement(_parent,_current,t)));
351     }
352 
353     override
354     public void putFloat(float f)
355     {
356         putElement(cast(IElement)(new FloatElement(_parent,_current,f)));
357     }
358 
359     override
360     public void putDouble(double d)
361     {
362         putElement(cast(IElement)(new DoubleElement(_parent,_current,d)));
363     }
364 
365     override
366     public void putDecimal32(Decimal32 d)
367     {
368         putElement(cast(IElement)(new Decimal32Element(cast(Element!Decimal32)_parent,cast(Element!Decimal32)_current,d)));
369     }
370 
371     override
372     public void putDecimal64(Decimal64 d)
373     {
374         putElement(cast(IElement)(new Decimal64Element(cast(Element!Decimal64)_parent,cast(Element!Decimal64)_current,d)));
375     }
376 
377     override
378     public void putDecimal128(Decimal128 d)
379     {
380        // putElement(cast(IElement)(new Decimal128Element(_parent,_current,d)));
381     }
382 
383     override
384     public void putUUID(UUID u)
385     {
386         //putElement(new UUIDElement(_parent,_current,u));
387     }
388 
389     override
390     public void putBinary(Binary bytes)
391     {
392         putElement(cast(IElement)(new BinaryElement(_parent, _current, bytes)));
393     }
394 
395     override
396     public void putBinary(byte[] bytes)
397     {
398         putBinary(new Binary(bytes));
399     }
400 
401     override
402     public void putString(string str)
403     {
404         putElement(cast(IElement)(new StringElement(_parent,_current,str)));
405     }
406 
407     override
408     public void putSymbol(Symbol symbol)
409     {
410         putElement(cast(IElement)(new SymbolElement(_parent,_current,symbol)));
411     }
412 
413     override
414     public void putObject(Object o)
415     {
416         if(o is null)
417         {
418             putNull();
419             return;
420         }
421 
422         Boolean toBool = cast(Boolean)o;
423         if (toBool !is null)
424         {
425             putBoolean(toBool.booleanValue);
426             return;
427         }
428 
429         UnsignedByte toUbyte = cast(UnsignedByte)o;
430         if (toUbyte !is null)
431         {
432             putUnsignedByte(toUbyte);
433             return;
434         }
435 
436         Byte toByte = cast(Byte)o;
437         if (toByte !is null)
438         {
439             putByte(toByte.byteValue);
440             return;
441         }
442 
443         UnsignedShort toUshort = cast(UnsignedShort)o;
444         if (toUshort !is null)
445         {
446             putUnsignedShort(toUshort);
447             return;
448         }
449 
450         Short toShort = cast(Short)o;
451         if (toShort !is null)
452         {
453             putShort(toShort.shortValue);
454             return;
455         }
456 
457         UnsignedInteger toUint = cast(UnsignedInteger)o;
458         if (toUint !is null)
459         {
460             putUnsignedInteger(toUint);
461             return;
462         }
463 
464         Integer toInt = cast(Integer)o;
465         if (toInt !is null)
466         {
467             putInt(toInt.intValue);
468             return;
469         }
470 
471         Char toChar = cast(Char)o;
472         if (toChar !is null)
473         {
474             putChar(toChar.charValue);
475             return;
476         }
477 
478         UnsignedLong toUlong= cast(UnsignedLong)o;
479         if (toUlong !is null)
480         {
481             putUnsignedLong(toUlong);
482             return;
483         }
484 
485         Long toLong = cast(Long)o;
486         if (toLong !is null)
487         {
488             putLong(toLong.longValue);
489             return;
490         }
491 
492         Date toDate = cast(Date)o;
493         if (toDate !is null)
494         {
495             putTimestamp(toDate);
496             return;
497         }
498 
499         Float toFloat = cast(Float)o;
500         if (toFloat !is null)
501         {
502             putFloat(toFloat.floatValue);
503             return;
504         }
505 
506         Double toDouble = cast(Double)o;
507         if (toDouble !is null)
508         {
509             putDouble(toDouble.longValue);
510             return;
511         }
512 
513         Decimal32 toDem32 = cast(Decimal32)o;
514         if (toDem32 !is null)
515         {
516             putDecimal32(toDem32);
517             return;
518         }
519 
520         Decimal64 toDem64 = cast(Decimal64)o;
521         if (toDem64 !is null)
522         {
523             putDecimal64(toDem64);
524             return;
525         }
526 
527         Decimal128 toDem128 = cast(Decimal128)o;
528         if (toDem128 !is null)
529         {
530             putDecimal128(toDem128);
531             return;
532         }
533 
534         //UUID toUuid = cast(UUID)o;
535         //if (toUuid !is null)
536         //{
537         //    putUUID(toUuid);
538         //    return;
539         //}
540 
541         Binary toBinary = cast(Binary)o;
542         if (toBinary !is null)
543         {
544             putBinary(toBinary);
545             return;
546         }
547 
548         String toString = cast(String)o;
549         if (toString !is null)
550         {
551             putString(cast(string)toString.getBytes);
552             return;
553         }
554 
555         Symbol toSymbol = cast(Symbol)o;
556         if(toSymbol !is null)
557         {
558             putSymbol(toSymbol);
559             return;
560         }
561 
562 
563         DescribedType toDescr = cast(DescribedType)o;
564         if (toDescr !is null)
565         {
566             putDescribedType(toDescr);
567             return;
568         }
569 
570         //Symbol[] toSymbolArry = cast(Symbol[])o;
571         //if (toSymbolArry !is null)
572         //{
573         //    putArray(false, Data.DataType.SYMBOL);
574         //    enter();
575         //    foreach(sym ; toSymbolArry)
576         //    {
577         //        putSymbol(sym);
578         //    }
579         //    exit();
580         //    return;
581         //}
582 
583         List!Object toList = cast(List!Object)o;
584         if(toList !is null)
585         {
586             putJavaList(toList);
587             return;
588         }
589 
590         Map!(Object,Object) toMap= cast(Map!(Object,Object))o;
591         if(toMap !is null)
592         {
593             putJavaMap(toMap);
594             return;
595         }
596 
597 
598 
599         //else if(o instanceof Object[])
600         //{
601         //    throw new IllegalArgumentException("Unsupported array type");
602         //}
603         //else if(o instanceof List)
604         //{
605         //    putJavaList((List)o);
606         //}
607         //else if(o instanceof Map)
608         //{
609         //    putJavaMap((Map)o);
610         //}
611         //else
612         throw new IllegalArgumentException("Unknown type " ~ typeid(o).stringof);
613 
614     }
615 
616     override
617     public void putJavaMap(Map!(Object, Object) map)
618     {
619         putMap();
620         enter();
621         foreach(MapEntry!(Object, Object) entry ; map)
622         {
623             putObject(entry.getKey());
624             putObject(entry.getValue());
625         }
626         exit();
627     }
628 
629     override
630     public void putJavaList(List!(Object) list)
631     {
632         putList();
633         enter();
634         foreach(Object o ; list)
635         {
636             putObject(o);
637         }
638         exit();
639     }
640 
641     override
642     public void putDescribedType(DescribedType dt)
643     {
644         putElement(cast(IElement)(new DescribedTypeElement(_parent,_current)));
645         enter();
646         putObject(dt.getDescriptor());
647         putObject(dt.getDescribed());
648         exit();
649     }
650 
651     override
652     public long getList()
653     {
654         ListElement toListEle = cast(ListElement)_current;
655         if( toListEle !is null)
656         {
657             return toListEle.count();
658         }
659         throw new IllegalStateException("Current value not list");
660     }
661 
662     override
663     public long getMap()
664     {
665         MapElement toMapEle = cast(MapElement)_current;
666         if(toMapEle !is null)
667         {
668             return toMapEle.count();
669         }
670         throw new IllegalStateException("Current value not map");
671     }
672 
673     override
674     public long getArray()
675     {
676         ArrayElement toArrayEle = cast(ArrayElement)_current;
677         if(toArrayEle !is null)
678         {
679             return toArrayEle.count();
680         }
681         throw new IllegalStateException("Current value not array");
682     }
683 
684     override
685     public bool isArrayDescribed()
686     {
687         ArrayElement toArrayEle = cast(ArrayElement)_current;
688         if(toArrayEle !is null)
689         {
690             return toArrayEle.isDescribed();
691         }
692         throw new IllegalStateException("Current value not array");
693     }
694 
695     override
696     public DataType getArrayType()
697     {
698         ArrayElement toArrayEle = cast(ArrayElement)_current;
699         if(toArrayEle !is null)
700         {
701             return toArrayEle.getArrayDataType();
702         }
703         throw new IllegalStateException("Current value not array");
704     }
705 
706     override
707     public bool isDescribed()
708     {
709         return _current !is null && _current.getDataType() == DataType.DESCRIBED;
710     }
711 
712     override
713     public bool isNull()
714     {
715         return _current !is null && _current.getDataType() == DataType.NULL;
716     }
717 
718     override
719     public Boolean getBoolean()
720     {
721         BooleanElement toBoolEle = cast(BooleanElement)_current;
722         if(toBoolEle !is null)
723         {
724             return cast(Boolean)toBoolEle.getValue();
725         }
726         throw new IllegalStateException("Current value not bool");
727     }
728 
729     override
730     public UnsignedByte getUnsignedByte()
731     {
732         UnsignedByteElement toUbyte = cast(UnsignedByteElement)_current;
733         if(toUbyte !is null)
734         {
735             return cast(UnsignedByte)toUbyte.getValue();
736         }
737         throw new IllegalStateException("Current value not unsigned byte");
738     }
739 
740     override
741     public Byte getByte()
742     {
743         ByteElement toByteEle = cast(ByteElement)_current;
744         if(toByteEle !is null)
745         {
746             return cast(Byte)toByteEle.getValue();
747         }
748         throw new IllegalStateException("Current value not byte");
749     }
750 
751     override
752     public UnsignedShort getUnsignedShort()
753     {
754         UnsignedShortElement toUShortEle = cast(UnsignedShortElement)_current;
755         if(toUShortEle !is null)
756         {
757             return cast(UnsignedShort)toUShortEle.getValue();
758         }
759         throw new IllegalStateException("Current value not unsigned short");
760     }
761 
762     override
763     public Short getShort()
764     {
765         ShortElement toShortEle = cast(ShortElement)_current;
766         if(toShortEle !is null)
767         {
768             return cast(Short)toShortEle.getValue();
769         }
770         throw new IllegalStateException("Current value not short");
771     }
772 
773     override
774     public UnsignedInteger getUnsignedInteger()
775     {
776         UnsignedIntegerElement toUIntEle = cast(UnsignedIntegerElement)_current;
777         if(toUIntEle !is null)
778         {
779             return cast(UnsignedInteger)toUIntEle.getValue();
780         }
781         throw new IllegalStateException("Current value not unsigned integer");
782     }
783 
784     override
785     public Integer getInt()
786     {
787         IntegerElement toIntEle = cast (IntegerElement)_current;
788         if(toIntEle !is null)
789         {
790             return cast(Integer)toIntEle.getValue();
791         }
792         throw new IllegalStateException("Current value not integer");
793     }
794 
795     override
796     public Integer getChar()
797     {
798         CharElement toCharEle = cast(CharElement)_current;
799         if(toCharEle !is null)
800         {
801             return cast(Integer)toCharEle.getValue();
802         }
803         throw new IllegalStateException("Current value not char");
804     }
805 
806     override
807     public UnsignedLong getUnsignedLong()
808     {
809         UnsignedLongElement toUnLongEle = cast(UnsignedLongElement)_current;
810         if(toUnLongEle !is null)
811         {
812             return cast(UnsignedLong)toUnLongEle.getValue();
813         }
814         throw new IllegalStateException("Current value not unsigned long");
815     }
816 
817     override
818     public Long getLong()
819     {
820         LongElement toLongEle = cast(LongElement)_current;
821         if(toLongEle !is null)
822         {
823             return cast(Long)toLongEle.getValue();
824         }
825         throw new IllegalStateException("Current value not long");
826     }
827 
828     override
829     public Date getTimestamp()
830     {
831         TimestampElement toTimeEle = cast(TimestampElement)_current;
832         if(toTimeEle !is null)
833         {
834             return cast(Date)toTimeEle.getValue();
835         }
836         throw new IllegalStateException("Current value not timestamp");
837     }
838 
839     override
840     public Float getFloat()
841     {
842         FloatElement toFloatEle = cast(FloatElement)_current;
843         if(toFloatEle !is null)
844         {
845             return cast(Float)toFloatEle.getValue();
846         }
847         throw new IllegalStateException("Current value not float");
848     }
849 
850     override
851     public Double getDouble()
852     {
853         DoubleElement toDoubelEle = cast(DoubleElement)_current;
854         if(toDoubelEle !is null)
855         {
856             return cast(Double)toDoubelEle.getValue();
857         }
858         throw new IllegalStateException("Current value not double");
859     }
860 
861     override
862     public Decimal32 getDecimal32()
863     {
864         Decimal32Element toDec32 = cast(Decimal32Element)_current;
865         if(toDec32 !is null)
866         {
867             return toDec32.getValue();
868         }
869         throw new IllegalStateException("Current value not decimal32");
870     }
871 
872     override
873     public Decimal64 getDecimal64()
874     {
875         Decimal64Element toDec64 = cast(Decimal64Element)_current;
876         if(toDec64 !is null)
877         {
878             return toDec64.getValue();
879         }
880         throw new IllegalStateException("Current value not decimal32");
881     }
882 
883     override
884     public Decimal128 getDecimal128()
885     {
886         //Decimal128Element toDec128 = cast(Decimal128Element)_current;
887         //if(toDec128 !is null)
888         //{
889         //    return toDec128.getValue();
890         //}
891         //throw new IllegalStateException("Current value not decimal32");
892         return null;
893     }
894 
895     override
896     public UUID getUUID()
897     {
898         implementationMissing(false);
899         UUID tmp;
900         return tmp;
901         //UUIDElement toUuidEle = cast(UUIDElement)_current;
902         //if(toUuidEle !is null)
903         //{
904         //    return toUuidEle.getValue();
905         //}
906         //throw new IllegalStateException("Current value not uuid");
907     }
908 
909     override
910     public Binary getBinary()
911     {
912         BinaryElement toBinary = cast(BinaryElement)_current;
913         if(toBinary !is null)
914         {
915             return cast(Binary)(toBinary.getValue());
916         }
917         throw new IllegalStateException("Current value not binary");
918     }
919 
920     override
921     public String getString()
922     {
923         StringElement toStringEle = cast(StringElement)_current;
924         if (toStringEle !is null)
925         {
926             return cast(String)(toStringEle.getValue());
927         }
928         throw new IllegalStateException("Current value not string");
929     }
930 
931     override
932     public Symbol getSymbol()
933     {
934         SymbolElement toSymbolEle = cast(SymbolElement)_current;
935         if(toSymbolEle !is null)
936         {
937             return cast(Symbol)(toSymbolEle.getValue());
938         }
939         throw new IllegalStateException("Current value not symbol");
940     }
941 
942     override
943     public Object getObject()
944     {
945       //  return _current is null ? null : _current.getValue();
946         return _current is null ? null : cast(Object)_current;
947     }
948 
949     override
950     public Map!(Object, Object) getJavaMap()
951     {
952         MapElement toMapEle = cast(MapElement)_current;
953         if(toMapEle !is null)
954         {
955             return cast(Map!(Object, Object))(toMapEle.getValue());
956         }
957         throw new IllegalStateException("Current value not map");
958     }
959 
960     override
961     public List!Object getJavaList()
962     {
963         ListElement toListEle = cast(ListElement)_current;
964         if(toListEle !is null)
965         {
966             return cast(List!Object)(toListEle.getValue());
967         }
968         throw new IllegalStateException("Current value not list");
969     }
970 
971     override
972     public List!Object getJavaArray()
973     {
974         ArrayElement toArrayEle = cast(ArrayElement)_current;
975         if(toArrayEle !is null)
976         {
977             return cast(List!Object)(toArrayEle.getValue());
978         }
979         throw new IllegalStateException("Current value not array");
980     }
981 
982     override
983     public DescribedType getDescribedType()
984     {
985         DescribedTypeElement toDescEle = cast(DescribedTypeElement)_current;
986         if(toDescEle !is null)
987         {
988             return cast(DescribedType)(toDescEle.getValue());
989         }
990         throw new IllegalStateException("Current value not described type");
991     }
992 
993     override
994     public string format()
995     {
996         //string sb;
997         //Element el = _first;
998         //bool first = true;
999         //while (el != null) {
1000         //    if (first) {
1001         //        first = false;
1002         //    } else {
1003         //        sb ~= ", ";
1004         //    }
1005         //    el.render(sb);
1006         //    el = el.next();
1007         //}
1008 
1009         return "";
1010     }
1011 
1012     //private void render(string sb, Element el)
1013     //{
1014     //    if (el is null) return;
1015     //    sb.append("    ").append(el).append("\n");
1016     //    sb = sb ~ "    " ~ "\n";
1017     //    if (el.canEnter()) {
1018     //        render(sb, el.child());
1019     //    }
1020     //    render(sb, el.next());
1021     //}
1022 
1023     //override
1024     //public String toString()
1025     //{
1026     //    StringBuilder sb = new StringBuilder();
1027     //    render(sb, _first);
1028     //    return String.format("Data[current=%h, parent=%h]{%n%s}",
1029     //                         System.identityHashCode(_current),
1030     //                         System.identityHashCode(_parent),
1031     //                         sb);
1032     //}
1033 }