1{-# LANGUAGE BangPatterns #-}
2module Throughput.BinaryPut (serialize) where
3
4import qualified Data.ByteString.Lazy as L
5import Data.Binary.Put
6
7import Throughput.Utils
8
9serialize :: Int -> Int -> Endian -> Int -> L.ByteString
10serialize wordSize chunkSize end = runPut .
11  case (wordSize, chunkSize, end) of
12    (1, 1,_)   -> putWord8N1
13    (1, 2,_)   -> putWord8N2
14    (1, 4,_)   -> putWord8N4
15    (1, 8,_)   -> putWord8N8
16    (1, 16, _) -> putWord8N16
17
18    (2, 1,  Big)    -> putWord16N1Big
19    (2, 2,  Big)    -> putWord16N2Big
20    (2, 4,  Big)    -> putWord16N4Big
21    (2, 8,  Big)    -> putWord16N8Big
22    (2, 16, Big)    -> putWord16N16Big
23    (2, 1,  Little) -> putWord16N1Little
24    (2, 2,  Little) -> putWord16N2Little
25    (2, 4,  Little) -> putWord16N4Little
26    (2, 8,  Little) -> putWord16N8Little
27    (2, 16, Little) -> putWord16N16Little
28    (2, 1,  Host)   -> putWord16N1Host
29    (2, 2,  Host)   -> putWord16N2Host
30    (2, 4,  Host)   -> putWord16N4Host
31    (2, 8,  Host)   -> putWord16N8Host
32    (2, 16, Host)   -> putWord16N16Host
33
34    (4, 1,  Big)    -> putWord32N1Big
35    (4, 2,  Big)    -> putWord32N2Big
36    (4, 4,  Big)    -> putWord32N4Big
37    (4, 8,  Big)    -> putWord32N8Big
38    (4, 16, Big)    -> putWord32N16Big
39    (4, 1,  Little) -> putWord32N1Little
40    (4, 2,  Little) -> putWord32N2Little
41    (4, 4,  Little) -> putWord32N4Little
42    (4, 8,  Little) -> putWord32N8Little
43    (4, 16, Little) -> putWord32N16Little
44    (4, 1,  Host)   -> putWord32N1Host
45    (4, 2,  Host)   -> putWord32N2Host
46    (4, 4,  Host)   -> putWord32N4Host
47    (4, 8,  Host)   -> putWord32N8Host
48    (4, 16, Host)   -> putWord32N16Host
49
50    (8, 1,  Host)        -> putWord64N1Host
51    (8, 2,  Host)        -> putWord64N2Host
52    (8, 4,  Host)        -> putWord64N4Host
53    (8, 8,  Host)        -> putWord64N8Host
54    (8, 16, Host)        -> putWord64N16Host
55    (8, 1,  Big)         -> putWord64N1Big
56    (8, 2,  Big)         -> putWord64N2Big
57    (8, 4,  Big)         -> putWord64N4Big
58    (8, 8,  Big)         -> putWord64N8Big
59    (8, 16, Big)         -> putWord64N16Big
60    (8, 1,  Little)      -> putWord64N1Little
61    (8, 2,  Little)      -> putWord64N2Little
62    (8, 4,  Little)      -> putWord64N4Little
63    (8, 8,  Little)      -> putWord64N8Little
64    (8, 16, Little)      -> putWord64N16Little
65
66------------------------------------------------------------------------
67
68putWord8N1 bytes = loop 0 0
69  where loop !s !n | n == bytes = return ()
70                   | otherwise  = do putWord8 s
71                                     loop (s+1) (n+1)
72
73putWord8N2 = loop 0
74  where loop s n | s `seq` n `seq` False = undefined
75        loop _ 0 = return ()
76        loop s n = do
77          putWord8 (s+0)
78          putWord8 (s+1)
79          loop (s+2) (n-2)
80
81putWord8N4 = loop 0
82  where loop s n | s `seq` n `seq` False = undefined
83        loop _ 0 = return ()
84        loop s n = do
85          putWord8 (s+0)
86          putWord8 (s+1)
87          putWord8 (s+2)
88          putWord8 (s+3)
89          loop (s+4) (n-4)
90
91putWord8N8 = loop 0
92  where loop s n | s `seq` n `seq` False = undefined
93        loop _ 0 = return ()
94        loop s n = do
95          putWord8 (s+0)
96          putWord8 (s+1)
97          putWord8 (s+2)
98          putWord8 (s+3)
99          putWord8 (s+4)
100          putWord8 (s+5)
101          putWord8 (s+6)
102          putWord8 (s+7)
103          loop (s+8) (n-8)
104
105putWord8N16 = loop 0
106  where loop s n | s `seq` n `seq` False = undefined
107        loop _ 0 = return ()
108        loop s n = do
109          putWord8 (s+0)
110          putWord8 (s+1)
111          putWord8 (s+2)
112          putWord8 (s+3)
113          putWord8 (s+4)
114          putWord8 (s+5)
115          putWord8 (s+6)
116          putWord8 (s+7)
117          putWord8 (s+8)
118          putWord8 (s+9)
119          putWord8 (s+10)
120          putWord8 (s+11)
121          putWord8 (s+12)
122          putWord8 (s+13)
123          putWord8 (s+14)
124          putWord8 (s+15)
125          loop (s+16) (n-16)
126
127------------------------------------------------------------------------
128-- Big endian, word16 writes
129
130putWord16N1Big = loop 0
131  where loop s n | s `seq` n `seq` False = undefined
132        loop _ 0 = return ()
133        loop s n = do
134          putWord16be (s+0)
135          loop (s+1) (n-1)
136
137putWord16N2Big = loop 0
138  where loop s n | s `seq` n `seq` False = undefined
139        loop _ 0 = return ()
140        loop s n = do
141          putWord16be (s+0)
142          putWord16be (s+1)
143          loop (s+2) (n-2)
144
145putWord16N4Big = loop 0
146  where loop s n | s `seq` n `seq` False = undefined
147        loop _ 0 = return ()
148        loop s n = do
149          putWord16be (s+0)
150          putWord16be (s+1)
151          putWord16be (s+2)
152          putWord16be (s+3)
153          loop (s+4) (n-4)
154
155putWord16N8Big = loop 0
156  where loop s n | s `seq` n `seq` False = undefined
157        loop _ 0 = return ()
158        loop s n = do
159          putWord16be (s+0)
160          putWord16be (s+1)
161          putWord16be (s+2)
162          putWord16be (s+3)
163          putWord16be (s+4)
164          putWord16be (s+5)
165          putWord16be (s+6)
166          putWord16be (s+7)
167          loop (s+8) (n-8)
168
169putWord16N16Big = loop 0
170  where loop s n | s `seq` n `seq` False = undefined
171        loop _ 0 = return ()
172        loop s n = do
173          putWord16be (s+0)
174          putWord16be (s+1)
175          putWord16be (s+2)
176          putWord16be (s+3)
177          putWord16be (s+4)
178          putWord16be (s+5)
179          putWord16be (s+6)
180          putWord16be (s+7)
181          putWord16be (s+8)
182          putWord16be (s+9)
183          putWord16be (s+10)
184          putWord16be (s+11)
185          putWord16be (s+12)
186          putWord16be (s+13)
187          putWord16be (s+14)
188          putWord16be (s+15)
189          loop (s+16) (n-16)
190
191------------------------------------------------------------------------
192-- Little endian, word16 writes
193
194putWord16N1Little = loop 0
195  where loop s n | s `seq` n `seq` False = undefined
196        loop _ 0 = return ()
197        loop s n = do
198          putWord16le (s+0)
199          loop (s+1) (n-1)
200
201putWord16N2Little = loop 0
202  where loop s n | s `seq` n `seq` False = undefined
203        loop _ 0 = return ()
204        loop s n = do
205          putWord16le (s+0)
206          putWord16le (s+1)
207          loop (s+2) (n-2)
208
209putWord16N4Little = loop 0
210  where loop s n | s `seq` n `seq` False = undefined
211        loop _ 0 = return ()
212        loop s n = do
213          putWord16le (s+0)
214          putWord16le (s+1)
215          putWord16le (s+2)
216          putWord16le (s+3)
217          loop (s+4) (n-4)
218
219putWord16N8Little = loop 0
220  where loop s n | s `seq` n `seq` False = undefined
221        loop _ 0 = return ()
222        loop s n = do
223          putWord16le (s+0)
224          putWord16le (s+1)
225          putWord16le (s+2)
226          putWord16le (s+3)
227          putWord16le (s+4)
228          putWord16le (s+5)
229          putWord16le (s+6)
230          putWord16le (s+7)
231          loop (s+8) (n-8)
232
233putWord16N16Little = loop 0
234  where loop s n | s `seq` n `seq` False = undefined
235        loop _ 0 = return ()
236        loop s n = do
237          putWord16le (s+0)
238          putWord16le (s+1)
239          putWord16le (s+2)
240          putWord16le (s+3)
241          putWord16le (s+4)
242          putWord16le (s+5)
243          putWord16le (s+6)
244          putWord16le (s+7)
245          putWord16le (s+8)
246          putWord16le (s+9)
247          putWord16le (s+10)
248          putWord16le (s+11)
249          putWord16le (s+12)
250          putWord16le (s+13)
251          putWord16le (s+14)
252          putWord16le (s+15)
253          loop (s+16) (n-16)
254
255------------------------------------------------------------------------
256-- Host endian, unaligned, word16 writes
257
258putWord16N1Host = loop 0
259  where loop s n | s `seq` n `seq` False = undefined
260        loop _ 0 = return ()
261        loop s n = do
262          putWord16host (s+0)
263          loop (s+1) (n-1)
264
265putWord16N2Host = loop 0
266  where loop s n | s `seq` n `seq` False = undefined
267        loop _ 0 = return ()
268        loop s n = do
269          putWord16host (s+0)
270          putWord16host (s+1)
271          loop (s+2) (n-2)
272
273putWord16N4Host = loop 0
274  where loop s n | s `seq` n `seq` False = undefined
275        loop _ 0 = return ()
276        loop s n = do
277          putWord16host (s+0)
278          putWord16host (s+1)
279          putWord16host (s+2)
280          putWord16host (s+3)
281          loop (s+4) (n-4)
282
283putWord16N8Host = loop 0
284  where loop s n | s `seq` n `seq` False = undefined
285        loop _ 0 = return ()
286        loop s n = do
287          putWord16host (s+0)
288          putWord16host (s+1)
289          putWord16host (s+2)
290          putWord16host (s+3)
291          putWord16host (s+4)
292          putWord16host (s+5)
293          putWord16host (s+6)
294          putWord16host (s+7)
295          loop (s+8) (n-8)
296
297putWord16N16Host = loop 0
298  where loop s n | s `seq` n `seq` False = undefined
299        loop _ 0 = return ()
300        loop s n = do
301          putWord16host (s+0)
302          putWord16host (s+1)
303          putWord16host (s+2)
304          putWord16host (s+3)
305          putWord16host (s+4)
306          putWord16host (s+5)
307          putWord16host (s+6)
308          putWord16host (s+7)
309          putWord16host (s+8)
310          putWord16host (s+9)
311          putWord16host (s+10)
312          putWord16host (s+11)
313          putWord16host (s+12)
314          putWord16host (s+13)
315          putWord16host (s+14)
316          putWord16host (s+15)
317          loop (s+16) (n-16)
318
319------------------------------------------------------------------------
320
321putWord32N1Big = loop 0
322  where loop s n | s `seq` n `seq` False = undefined
323        loop _ 0 = return ()
324        loop s n = do
325          putWord32be (s+0)
326          loop (s+1) (n-1)
327
328putWord32N2Big = loop 0
329  where loop s n | s `seq` n `seq` False = undefined
330        loop _ 0 = return ()
331        loop s n = do
332          putWord32be (s+0)
333          putWord32be (s+1)
334          loop (s+2) (n-2)
335
336putWord32N4Big = loop 0
337  where loop s n | s `seq` n `seq` False = undefined
338        loop _ 0 = return ()
339        loop s n = do
340          putWord32be (s+0)
341          putWord32be (s+1)
342          putWord32be (s+2)
343          putWord32be (s+3)
344          loop (s+4) (n-4)
345
346putWord32N8Big = loop 0
347  where loop s n | s `seq` n `seq` False = undefined
348        loop _ 0 = return ()
349        loop s n = do
350          putWord32be (s+0)
351          putWord32be (s+1)
352          putWord32be (s+2)
353          putWord32be (s+3)
354          putWord32be (s+4)
355          putWord32be (s+5)
356          putWord32be (s+6)
357          putWord32be (s+7)
358          loop (s+8) (n-8)
359
360putWord32N16Big = loop 0
361  where loop s n | s `seq` n `seq` False = undefined
362        loop _ 0 = return ()
363        loop s n = do
364          putWord32be (s+0)
365          putWord32be (s+1)
366          putWord32be (s+2)
367          putWord32be (s+3)
368          putWord32be (s+4)
369          putWord32be (s+5)
370          putWord32be (s+6)
371          putWord32be (s+7)
372          putWord32be (s+8)
373          putWord32be (s+9)
374          putWord32be (s+10)
375          putWord32be (s+11)
376          putWord32be (s+12)
377          putWord32be (s+13)
378          putWord32be (s+14)
379          putWord32be (s+15)
380          loop (s+16) (n-16)
381
382------------------------------------------------------------------------
383
384putWord32N1Little = loop 0
385  where loop s n | s `seq` n `seq` False = undefined
386        loop _ 0 = return ()
387        loop s n = do
388          putWord32le (s+0)
389          loop (s+1) (n-1)
390
391putWord32N2Little = loop 0
392  where loop s n | s `seq` n `seq` False = undefined
393        loop _ 0 = return ()
394        loop s n = do
395          putWord32le (s+0)
396          putWord32le (s+1)
397          loop (s+2) (n-2)
398
399putWord32N4Little = loop 0
400  where loop s n | s `seq` n `seq` False = undefined
401        loop _ 0 = return ()
402        loop s n = do
403          putWord32le (s+0)
404          putWord32le (s+1)
405          putWord32le (s+2)
406          putWord32le (s+3)
407          loop (s+4) (n-4)
408
409putWord32N8Little = loop 0
410  where loop s n | s `seq` n `seq` False = undefined
411        loop _ 0 = return ()
412        loop s n = do
413          putWord32le (s+0)
414          putWord32le (s+1)
415          putWord32le (s+2)
416          putWord32le (s+3)
417          putWord32le (s+4)
418          putWord32le (s+5)
419          putWord32le (s+6)
420          putWord32le (s+7)
421          loop (s+8) (n-8)
422
423putWord32N16Little = loop 0
424  where loop s n | s `seq` n `seq` False = undefined
425        loop _ 0 = return ()
426        loop s n = do
427          putWord32le (s+0)
428          putWord32le (s+1)
429          putWord32le (s+2)
430          putWord32le (s+3)
431          putWord32le (s+4)
432          putWord32le (s+5)
433          putWord32le (s+6)
434          putWord32le (s+7)
435          putWord32le (s+8)
436          putWord32le (s+9)
437          putWord32le (s+10)
438          putWord32le (s+11)
439          putWord32le (s+12)
440          putWord32le (s+13)
441          putWord32le (s+14)
442          putWord32le (s+15)
443          loop (s+16) (n-16)
444
445------------------------------------------------------------------------
446
447putWord32N1Host = loop 0
448  where loop s n | s `seq` n `seq` False = undefined
449        loop _ 0 = return ()
450        loop s n = do
451          putWord32host (s+0)
452          loop (s+1) (n-1)
453
454putWord32N2Host = loop 0
455  where loop s n | s `seq` n `seq` False = undefined
456        loop _ 0 = return ()
457        loop s n = do
458          putWord32host (s+0)
459          putWord32host (s+1)
460          loop (s+2) (n-2)
461
462putWord32N4Host = loop 0
463  where loop s n | s `seq` n `seq` False = undefined
464        loop _ 0 = return ()
465        loop s n = do
466          putWord32host (s+0)
467          putWord32host (s+1)
468          putWord32host (s+2)
469          putWord32host (s+3)
470          loop (s+4) (n-4)
471
472putWord32N8Host = loop 0
473  where loop s n | s `seq` n `seq` False = undefined
474        loop _ 0 = return ()
475        loop s n = do
476          putWord32host (s+0)
477          putWord32host (s+1)
478          putWord32host (s+2)
479          putWord32host (s+3)
480          putWord32host (s+4)
481          putWord32host (s+5)
482          putWord32host (s+6)
483          putWord32host (s+7)
484          loop (s+8) (n-8)
485
486putWord32N16Host = loop 0
487  where loop s n | s `seq` n `seq` False = undefined
488        loop _ 0 = return ()
489        loop s n = do
490          putWord32host (s+0)
491          putWord32host (s+1)
492          putWord32host (s+2)
493          putWord32host (s+3)
494          putWord32host (s+4)
495          putWord32host (s+5)
496          putWord32host (s+6)
497          putWord32host (s+7)
498          putWord32host (s+8)
499          putWord32host (s+9)
500          putWord32host (s+10)
501          putWord32host (s+11)
502          putWord32host (s+12)
503          putWord32host (s+13)
504          putWord32host (s+14)
505          putWord32host (s+15)
506          loop (s+16) (n-16)
507
508------------------------------------------------------------------------
509
510putWord64N1Big = loop 0
511  where loop s n | s `seq` n `seq` False = undefined
512        loop _ 0 = return ()
513        loop s n = do
514          putWord64be (s+0)
515          loop (s+1) (n-1)
516
517putWord64N2Big = loop 0
518  where loop s n | s `seq` n `seq` False = undefined
519        loop _ 0 = return ()
520        loop s n = do
521          putWord64be (s+0)
522          putWord64be (s+1)
523          loop (s+2) (n-2)
524
525putWord64N4Big = loop 0
526  where loop s n | s `seq` n `seq` False = undefined
527        loop _ 0 = return ()
528        loop s n = do
529          putWord64be (s+0)
530          putWord64be (s+1)
531          putWord64be (s+2)
532          putWord64be (s+3)
533          loop (s+4) (n-4)
534
535putWord64N8Big = loop 0
536  where loop s n | s `seq` n `seq` False = undefined
537        loop _ 0 = return ()
538        loop s n = do
539          putWord64be (s+0)
540          putWord64be (s+1)
541          putWord64be (s+2)
542          putWord64be (s+3)
543          putWord64be (s+4)
544          putWord64be (s+5)
545          putWord64be (s+6)
546          putWord64be (s+7)
547          loop (s+8) (n-8)
548
549putWord64N16Big = loop 0
550  where loop s n | s `seq` n `seq` False = undefined
551        loop _ 0 = return ()
552        loop s n = do
553          putWord64be (s+0)
554          putWord64be (s+1)
555          putWord64be (s+2)
556          putWord64be (s+3)
557          putWord64be (s+4)
558          putWord64be (s+5)
559          putWord64be (s+6)
560          putWord64be (s+7)
561          putWord64be (s+8)
562          putWord64be (s+9)
563          putWord64be (s+10)
564          putWord64be (s+11)
565          putWord64be (s+12)
566          putWord64be (s+13)
567          putWord64be (s+14)
568          putWord64be (s+15)
569          loop (s+16) (n-16)
570
571------------------------------------------------------------------------
572
573putWord64N1Little = loop 0
574  where loop s n | s `seq` n `seq` False = undefined
575        loop _ 0 = return ()
576        loop s n = do
577          putWord64le (s+0)
578          loop (s+1) (n-1)
579
580putWord64N2Little = loop 0
581  where loop s n | s `seq` n `seq` False = undefined
582        loop _ 0 = return ()
583        loop s n = do
584          putWord64le (s+0)
585          putWord64le (s+1)
586          loop (s+2) (n-2)
587
588putWord64N4Little = loop 0
589  where loop s n | s `seq` n `seq` False = undefined
590        loop _ 0 = return ()
591        loop s n = do
592          putWord64le (s+0)
593          putWord64le (s+1)
594          putWord64le (s+2)
595          putWord64le (s+3)
596          loop (s+4) (n-4)
597
598putWord64N8Little = loop 0
599  where loop s n | s `seq` n `seq` False = undefined
600        loop _ 0 = return ()
601        loop s n = do
602          putWord64le (s+0)
603          putWord64le (s+1)
604          putWord64le (s+2)
605          putWord64le (s+3)
606          putWord64le (s+4)
607          putWord64le (s+5)
608          putWord64le (s+6)
609          putWord64le (s+7)
610          loop (s+8) (n-8)
611
612putWord64N16Little = loop 0
613  where loop s n | s `seq` n `seq` False = undefined
614        loop _ 0 = return ()
615        loop s n = do
616          putWord64le (s+0)
617          putWord64le (s+1)
618          putWord64le (s+2)
619          putWord64le (s+3)
620          putWord64le (s+4)
621          putWord64le (s+5)
622          putWord64le (s+6)
623          putWord64le (s+7)
624          putWord64le (s+8)
625          putWord64le (s+9)
626          putWord64le (s+10)
627          putWord64le (s+11)
628          putWord64le (s+12)
629          putWord64le (s+13)
630          putWord64le (s+14)
631          putWord64le (s+15)
632          loop (s+16) (n-16)
633
634------------------------------------------------------------------------
635
636putWord64N1Host = loop 0
637  where loop s n | s `seq` n `seq` False = undefined
638        loop _ 0 = return ()
639        loop s n = do
640          putWord64host (s+0)
641          loop (s+1) (n-1)
642
643putWord64N2Host = loop 0
644  where loop s n | s `seq` n `seq` False = undefined
645        loop _ 0 = return ()
646        loop s n = do
647          putWord64host (s+0)
648          putWord64host (s+1)
649          loop (s+2) (n-2)
650
651putWord64N4Host = loop 0
652  where loop s n | s `seq` n `seq` False = undefined
653        loop _ 0 = return ()
654        loop s n = do
655          putWord64host (s+0)
656          putWord64host (s+1)
657          putWord64host (s+2)
658          putWord64host (s+3)
659          loop (s+4) (n-4)
660
661putWord64N8Host = loop 0
662  where loop s n | s `seq` n `seq` False = undefined
663        loop _ 0 = return ()
664        loop s n = do
665          putWord64host (s+0)
666          putWord64host (s+1)
667          putWord64host (s+2)
668          putWord64host (s+3)
669          putWord64host (s+4)
670          putWord64host (s+5)
671          putWord64host (s+6)
672          putWord64host (s+7)
673          loop (s+8) (n-8)
674
675putWord64N16Host = loop 0
676  where loop s n | s `seq` n `seq` False = undefined
677        loop _ 0 = return ()
678        loop s n = do
679          putWord64host (s+0)
680          putWord64host (s+1)
681          putWord64host (s+2)
682          putWord64host (s+3)
683          putWord64host (s+4)
684          putWord64host (s+5)
685          putWord64host (s+6)
686          putWord64host (s+7)
687          putWord64host (s+8)
688          putWord64host (s+9)
689          putWord64host (s+10)
690          putWord64host (s+11)
691          putWord64host (s+12)
692          putWord64host (s+13)
693          putWord64host (s+14)
694          putWord64host (s+15)
695          loop (s+16) (n-16)
696
697