132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Jan 2007 : initial release
|
|
8
|
|
9 author: Kris
|
|
10
|
|
11 *******************************************************************************/
|
|
12
|
|
13 module tango.io.protocol.EndianProtocol;
|
|
14
|
|
15 private import tango.core.ByteSwap;
|
|
16
|
|
17 private import tango.io.model.IBuffer,
|
|
18 tango.io.model.IConduit;
|
|
19
|
|
20 private import tango.io.protocol.NativeProtocol;
|
|
21
|
|
22 /*******************************************************************************
|
|
23
|
|
24 *******************************************************************************/
|
|
25
|
|
26 class EndianProtocol : NativeProtocol
|
|
27 {
|
|
28 /***********************************************************************
|
|
29
|
|
30 ***********************************************************************/
|
|
31
|
|
32 this (IConduit conduit, bool prefix=true)
|
|
33 {
|
|
34 super (conduit, prefix);
|
|
35 }
|
|
36
|
|
37 /***********************************************************************
|
|
38
|
|
39 ***********************************************************************/
|
|
40
|
|
41 override void[] read (void* dst, uint bytes, Type type)
|
|
42 {
|
|
43 auto ret = super.read (dst, bytes, type);
|
|
44
|
|
45 switch (type)
|
|
46 {
|
|
47 case Type.Short:
|
|
48 case Type.UShort:
|
|
49 case Type.Utf16:
|
|
50 ByteSwap.swap16 (dst, bytes);
|
|
51 break;
|
|
52
|
|
53 case Type.Int:
|
|
54 case Type.UInt:
|
|
55 case Type.Float:
|
|
56 case Type.Utf32:
|
|
57 ByteSwap.swap32 (dst, bytes);
|
|
58 break;
|
|
59
|
|
60 case Type.Long:
|
|
61 case Type.ULong:
|
|
62 case Type.Double:
|
|
63 ByteSwap.swap64 (dst, bytes);
|
|
64 break;
|
|
65
|
|
66 case Type.Real:
|
|
67 ByteSwap.swap80 (dst, bytes);
|
|
68 break;
|
|
69
|
|
70 default:
|
|
71 break;
|
|
72 }
|
|
73
|
|
74 return ret;
|
|
75 }
|
|
76
|
|
77 /***********************************************************************
|
|
78
|
|
79 ***********************************************************************/
|
|
80
|
|
81 override void write (void* src, uint bytes, Type type)
|
|
82 {
|
|
83 alias void function (void* dst, uint bytes) Swapper;
|
|
84
|
|
85 void write (int mask, Swapper mutate)
|
|
86 {
|
|
87 uint writer (void[] dst)
|
|
88 {
|
|
89 // cap bytes written
|
|
90 uint len = dst.length & mask;
|
|
91 if (len > bytes)
|
|
92 len = bytes;
|
|
93
|
|
94 dst [0..len] = src [0..len];
|
|
95 mutate (dst.ptr, len);
|
|
96 return len;
|
|
97 }
|
|
98
|
|
99 while (bytes)
|
|
100 if (bytes -= buffer_.write (&writer))
|
|
101 // flush if we used all buffer space
|
|
102 buffer_.drain (buffer.output);
|
|
103 }
|
|
104
|
|
105
|
|
106 switch (type)
|
|
107 {
|
|
108 case Type.Short:
|
|
109 case Type.UShort:
|
|
110 case Type.Utf16:
|
|
111 write (~1, &ByteSwap.swap16);
|
|
112 break;
|
|
113
|
|
114 case Type.Int:
|
|
115 case Type.UInt:
|
|
116 case Type.Float:
|
|
117 case Type.Utf32:
|
|
118 write (~3, &ByteSwap.swap32);
|
|
119 break;
|
|
120
|
|
121 case Type.Long:
|
|
122 case Type.ULong:
|
|
123 case Type.Double:
|
|
124 write (~7, &ByteSwap.swap64);
|
|
125 break;
|
|
126
|
|
127 case Type.Real:
|
|
128 write (~15, &ByteSwap.swap80);
|
|
129 break;
|
|
130
|
|
131 default:
|
|
132 super.write (src, bytes, type);
|
|
133 break;
|
|
134 }
|
|
135 }
|
|
136 }
|
|
137
|
|
138
|
|
139 /*******************************************************************************
|
|
140
|
|
141 *******************************************************************************/
|
|
142
|
|
143 debug (UnitTest)
|
|
144 {
|
|
145 import tango.io.Buffer;
|
|
146
|
|
147 unittest
|
|
148 {
|
|
149 void[] alloc (EndianProtocol.Reader reader, uint bytes, EndianProtocol.Type type)
|
|
150 {
|
|
151 return reader ((new void[bytes]).ptr, bytes, type);
|
|
152 }
|
|
153
|
|
154 char[] mule;
|
|
155 char[] test = "testing testing 123";
|
|
156
|
|
157 auto protocol = new EndianProtocol (new Buffer(32));
|
|
158 protocol.writeArray (test.ptr, test.length, protocol.Type.Utf8);
|
|
159
|
|
160 mule = cast(char[]) protocol.readArray (mule.ptr, mule.length, protocol.Type.Utf8, &alloc);
|
|
161 assert (mule == test);
|
|
162
|
|
163 }
|
|
164 }
|
|
165
|
|
166
|
|
167
|
|
168
|
|
169
|