1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include <stdio.h>
#include <string.h>
#include "IO/Write.h"
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
static void InvalidSizeError(WriteController *Controller, int32_t Size) {
// FIXME
}
template<typename T>
static T getValue(const void *Ptr) {
return *(reinterpret_cast<const T*>(Ptr));
}
template<typename T>
static T getValue(const void *Ptr,size_t I) {
return (reinterpret_cast<const T*>(Ptr))[I];
}
static int getIntValue(WriteController *Controller, const void *Ptr, int32_t Size) {
switch(Size) {
case 1:
return getValue<int8_t>(Ptr);
case 2:
return getValue<int16_t>(Ptr);
case 4:
return getValue<int32_t>(Ptr);
case 8:
return int(getValue<int64_t>(Ptr));
default:
InvalidSizeError(Controller, Size);
break;
}
return 0;
}
static FILE *getFilePtr(WriteController *Controller) {
return stdin;
}
class Buffer {
enum {
kStorageSize = 128
};
size_t Offset;
char Storage[kStorageSize];
public:
Buffer() : Offset(0) {}
template <typename T>
void Print(const char *FMT, T Value) {
auto Remaining = size_t(kStorageSize)-Offset;
if(Remaining)
Offset += snprintf(Storage + Offset, Remaining, FMT, Value);
}
void Write(WriteController *Controller) {
fwrite(Storage, 1, Offset, getFilePtr(Controller));
}
};
template <typename T>
static inline void SmallPrintf(WriteController *Controller, const char *FMT, T Value) {
Buffer Buf;
Buf.Print(FMT, Value);
Buf.Write(Controller);
}
template <typename T1, typename T2>
static inline void SmallPrintf(WriteController *Controller, const char *FMT1, T1 Value1, const char *FMT2, T2 Value2) {
Buffer Buf;
Buf.Print(FMT1, Value1);
Buf.Print(FMT2, Value2);
Buf.Write(Controller);
}
LIBFLANG_ABI void libflang_write_start(WriteController *Controller) {
}
LIBFLANG_ABI void libflang_write_integer(WriteController *Controller, const void *Ptr, int32_t Size) {
SmallPrintf(Controller, "%i", getIntValue(Controller, Ptr, Size));
}
LIBFLANG_ABI void libflang_write_real(WriteController *Controller, const void *Ptr, int32_t Size) {
switch(Size) {
case 4:
SmallPrintf(Controller, "%g", getValue<float>(Ptr));
break;
case 8:
SmallPrintf(Controller, "%g", getValue<double>(Ptr));
break;
default:
InvalidSizeError(Controller, Size);
break;
}
}
LIBFLANG_ABI void libflang_write_complex(WriteController *Controller, const void *Ptr, int32_t Size) {
switch(Size) {
case 4:
SmallPrintf(Controller, "(%g, ", getValue<float>(Ptr), "%g)", getValue<float>(Ptr,1));
break;
case 8:
SmallPrintf(Controller, "(%g, ", getValue<double>(Ptr), "%g)", getValue<double>(Ptr,1));
break;
default:
InvalidSizeError(Controller, Size);
break;
}
}
LIBFLANG_ABI void libflang_write_logical(WriteController *Controller, const void *Ptr, int32_t Size) {
SmallPrintf(Controller, "%s", getIntValue(Controller, Ptr, Size) != 0? "true" : "false");
}
LIBFLANG_ABI void libflang_write_character(WriteController *Controller, const char *Ptr, size_t Length) {
fwrite(Ptr, 1, Length, getFilePtr(Controller));
}
LIBFLANG_ABI void libflang_write_end(WriteController *Controller) {
fwrite("\n", 1, 1, getFilePtr(Controller));
}
|