These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / interface / efi / efi_strings.c
1 /*
2  * Copyright (C) 2011 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25
26 #include <stddef.h>
27 #include <stdarg.h>
28 #include <ipxe/vsprintf.h>
29 #include <ipxe/efi/efi_strings.h>
30
31 /** Context used by efi_vsnprintf() and friends */
32 struct efi_sputc_context {
33         /** printf context */
34         struct printf_context ctx;
35         /** Buffer for formatted string (used by efi_printf_sputc()) */
36         wchar_t *buf;
37         /** Buffer length (used by efi_printf_sputc())
38          *
39          * Note that this is a number of wide characters, not a number
40          * of bytes.
41          */
42         size_t max_wlen;
43 };
44
45 /**
46  * Write wide character to buffer
47  *
48  * @v ctx               Context
49  * @v c                 Character
50  */
51 static void efi_printf_sputc ( struct printf_context *ctx, unsigned int c ) {
52         struct efi_sputc_context * sctx =
53                 container_of ( ctx, struct efi_sputc_context, ctx );
54
55         if ( ctx->len < sctx->max_wlen )
56                 sctx->buf[ctx->len] = c;
57 }
58
59 /**
60  * Write a formatted string to a wide-character buffer
61  *
62  * @v wbuf              Buffer into which to write the string
63  * @v wsize             Size of buffer (in wide characters)
64  * @v fmt               Format string
65  * @v args              Arguments corresponding to the format string
66  * @ret wlen            Length of formatted string (in wide characters)
67  *
68  * If the buffer is too small to contain the string, the returned
69  * length is the length that would have been written had enough space
70  * been available.
71  */
72 int efi_vsnprintf ( wchar_t *wbuf, size_t wsize, const char *fmt,
73                     va_list args ) {
74         struct efi_sputc_context sctx;
75         size_t wlen;
76         size_t wend;
77
78         /* Hand off to vcprintf */
79         sctx.ctx.handler = efi_printf_sputc;
80         sctx.buf = wbuf;
81         sctx.max_wlen = wsize;
82         wlen = vcprintf ( &sctx.ctx, fmt, args );
83
84         /* Add trailing NUL */
85         if ( wsize ) {
86                 wend = wsize - 1;
87                 if ( wlen < wend )
88                         wend = wlen;
89                 wbuf[wend] = '\0';
90         }
91
92         return wlen;
93 }
94
95 /**
96  * Write a formatted string to a buffer
97  *
98  * @v wbuf              Buffer into which to write the string
99  * @v wsize             Size of buffer (in wide characters)
100  * @v fmt               Format string
101  * @v ...               Arguments corresponding to the format string
102  * @ret wlen            Length of formatted string (in wide characters)
103  */
104 int efi_snprintf ( wchar_t *wbuf, size_t wsize, const char *fmt, ... ) {
105         va_list args;
106         int i;
107
108         va_start ( args, fmt );
109         i = efi_vsnprintf ( wbuf, wsize, fmt, args );
110         va_end ( args );
111         return i;
112 }
113
114 /**
115  * Version of efi_vsnprintf() that accepts a signed buffer size
116  *
117  * @v wbuf              Buffer into which to write the string
118  * @v swsize            Size of buffer (in wide characters)
119  * @v fmt               Format string
120  * @v args              Arguments corresponding to the format string
121  * @ret wlen            Length of formatted string (in wide characters)
122  */
123 int efi_vssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt,
124                      va_list args ) {
125
126         /* Treat negative buffer size as zero buffer size */
127         if ( swsize < 0 )
128                 swsize = 0;
129
130         /* Hand off to vsnprintf */
131         return efi_vsnprintf ( wbuf, swsize, fmt, args );
132 }
133
134 /**
135  * Version of efi_vsnprintf() that accepts a signed buffer size
136  *
137  * @v wbuf              Buffer into which to write the string
138  * @v swsize            Size of buffer (in wide characters)
139  * @v fmt               Format string
140  * @v ...               Arguments corresponding to the format string
141  * @ret wlen            Length of formatted string (in wide characters)
142  */
143 int efi_ssnprintf ( wchar_t *wbuf, ssize_t swsize, const char *fmt, ... ) {
144         va_list args;
145         int len;
146
147         /* Hand off to vssnprintf */
148         va_start ( args, fmt );
149         len = efi_vssnprintf ( wbuf, swsize, fmt, args );
150         va_end ( args );
151         return len;
152 }