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.EncoderImpl;
13 
14 import hunt.proton.codec.AMQPType;
15 import hunt.proton.codec.DecoderImpl;
16 import hunt.proton.codec.ByteBufferEncoder;
17 import hunt.proton.codec.WritableBuffer;
18 import hunt.proton.codec.EncodingCodes;
19 
20 import hunt.proton.amqp.Binary;
21 import hunt.proton.amqp.Decimal128;
22 import hunt.proton.amqp.Decimal32;
23 import hunt.proton.amqp.Decimal64;
24 import hunt.proton.amqp.DescribedType;
25 import hunt.proton.amqp.Symbol;
26 import hunt.proton.amqp.UnsignedByte;
27 import hunt.proton.amqp.UnsignedInteger;
28 import hunt.proton.amqp.UnsignedLong;
29 import hunt.proton.amqp.UnsignedShort;
30 
31 import hunt.proton.codec.NullType;
32 import hunt.proton.codec.BooleanType;
33 import hunt.proton.codec.ByteType;
34 import hunt.proton.codec.UnsignedByteType;
35 import hunt.proton.codec.IntegerType;
36 import hunt.proton.codec.ShortType;
37 import hunt.proton.codec.UnsignedIntegerType;
38 import hunt.proton.codec.LongType;
39 import hunt.proton.codec.UnsignedLongType;
40 import hunt.proton.codec.UnsignedShortType;
41 import hunt.proton.codec.BigIntegerType;
42 import hunt.proton.codec.CharacterType;
43 import hunt.proton.codec.FloatType;
44 import hunt.proton.codec.DoubleType;
45 import hunt.proton.codec.TimestampType;
46 import hunt.proton.codec.UUIDType;
47 import hunt.proton.codec.Decimal32Type;
48 import hunt.proton.codec.Decimal64Type;
49 import hunt.proton.codec.Decimal128Type;
50 import hunt.proton.codec.BinaryType;
51 import hunt.proton.codec.SymbolType;
52 import hunt.proton.codec.StringType;
53 import hunt.proton.codec.ListType;
54 import hunt.proton.codec.MapType;
55 import hunt.proton.codec.ArrayType;
56 import hunt.proton.codec.BigIntegerType;
57 import hunt.proton.codec.NullType;
58 import hunt.proton.codec.SymbolMapType;
59 import hunt.proton.codec.DynamicDescribedType;
60 import hunt.proton.codec.ObjectMapType;
61 import hunt.proton.codec.transport.AttachType;
62 import hunt.proton.codec.security.SaslInitType;
63 import hunt.proton.codec.security.SaslOutcomeType;
64 import hunt.proton.codec.security.SaslInitType;
65 import hunt.proton.codec.messaging.TargetType;
66 import hunt.proton.codec.messaging.HeaderType;
67 import hunt.proton.codec.messaging.SourceType;
68 import hunt.proton.codec.transport.TransferType;
69 import hunt.proton.codec.transport.DetachType;
70 import hunt.proton.codec.transport.DispositionType;
71 import hunt.proton.codec.transaction.DischargeType;
72 import hunt.proton.codec.transport.ErrorConditionType;
73 import hunt.proton.codec.transaction.TransactionalStateType;
74 import hunt.proton.codec.transport.BeginType;
75 import hunt.proton.codec.transport.FlowType;
76 import hunt.proton.codec.messaging.RejectedType;
77 import hunt.proton.codec.messaging.ModifiedType;
78 import hunt.proton.codec.transport.OpenType;
79 import hunt.proton.codec.messaging.ReceivedType;
80 import hunt.proton.codec.messaging.PropertiesType;
81 
82 import hunt.io.ByteBuffer;
83 import hunt.time.LocalDateTime;
84 import hunt.collection.List;
85 import hunt.collection.Map;
86 import hunt.Exceptions;
87 import hunt.String;
88 
89 import std.uuid;
90 import hunt.logging.ConsoleLogger;
91 import hunt.Byte;
92 import hunt.collection.AbstractList;
93 import hunt.collection.ArrayList;
94 import hunt.collection.HashMap;
95 import hunt.Short;
96 import hunt.Long;
97 import hunt.Integer;
98 import hunt.Float;
99 import hunt.Double;
100 import hunt.Char;
101 import hunt.Boolean;
102 import hunt.Object;
103 
104 
105 class EncoderImpl : ByteBufferEncoder
106 {
107     private static byte DESCRIBED_TYPE_OP = cast(byte)0;
108 
109     private WritableBuffer _buffer;
110 
111     private DecoderImpl _decoder;
112     private Map!(TypeInfo, IAMQPType) _typeRegistry; // = new HashMap!(TypeInfo, AMQPType!Object)(); IAMQPType
113     private Map!(Object, IAMQPType) _describedDescriptorRegistry ;//= new HashMap!(Object, AMQPType!Object)();
114     private Map!(TypeInfo, IAMQPType)  _describedTypesClassRegistry;// = new HashMap!(TypeInfo, AMQPType!Object)();
115 
116     private NullType              _nullType;
117     private BooleanType           _boolType;
118     private ByteType              _byteType;
119     private UnsignedByteType      _unsignedByteType;
120     private ShortType             _shortType;
121     private UnsignedShortType     _unsignedShortType;
122     private IntegerType           _integerType;
123     private UnsignedIntegerType   _unsignedIntegerType;
124     private LongType              _longType;
125     private UnsignedLongType      _unsignedLongType;
126    // private BigIntegerType        _bigIntegerType;
127 
128     private CharacterType         _characterType;
129     private FloatType             _floatType;
130     private DoubleType            _doubleType;
131     private TimestampType         _timestampType;
132  //   private UUIDType              _uuidType;
133 
134     //private Decimal32Type         _decimal32Type;
135     //private Decimal64Type         _decimal64Type;
136     //private Decimal128Type        _decimal128Type;
137 
138     private BinaryType            _binaryType;
139     private SymbolType            _symbolType;
140     private StringType            _stringType;
141 
142     private ListType              _listType;
143     private MapType               _mapType;
144     private SymbolMapType         _symbolMapType;
145     private ObjectMapType         _objectMapType;
146  //   private ArrayType             _arrayType;//
147 
148     this(DecoderImpl decoder)
149     {
150 
151         _typeRegistry = new HashMap!(TypeInfo, IAMQPType);
152         _describedDescriptorRegistry = new HashMap!(Object, IAMQPType);
153         _describedTypesClassRegistry = new HashMap!(TypeInfo, IAMQPType) ;
154         _decoder                = decoder;
155         _nullType               = new NullType(this, decoder);
156         _boolType               = new BooleanType(this, decoder);
157         _byteType               = new ByteType(this, decoder);
158         _unsignedByteType       = new UnsignedByteType(this, decoder);
159         _shortType              = new ShortType(this, decoder);
160         _unsignedShortType      = new UnsignedShortType(this, decoder);
161         _integerType            = new IntegerType(this, decoder);
162         _unsignedIntegerType    = new UnsignedIntegerType(this, decoder);
163         _longType               = new LongType(this, decoder);
164         _unsignedLongType       = new UnsignedLongType(this, decoder);
165        // _bigIntegerType         = new BigIntegerType(this, decoder);
166 
167         _characterType          = new CharacterType(this, decoder);
168         _floatType              = new FloatType(this, decoder);
169         _doubleType             = new DoubleType(this, decoder);
170         _timestampType          = new TimestampType(this, decoder);
171         //_uuidType               = new UUIDType(this, decoder);
172         //
173         //_decimal32Type          = new Decimal32Type(this, decoder);
174         //_decimal64Type          = new Decimal64Type(this, decoder);
175         //_decimal128Type         = new Decimal128Type(this, decoder);
176 
177 
178         _binaryType             = new BinaryType(this, decoder);
179         _symbolType             = new SymbolType(this, decoder);
180         _stringType             = new StringType(this, decoder);
181 
182        _listType               = new ListType(this, decoder);
183         _mapType                = new MapType(this, decoder);
184         _symbolMapType          = new SymbolMapType(this,decoder);
185         _objectMapType          = new ObjectMapType(this,decoder);
186         //
187         //_arrayType              = new ArrayType(this,
188         //                                        decoder,
189         //                                        _boolType,
190         //                                        _byteType,
191         //                                        _shortType,
192         //                                        _integerType,
193         //                                        _longType,
194         //                                        _floatType,
195         //                                        _doubleType,
196         //                                        _characterType);
197     }
198 
199     override
200     public void setByteBuffer(ByteBuffer buf)
201     {
202         _buffer = new ByteBufferWrapper(buf);
203     }
204 
205     public void setByteBuffer(WritableBuffer buf)
206     {
207         _buffer = buf;
208     }
209 
210     public WritableBuffer getBuffer()
211     {
212         return _buffer;
213     }
214 
215     public DecoderImpl getDecoder()
216     {
217         return _decoder;
218     }
219 
220     public IAMQPType getType(Object element)
221     {
222         //return cast(IAMQPType)element;
223        return getTypeFromClass((element is null? typeid(Null) : typeid(element)), element);
224     }
225 
226     public IAMQPType getTypeFromClass(TypeInfo clazz)
227     {
228         //implementationMissing(false);
229         //return null;
230         return getTypeFromClass(clazz, null);
231     }
232 
233 
234     private IAMQPType getTypeFromClass(TypeInfo clazz, Object instance)
235     {
236         IAMQPType amqpType = _typeRegistry.get(clazz);
237        // logInfof("---------------%s",clazz.toString);
238         if(amqpType is null)
239         {
240             amqpType = deduceTypeFromClass(clazz, instance);
241         }
242 
243         return amqpType;
244     }
245     //
246     private IAMQPType deduceTypeFromClass(TypeInfo clazz, Object instance) {
247         IAMQPType amqpType = null;
248 
249         version(HUNT_AMQP_DEBUG) tracef("deducing %s", clazz);
250 
251         //if(clazz.isArray())
252         //{
253         //    amqpType = _arrayType;
254         //}
255         //else
256         //{
257             if(typeid(EmptyList!(Object)) == clazz) {
258                 amqpType = _listType;
259             } else  if (typeid(SaslOutcomeWrapper) == clazz)
260             {
261                 amqpType = _listType;
262             }
263             else if (typeid(SaslInitWrapper) == clazz)//TargetWrapper
264             {
265                 amqpType = _listType;
266             }
267             else if (typeid(TargetWrapper) == clazz)//HeaderWrapper
268             {
269                 amqpType = _listType;
270             }
271             else if (typeid(HeaderWrapper) == clazz)//RejectedWrapper
272             {
273                 amqpType = _listType;
274             }
275             else if (typeid(SourceWrapper) == clazz)//RejectedWrapper
276             {
277                 amqpType = _listType;
278             }
279             else if (typeid(TransferWrapper) == clazz)//RejectedWrapper
280             {
281                 amqpType = _listType;
282             }
283             else if (typeid(AttachWrapper) == clazz)//RejectedWrapper
284             {
285                 amqpType = _listType;
286             }
287             else if (typeid(DetachWrapper) == clazz)//RejectedWrapper
288             {
289                 amqpType = _listType;
290             }
291             else if (typeid(DispositionWrapper) == clazz)//RejectedWrapper
292             {
293                 amqpType = _listType;
294             }
295             else if (typeid(DischargeWrapper) == clazz)//RejectedWrapper
296             {
297                 amqpType = _listType;
298             }
299             else if (typeid(ErrorConditionWrapper) == clazz)//RejectedWrapper
300             {
301                 amqpType = _listType;
302             }
303             else if (typeid(TransactionalStateWrapper) == clazz)//RejectedWrapper
304             {
305                 amqpType = _listType;
306             }
307             else if (typeid(BeginWrapper) == clazz)//RejectedWrapper//DischargeWrapper//ErrorConditionWrapper//TransactionalStateWrapper
308             {
309                 amqpType = _listType;
310             }
311             else if (typeid(FlowWrapper) == clazz)//RejectedWrapper//SourceWrapper//TransferWrapper//AttachWrapper//DetachWrapper//DispositionWrapper//BeginWrapper
312             {
313                 amqpType = _listType;
314             }
315             else if (typeid(RejectedWrapper) == clazz)//RejectedWrapper//FlowWrapper
316             {
317                 amqpType = _listType;
318             }
319             else if (typeid(ModifiedWrapper) == clazz)//OpenWrapper
320             {
321                 amqpType = _listType;
322             }
323             else if (typeid(OpenWrapper) == clazz)//OpenWrapper
324             {
325                 amqpType = _listType;
326             }
327             else if (typeid(ReceivedWrapper) == clazz)//PropertiesWrapper
328             {
329                 amqpType = _listType;
330             }
331             else if (typeid(PropertiesWrapper) == clazz)//PropertiesWrapper
332             {
333                 amqpType = _listType;
334             }
335             else if (typeid(ArrayList!Object) == clazz)
336             {
337                 amqpType = _listType;
338             }
339             else if(typeid(List!Object) == clazz)
340             {
341                 amqpType = _listType;
342             }
343             else if(typeid(Map!(String,Object)) == clazz)
344             {
345                 amqpType = _mapType;
346             }
347             else if(typeid(Map!(Symbol,Object)) == clazz)
348             {
349                 amqpType = _symbolMapType;
350             }
351             else
352             {
353                 amqpType = _describedTypesClassRegistry.get(clazz);
354                 if(amqpType is null && instance !is null)
355                 {
356                     DescribedType describedType = (cast(DescribedType) instance);
357 
358                     version(HUNT_DEBUG) {
359                         if(describedType is null) {
360                             warningf("Can't cast to DescribedType from %s", typeid(instance));
361                         }
362                     }
363 
364                     assert(describedType !is null, 
365                         "Can't cast to DescribedType from " ~ typeid(instance).toString());
366 
367                     Object descriptor = (cast(DescribedType) instance).getDescriptor();
368                     amqpType = _describedDescriptorRegistry.get(descriptor);
369                     if(amqpType is null)
370                     {
371                         amqpType = new DynamicDescribedType(this, descriptor);
372                         _describedDescriptorRegistry.put(descriptor, amqpType);
373                     }
374                 }
375 
376                 return amqpType;
377             }
378        // }
379          _typeRegistry.put(clazz, amqpType);
380 
381         return amqpType;
382     }
383 
384     public void register(V)(AMQPType!(V) type)
385     {
386         register!V(type.getTypeClass(), type);
387     }
388 
389     void register(T)(TypeInfo clazz, AMQPType!(T) type)
390     {
391         _typeRegistry.put(clazz, type);
392     }
393     //
394     //public void registerDescribedType(Class clazz, Object descriptor)
395     //{
396     //    AMQPType<?> type = _describedDescriptorRegistry.get(descriptor);
397     //    if(type is null)
398     //    {
399     //        type = new DynamicDescribedType(this, descriptor);
400     //        _describedDescriptorRegistry.put(descriptor, type);
401     //    }
402     //    _describedTypesClassRegistry.put(clazz, type);
403     //}
404 
405     override
406     public void writeNull()
407     {
408         _buffer.put(EncodingCodes.NULL);
409     }
410 
411     override
412     public void writeBoolean(bool bl)
413     {
414         if (bl)
415         {
416             _buffer.put(EncodingCodes.BOOLEAN_TRUE);
417         }
418         else
419         {
420             _buffer.put(EncodingCodes.BOOLEAN_FALSE);
421         }
422     }
423 
424     public void writeBoolean(Boolean bl)
425     {
426         if(bl is null)
427         {
428             writeNull();
429         }
430         else if (bl.booleanValue())
431         {
432             _buffer.put(EncodingCodes.BOOLEAN_TRUE);
433         }
434         else
435         {
436             _buffer.put(EncodingCodes.BOOLEAN_FALSE);
437         }
438     }
439 
440     override
441     public void writeUnsignedByte(UnsignedByte ub)
442     {
443         if(ub is null)
444         {
445             writeNull();
446         }
447         else
448         {
449             _unsignedByteType.fastWrite(this, ub);
450         }
451     }
452 
453     override
454     public void writeUnsignedShort(UnsignedShort us)
455     {
456         if(us is null)
457         {
458             writeNull();
459         }
460         else
461         {
462             _unsignedShortType.fastWrite(this, us);
463         }
464     }
465 
466     override
467     public void writeUnsignedInteger(UnsignedInteger ui)
468     {
469         if(ui is null)
470         {
471             writeNull();
472         }
473         else
474         {
475             _unsignedIntegerType.fastWrite(this, ui);
476         }
477     }
478 
479     override
480     public void writeUnsignedLong(UnsignedLong ul)
481     {
482         if(ul is null)
483         {
484             writeNull();
485         }
486         else
487         {
488             _unsignedLongType.fastWrite(this, ul);
489         }
490     }
491 
492     override
493     public void writeByte(byte b)
494     {
495         _byteType.write(new Byte(b));
496     }
497 
498     override
499     public void writeByte(Byte b)
500     {
501         if(b is null)
502         {
503             writeNull();
504         }
505         else
506         {
507             writeByte(b.byteValue());
508         }
509     }
510 
511     override
512     public void writeShort(short s)
513     {
514         _shortType.write(s);
515     }
516 
517     override
518     public void writeShort(Short s)
519     {
520         if(s is null)
521         {
522             writeNull();
523         }
524         else
525         {
526             writeShort(s.shortValue());
527         }
528     }
529 
530     override
531     public void writeInteger(int i)
532     {
533         _integerType.write(i);
534     }
535 
536     override
537     public void writeInteger(Integer i)
538     {
539         if(i is null)
540         {
541             writeNull();
542         }
543         else
544         {
545             writeInteger(i.intValue());
546         }
547     }
548 
549     override
550     public void writeLong(long l)
551     {
552         _longType.write(l);
553     }
554 
555     override
556     public void writeLong(Long l)
557     {
558 
559         if(l is null)
560         {
561             writeNull();
562         }
563         else
564         {
565             writeLong(l.longValue());
566         }
567     }
568 
569     override
570     public void writeFloat(float f)
571     {
572         _floatType.write(f);
573     }
574 
575     override
576     public void writeFloat(Float f)
577     {
578         if(f is null)
579         {
580             writeNull();
581         }
582         else
583         {
584             writeFloat(f.floatValue());
585         }
586     }
587 
588     override
589     public void writeDouble(double d)
590     {
591         _doubleType.write(d);
592     }
593 
594     override
595     public void writeDouble(Double d)
596     {
597         if(d is null)
598         {
599             writeNull();
600         }
601         else
602         {
603             writeDouble(d.doubleValue());
604         }
605     }
606 
607     override
608     public void writeDecimal32(Decimal32 d)
609     {
610         if(d is null)
611         {
612             writeNull();
613         }
614         else
615         {
616          //   _decimal32Type.write(d);
617         }
618     }
619 
620     override
621     public void writeDecimal64(Decimal64 d)
622     {
623         if(d is null)
624         {
625             writeNull();
626         }
627         else
628         {
629          //   _decimal64Type.write(d);
630         }
631     }
632 
633     override
634     public void writeDecimal128(Decimal128 d)
635     {
636         if(d is null)
637         {
638             writeNull();
639         }
640         else
641         {
642            // _decimal128Type.write(d);
643         }
644     }
645 
646     override
647     public void writeCharacter(char c)
648     {
649         // TODO - java character may be half of a pair, should probably throw exception then
650         _characterType.write(c);
651     }
652 
653     override
654     public void writeCharacter(Char c)
655     {
656         if(c is null)
657         {
658             writeNull();
659         }
660         else
661         {
662             writeCharacter(c.charValue());
663         }
664     }
665 
666     override
667     public void writeTimestamp(long timestamp)
668     {
669       //  implementationMissing(false);
670         _timestampType.fastWrite(this, timestamp);
671     }
672 
673     override
674     public void writeTimestamp(Date d)
675     {
676         if(d is null)
677         {
678             writeNull();
679         }
680         else
681         {
682             //implementationMissing(false);
683             _timestampType.fastWrite(this, d.toEpochMilli());
684         }
685     }
686 
687     override
688     public void writeUUID(UUID uuid)
689     {
690         //if(uuid is null)
691         //{
692         //    writeNull();
693         //}
694         //else
695         //{
696         //    _uuidType.fastWrite(this, uuid);
697         //}
698     }
699 
700     override
701     public void writeBinary(Binary b)
702     {
703         if(b is null)
704         {
705             writeNull();
706         }
707         else
708         {
709             _binaryType.fastWrite(this, b);
710         }
711     }
712 
713     override
714     public void writeString(String s)
715     {
716         if(s is null)
717         {
718             writeNull();
719         }
720         else
721         {
722             _stringType.write(s);
723         }
724     }
725 
726     override
727     public void writeSymbol(Symbol s)
728     {
729         if(s is null)
730         {
731             writeNull();
732         }
733         else
734         {
735             _symbolType.fastWrite(this, s);
736         }
737     }
738 
739     override
740     public void writeList(Object l)
741     {
742         if(l is null)
743         {
744             writeNull();
745         }
746         else
747         {
748             _listType.write(l);
749         }
750     }
751 
752     override
753     public void writeMap(Object m)
754     {
755 
756         if(m is null)
757         {
758             writeNull();
759         }
760         else
761         {
762             _objectMapType.write(m);
763         }
764     }
765 
766     override
767     public void writeDescribedType(DescribedType d)
768     {
769         if(d is null)
770         {
771             writeNull();
772         }
773         else
774         {
775             _buffer.put(DESCRIBED_TYPE_OP);
776            // implementationMissing(false);
777             writeObject(d.getDescriptor());
778             writeObject(d.getDescribed());
779         }
780     }
781 
782     //override
783     //public void writeArray(bool[] a)
784     //{
785     //    if(a is null)
786     //    {
787     //        writeNull();
788     //    }
789     //    else
790     //    {
791     //        _arrayType.write(a);
792     //    }
793     //}
794 
795     //override
796     //public void writeArray(byte[] a)
797     //{
798     //    if(a is null)
799     //    {
800     //        writeNull();
801     //    }
802     //    else
803     //    {
804     //        _arrayType.write(a);
805     //    }
806     //}
807     //
808     //override
809     //public void writeArray(short[] a)
810     //{
811     //    if(a is null)
812     //    {
813     //        writeNull();
814     //    }
815     //    else
816     //    {
817     //        _arrayType.write(a);
818     //    }
819     //}
820 
821     override
822     public void writeArray(int[] a)
823     {
824         if(a is null)
825         {
826             writeNull();
827         }
828         else
829         {
830           //  _arrayType.write(a);
831         }
832     }
833 
834     override
835     public void writeArray(long[] a)
836     {
837         if(a is null)
838         {
839             writeNull();
840         }
841         else
842         {
843            // _arrayType.write(a);
844         }
845     }
846 
847     override
848     public void writeArray(float[] a)
849     {
850         if(a is null)
851         {
852             writeNull();
853         }
854         else
855         {
856          //   _arrayType.write(a);
857         }
858     }
859 
860     override
861     public void writeArray(double[] a)
862     {
863         if(a is null)
864         {
865             writeNull();
866         }
867         else
868         {
869          //   _arrayType.write(a);
870         }
871     }
872 
873     override
874     public void writeArray(char[] a)
875     {
876         if(a is null)
877         {
878             writeNull();
879         }
880         else
881         {
882            // _arrayType.write(a);
883         }
884     }
885 
886     override
887     public void writeArray(Object[] a)
888     {
889         if(a is null)
890         {
891             writeNull();
892         }
893         else
894         {
895           //  _arrayType.write(a);
896         }
897     }
898 
899     override
900     public void writeObject(Object o)
901     {
902         if (o !is null)
903         {
904             IAMQPType type = _typeRegistry.get(typeid(o));
905 
906             if(type !is null)
907             {
908                 type.write(o);
909             }
910             else
911             {
912                 writeUnregisteredType(o);
913             }
914         }
915         else
916         {
917             _buffer.put(EncodingCodes.NULL);
918         }
919     }
920 
921 
922 
923 
924 
925     private void writeUnregisteredType(Object o)
926     {
927 
928 
929         if(cast(List!Object)o !is null)
930         {
931             writeList(o);
932         }
933         else if(cast(Map!(String,Object))o !is null)
934         {
935             writeMap(o);
936         }
937         else if( cast(DescribedType)o !is null)
938         {
939             writeDescribedType(cast(DescribedType)o);
940         }
941         else
942         {
943             throw new IllegalArgumentException(
944                 "Do not know how to write Objects of class ");
945         }
946     }
947     //
948     //private void writeArrayType(Object array) {
949     //    Class<?> componentType = array.getClass().getComponentType();
950     //    if(componentType.isPrimitive())
951     //    {
952     //        if(componentType == Boolean.TYPE)
953     //        {
954     //            writeArray((bool[])array);
955     //        }
956     //        else if(componentType == Byte.TYPE)
957     //        {
958     //            writeArray((byte[])array);
959     //        }
960     //        else if(componentType == Short.TYPE)
961     //        {
962     //            writeArray((short[])array);
963     //        }
964     //        else if(componentType == Integer.TYPE)
965     //        {
966     //            writeArray((int[])array);
967     //        }
968     //        else if(componentType == Long.TYPE)
969     //        {
970     //            writeArray((long[])array);
971     //        }
972     //        else if(componentType == Float.TYPE)
973     //        {
974     //            writeArray((float[])array);
975     //        }
976     //        else if(componentType == Double.TYPE)
977     //        {
978     //            writeArray((double[])array);
979     //        }
980     //        else if(componentType == Character.TYPE)
981     //        {
982     //            writeArray((char[])array);
983     //        }
984     //        else
985     //        {
986     //            throw new IllegalArgumentException("Cannot write arrays of type " ~ componentType.getName());
987     //        }
988     //    }
989     //    else
990     //    {
991     //        writeArray((Object[]) array);
992     //    }
993     //}
994 
995     public void writeRaw(byte b)
996     {
997         _buffer.put(b);
998     }
999 
1000     void writeRaw(short s)
1001     {
1002         _buffer.putShort(s);
1003     }
1004 
1005     void writeRaw(int i)
1006     {
1007         _buffer.putInt(i);
1008     }
1009 
1010     void writeRaw(long l)
1011     {
1012         _buffer.putLong(l);
1013     }
1014 
1015     void writeRaw(float f)
1016     {
1017         _buffer.putFloat(f);
1018     }
1019 
1020     void writeRaw(double d)
1021     {
1022         _buffer.putDouble(d);
1023     }
1024 
1025     void writeRaw(byte[] src, int offset, int length)
1026     {
1027         _buffer.put(src, offset, length);
1028     }
1029 
1030     void writeRaw(String str)
1031     {
1032         _buffer.put(cast(string)str.getBytes());
1033     }
1034 
1035     //AMQPType<?> getNullTypeEncoder()
1036     //{
1037     //    return _nullType;
1038     //}
1039 }