~yves-pelletier/libecbufr/documentation

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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/***
Copyright Her Majesty The Queen in Right of Canada, Environment Canada, 2009.
Copyright Sa Majesté la Reine du Chef du Canada, Environnement Canada, 2009.

This file is part of libECBUFR.

    libECBUFR is free software: you can redistribute it and/or modify
    it under the terms of the Lesser GNU General Public License,
    version 3, as published by the Free Software Foundation.

    libECBUFR is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    Lesser GNU General Public License for more details.

    You should have received a copy of the Lesser GNU General Public
    License along with libECBUFR.  If not, see <http://www.gnu.org/licenses/>.

 * fichier:  bufr_sio.c
 *
 * author:  Vanh Souvanlasy (avril 1996)
 *
 * function: for writing or reading BUFR message through a file descriptor
 *
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>

#include "bufr_api.h"
#include "bufr_io.h"
#include "bufr_message.h"

/**
 * @english
 * internal callback to write to a byte-oriented buffer sink
 * @param     client_data : file descriptor to output file or socket stream
 * @param     len : number of bytes to write
 * @param     buffer : data buffer to write from
 * @return     number of bytes written. Zero or negative means
 *      some kind of error.
 * @endenglish
 * @francais
 * @todo translate to French
 * @endfrancais
 * @author Chris Beauregard
 * @ingroup internal
 */
static ssize_t bufr_swrite_fn( void *client_data, size_t len,
                               const char *buffer)
	{
	/* write to a file descriptor, handling short writes correctly */
	int wrote = 0;
	while( len > 0 )
		{
		ssize_t rc = write( (int) client_data, buffer, len );
		if( rc <= 0 )
			{
			/* EAGAIN happens when non-blocking I/O is used, EINTR
			 * happens when a signal triggers. Neither of them should
			 * interrupt writing.
			 */
			if( errno != EINTR && errno != EAGAIN ) break;
			errno = 0;
			continue;
			}
		wrote += rc;
		len -= rc;
		buffer += rc;
		}
	return wrote;
	}

/**
 * @english
 * write a BUFR message sections into a file descriptor or socket
 *           stream
 * @param     fd   : file descriptor opened for writing
 * @param     bufr : pointer to BUFR data structure
 * @endenglish
 * @francais
 * @todo translate to French
 * @endfrancais
 * @author Vanh Souvanlasy
 * @ingroup internal
 */
int bufr_swrite_message(int  fd, BUFR_Message *bufr)
   {
		return bufr_callback_write_message( bufr_swrite_fn, (void*) fd, bufr );
   }

/**
 * bufr_sread_fn
 * @english
 * internal callback to read from a byte-oriented buffer source
 * @param     client_data : file descriptor to input file or socket stream
 * @param     len : number of bytes to read
 * @param     buffer : data buffer to read into
 * @return     number of bytes read. Zero means end-of-file, negative means
 *      some kind of error.
 * @endenglish
 * @francais
 * @todo translate to French
 * @endfrancais
 * @author Chris Beauregard
 * @ingroup internal
 */
static ssize_t bufr_sread_fn( void* client_data, size_t len, char* buffer )
	{
	/* read from a file descriptor, handling short reads correctly */
	int got = 0;
	while( len > 0 )
		{
		ssize_t rc = read( (int) client_data, buffer, len );
		if( rc == 0 ) break;	/* end-of-file */
		if( rc < 0 )
			{
			/* EAGAIN happens when non-blocking I/O is used, EINTR
			 * happens when a signal triggers. Neither of them should
			 * interrupt reading.
			 */
			if( errno != EINTR && errno != EAGAIN ) break;
			errno = 0;
			continue;
			}
		got += rc;
		len -= rc;
		buffer += rc;
		}
	return got;
	}

/**
 * @english
 * read a BUFR report from a socket
 * @param     fd   : file descriptor to input file or socket stream
 * @endenglish
 * @francais
 * @todo translate to French
 * @endfrancais
 * @author Vanh Souvanlasy
 * @ingroup bufr_sio.c

 */
int bufr_sread_message( int fd, BUFR_Message **rtrn )
   {
	return bufr_callback_read_message( bufr_sread_fn, (void*) fd, rtrn );
   }