NAMD
imd.C
Go to the documentation of this file.
1 
2 
3 #include "imd.h"
4 #include "vmdsock.h"
5 #include <string.h>
6 #include <errno.h>
7 #include <stdlib.h>
8 
9 typedef struct {
12 } IMDheader;
13 
14 #define HEADERSIZE 8
15 
16 static void swap4(char *data, int ndata) {
17  int i;
18  char *dataptr;
19  char b0, b1;
20 
21  dataptr = data;
22  for (i=0; i<ndata; i+=4) {
23  b0 = dataptr[0];
24  b1 = dataptr[1];
25  dataptr[0] = dataptr[3];
26  dataptr[1] = dataptr[2];
27  dataptr[2] = b1;
28  dataptr[3] = b0;
29  dataptr += 4;
30  }
31 }
32 
34 typedef union {
36  struct {
37  unsigned int highest : 8;
38  unsigned int high : 8;
39  unsigned int low : 8;
40  unsigned int lowest : 8;
41  } b;
42 } netint;
43 
44 static int32 imd_htonl(int32 h) {
45  netint n;
46  n.b.highest = h >> 24;
47  n.b.high = h >> 16;
48  n.b.low = h >> 8;
49  n.b.lowest = h;
50  return n.i;
51 }
52 
53 static int32 imd_ntohl(int32 n) {
54  netint u;
55  u.i = n;
56  return (u.b.highest << 24 | u.b.high << 16 | u.b.low << 8 | u.b.lowest);
57 }
58 
59 static void fill_header(IMDheader *header, IMDType type, int32 length) {
60  header->type = imd_htonl((int32)type);
61  header->length = imd_htonl(length);
62 }
63 
64 static void swap_header(IMDheader *header) {
65  header->type = imd_ntohl(header->type);
66  header->length= imd_ntohl(header->length);
67 }
68 
69 static int32 imd_readn(void *s, char *ptr, int32 n) {
70  int32 nleft;
71  int32 nread;
72 
73  nleft = n;
74  while (nleft > 0) {
75  if ((nread = vmdsock_read(s, ptr, nleft)) < 0) {
76  if (errno == EINTR)
77  nread = 0; /* and call read() again */
78  else
79  return -1;
80  } else if (nread == 0)
81  break; /* EOF */
82  nleft -= nread;
83  ptr += nread;
84  }
85  return n-nleft;
86 }
87 
88 static int32 imd_writen(void *s, const char *ptr, int32 n) {
89  int32 nleft;
90  int32 nwritten;
91 
92  nleft = n;
93  while (nleft > 0) {
94  if ((nwritten = vmdsock_write(s, ptr, nleft)) <= 0) {
95  if (errno == EINTR)
96  nwritten = 0;
97  else
98  return -1;
99  }
100  nleft -= nwritten;
101  ptr += nwritten;
102  }
103  return n;
104 }
105 
106 
107 int imd_disconnect(void *s) {
108  IMDheader header;
109  fill_header(&header, IMD_DISCONNECT, 0);
110  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
111 }
112 
113 int imd_pause(void *s) {
114  IMDheader header;
115  fill_header(&header, IMD_PAUSE, 0);
116  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
117 }
118 
119 int imd_kill(void *s) {
120  IMDheader header;
121  fill_header(&header, IMD_KILL, 0);
122  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
123 }
124 
125 int imd_go(void *s) {
126  IMDheader header;
127  fill_header(&header, IMD_GO, 0);
128  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
129 }
130 
131 
132 int imd_handshake(void *s, const int IMDVersion) {
133  IMDheader header;
134  fill_header(&header, IMD_HANDSHAKE, 1);
135  header.length = IMDVersion; // Not byteswapped!
136  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
137 }
138 
139 int imd_trate(void *s, int32 rate) {
140  IMDheader header;
141  fill_header(&header, IMD_TRATE, rate);
142  return (imd_writen(s, (char *)&header, HEADERSIZE) != HEADERSIZE);
143 }
144 
145 // Data methods
146 
147 // Method to convert IMDSessionInfo into a std::vector<Type>
148 std::vector<char> toTypeVector(const IMDSessionInfo* info) {
149  std::vector<char> data;
150  data.push_back(static_cast<char>(info->time_switch));
151  data.push_back(static_cast<char>(info->energies_switch));
152  data.push_back(static_cast<char>(info->box_switch));
153  data.push_back(static_cast<char>(info->fcoords_switch));
154  data.push_back(static_cast<char>(info->wrap_switch));
155  data.push_back(static_cast<char>(info->velocities_switch));
156  data.push_back(static_cast<char>(info->forces_switch));
157  return data;
158 }
159 
160 int imd_sessioninfo(void *s, const IMDSessionInfo *info) {
161  std::vector<char> infoData = toTypeVector(info);
162  int32 size = HEADERSIZE+infoData.size()*sizeof(char);
163  char *buf = new char[size];
164  fill_header((IMDheader *)buf, IMD_SESSIONINFO, static_cast<int32>(infoData.size()));
165  memcpy((void *)(buf+HEADERSIZE), (const void *)(infoData.data()), infoData.size()*sizeof(char));
166  int rc = (imd_writen(s, buf, size) != size);
167  delete [] buf;
168  return rc;
169 }
170 
171 int imd_send_mdcomm(void *s,int32 n,const int32 *indices,const float *forces) {
172  int32 size = HEADERSIZE+16*n;
173  char *buf = new char[size];
174  fill_header((IMDheader *)buf, IMD_MDCOMM, n);
175  memcpy((void *)(buf+HEADERSIZE), (const void *)indices, 4*n);
176  memcpy((void *)(buf+HEADERSIZE+4*n), (const void *)forces, 12*n);
177  int rc = (imd_writen(s, buf, size) != size);
178  delete [] buf;
179  return rc;
180 }
181 
182 int imd_send_energies(void *s, const IMDEnergies *energies) {
183  int32 size = HEADERSIZE+sizeof(IMDEnergies);
184  char *buf = new char[size];
185  fill_header((IMDheader *)buf, IMD_ENERGIES, 1);
186  memcpy((void *)(buf+HEADERSIZE), (const void *)energies, sizeof(IMDEnergies));
187  int rc = (imd_writen(s, buf, size) != size);
188  delete [] buf;
189  return rc;
190 }
191 
192 int imd_send_fcoords(void *s, int32 n, const float *coords) {
193  int32 size = HEADERSIZE+12*n;
194  char *buf = new char[size];
195  fill_header((IMDheader *)buf, IMD_FCOORDS, n);
196  memcpy((void *)(buf+HEADERSIZE), (const void *)coords, 12*n);
197  int rc = (imd_writen(s, buf, size) != size);
198  delete [] buf;
199  return rc;
200 }
201 
202 int imd_send_velocities(void *s, int32 n, const float *vels) {
203  int32 size = HEADERSIZE+3*n*sizeof(float);
204  char *buf = new char[size];
206  memcpy((void *)(buf+HEADERSIZE), (const void *)vels, 3*n*sizeof(float));
207  int rc = (imd_writen(s, buf, size) != size);
208  delete [] buf;
209  return rc;
210 }
211 
212 int imd_send_forces(void *s, int32 n, const float *forces) {
213  int32 size = HEADERSIZE+3*n*sizeof(float);
214  char *buf = new char[size];
215  fill_header((IMDheader *)buf, IMD_FORCES, n);
216  memcpy((void *)(buf+HEADERSIZE), (const void *)forces, 3*n*sizeof(float));
217  int rc = (imd_writen(s, buf, size) != size);
218  delete [] buf;
219  return rc;
220 }
221 
222 int imd_send_box(void *s, const IMDBox *box) {
223  int32 size = HEADERSIZE+sizeof(IMDBox);
224  char *buf = new char[size];
225  fill_header((IMDheader *)buf, IMD_BOX, 1);
226  memcpy((void *)(buf+HEADERSIZE), (const void *)box, sizeof(IMDBox));
227  int rc = (imd_writen(s, buf, size) != size);
228  delete [] buf;
229  return rc;
230 }
231 
232 int imd_send_time(void *s, const IMDTime *time) {
233  int32 size = HEADERSIZE+sizeof(IMDTime);
234  char *buf = new char[size];
235  fill_header((IMDheader *)buf, IMD_TIME, 1);
236  memcpy((void *)(buf+HEADERSIZE), (const void *)time, sizeof(IMDTime));
237  int rc = (imd_writen(s, buf, size) != size);
238  delete [] buf;
239  return rc;
240 }
241 // The IMD receive functions
242 
243 // The IMD receive functions
245  IMDheader header;
246  if (imd_readn(s, (char *)&header, HEADERSIZE) != HEADERSIZE)
247  return IMD_IOERROR;
248  *length = header.length;
249  swap_header(&header);
250  return IMDType(header.type);
251 }
252 
253 int imd_recv_handshake(void *s) {
254  // Wait 5 seconds for the handshake to come
255  if (vmdsock_selread(s, 5) != 1) return -1;
256 
257  // Check to see that a valid handshake was received
258  int32 buf;
259  IMDType type = imd_recv_header_nolengthswap(s, &buf);
260  if (type != IMD_HANDSHAKE) return -1;
261 
262  // Check its endianness, as well as the IMD version.
263  if (buf == static_cast<int>(IMDversion_t::IMDv2)) {
264  if (!imd_go(s)) return 0;
265  return -1;
266  }
267  swap4((char *)&buf, 4);
268  if (buf == static_cast<int>(IMDversion_t::IMDv2)) {
269  if (!imd_go(s)) return 1;
270  }
271 
272  // We failed to determine endianness.
273  return -1;
274 }
275 
276 IMDType imd_recv_header(void *s, int32 *length) {
277  IMDheader header;
278  if (imd_readn(s, (char *)&header, HEADERSIZE) != HEADERSIZE)
279  return IMD_IOERROR;
280  int i;
281  char *ch = (char*)(&header);
282  swap_header(&header);
283  *length = header.length;
284  return IMDType(header.type);
285 }
286 
287 int imd_recv_mdcomm(void *s, int32 n, int32 *indices, float *forces) {
288  if (imd_readn(s, (char *)indices, 4*n) != 4*n) return 1;
289  if (imd_readn(s, (char *)forces, 12*n) != 12*n) return 1;
290  return 0;
291 }
292 
293 int imd_recv_energies(void *s, IMDEnergies *energies) {
294  return (imd_readn(s, (char *)energies, sizeof(IMDEnergies))
295  != sizeof(IMDEnergies));
296 }
297 
298 int imd_recv_fcoords(void *s, int32 n, float *coords) {
299  return (imd_readn(s, (char *)coords, 12*n) != 12*n);
300 }
301 
302 int imd_recv_velocities(void *s, int32 n, float *vels) {
303  return (imd_readn(s, (char *)vels, 12*n) != 12*n);
304 }
305 
306 int imd_recv_forces(void *s, int32 n, float *forces) {
307  return (imd_readn(s, (char *)forces, 12*n) != 12*n);
308 }
309 
310 int imd_recv_box(void *s, IMDBox *box) {
311  return (imd_readn(s, (char *)box, sizeof(IMDBox)) != sizeof(IMDBox));
312 }
313 
314 int imd_recv_time(void *s, IMDTime *time) {
315  return (imd_readn(s, (char *)time, sizeof(IMDTime)) != sizeof(IMDTime));
316 }
317 
static int32 imd_writen(void *s, const char *ptr, int32 n)
Definition: imd.C:88
static void fill_header(IMDheader *header, IMDType type, int32 length)
Definition: imd.C:59
Definition: imd.C:9
int imd_send_mdcomm(void *s, int32 n, const int32 *indices, const float *forces)
Definition: imd.C:171
int vmdsock_selread(void *v, int sec)
Definition: vmdsock.C:177
IMDType imd_recv_header_nolengthswap(void *s, int32 *length)
Definition: imd.C:244
structure used to perform byte swapping operations
Definition: imd.C:34
int imd_send_energies(void *s, const IMDEnergies *energies)
Definition: imd.C:182
int imd_recv_forces(void *s, int32 n, float *forces)
Definition: imd.C:306
int32_t int32
Definition: common.h:38
int imd_recv_time(void *s, IMDTime *time)
Definition: imd.C:314
#define HEADERSIZE
Definition: imd.C:14
int32 i
Definition: imd.C:35
int imd_send_box(void *s, const IMDBox *box)
Definition: imd.C:222
unsigned int low
Definition: imd.C:39
Definition: imd.h:19
int wrap_switch
Definition: imd.h:66
Definition: imd.h:22
static int32 imd_ntohl(int32 n)
Definition: imd.C:53
struct netint::@50 b
IMDType
Definition: imd.h:15
static void swap4(char *data, int ndata)
Definition: imd.C:16
int imd_trate(void *s, int32 rate)
Definition: imd.C:139
int imd_pause(void *s)
Definition: imd.C:113
static int32 imd_htonl(int32 h)
Definition: imd.C:44
int imd_go(void *s)
Definition: imd.C:125
Definition: imd.h:32
Definition: imd.h:55
int imd_send_fcoords(void *s, int32 n, const float *coords)
Definition: imd.C:192
unsigned int lowest
Definition: imd.C:40
int imd_recv_velocities(void *s, int32 n, float *vels)
Definition: imd.C:302
static void swap_header(IMDheader *header)
Definition: imd.C:64
unsigned int high
Definition: imd.C:38
int imd_send_forces(void *s, int32 n, const float *forces)
Definition: imd.C:212
int imd_recv_fcoords(void *s, int32 n, float *coords)
Definition: imd.C:298
int imd_send_time(void *s, const IMDTime *time)
Definition: imd.C:232
int time_switch
Definition: imd.h:62
int imd_recv_mdcomm(void *s, int32 n, int32 *indices, float *forces)
Definition: imd.C:287
int imd_sessioninfo(void *s, const IMDSessionInfo *info)
Definition: imd.C:160
static int32 imd_readn(void *s, char *ptr, int32 n)
Definition: imd.C:69
Definition: imd.h:24
int box_switch
Definition: imd.h:64
Definition: imd.h:49
int imd_handshake(void *s, const int IMDVersion)
Definition: imd.C:132
Definition: imd.h:30
int imd_disconnect(void *s)
Definition: imd.C:107
int fcoords_switch
Definition: imd.h:65
int velocities_switch
Definition: imd.h:67
std::vector< char > toTypeVector(const IMDSessionInfo *info)
Definition: imd.C:148
int32 length
Definition: imd.C:11
int imd_recv_handshake(void *s)
Receive header and data.
Definition: imd.C:253
int imd_kill(void *s)
Definition: imd.C:119
int forces_switch
Definition: imd.h:68
int vmdsock_write(void *v, const void *buf, int len)
Definition: vmdsock.C:145
Definition: imd.h:23
Definition: imd.h:29
int imd_recv_energies(void *s, IMDEnergies *energies)
Definition: imd.C:293
Definition: common.h:275
unsigned int highest
Definition: imd.C:37
Definition: imd.h:21
IMDType imd_recv_header(void *s, int32 *length)
Definition: imd.C:276
int imd_recv_box(void *s, IMDBox *box)
Definition: imd.C:310
int energies_switch
Definition: imd.h:63
int32 type
Definition: imd.C:10
static float * coords
Definition: ScriptTcl.C:67
int vmdsock_read(void *v, void *buf, int len)
Definition: vmdsock.C:154
int imd_send_velocities(void *s, int32 n, const float *vels)
Definition: imd.C:202