00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00035 #include <stdarg.h>
00036 #include <stdio.h>
00037 #include <str.h>
00038 #include <io/printf_core.h>
00039 #include <errno.h>
00040
00041 typedef struct {
00042 size_t size;
00043 size_t len;
00044 char *dst;
00045 } vsnprintf_data_t;
00046
00064 static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data)
00065 {
00066 size_t left = data->size - data->len;
00067
00068 if (left == 0)
00069 return ((int) size);
00070
00071 if (left == 1) {
00072
00073
00074
00075 data->dst[data->size - 1] = 0;
00076 data->len = data->size;
00077 return ((int) size);
00078 }
00079
00080 if (left <= size) {
00081
00082
00083
00084
00085 size_t index = 0;
00086
00087 while (index < size) {
00088 wchar_t uc = str_decode(str, &index, size);
00089
00090 if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
00091 break;
00092 }
00093
00094
00095
00096
00097 data->dst[data->len] = 0;
00098
00099 return ((int) size);
00100 }
00101
00102
00103 memcpy((void *)(data->dst + data->len), (void *) str, size);
00104 data->len += size;
00105
00106
00107
00108
00109 data->dst[data->len] = 0;
00110
00111 return ((int) size);
00112 }
00113
00131 static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
00132 {
00133 size_t index = 0;
00134
00135 while (index < (size / sizeof(wchar_t))) {
00136 size_t left = data->size - data->len;
00137
00138 if (left == 0)
00139 return ((int) size);
00140
00141 if (left == 1) {
00142
00143
00144
00145 data->dst[data->size - 1] = 0;
00146 data->len = data->size;
00147 return ((int) size);
00148 }
00149
00150 if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK)
00151 break;
00152
00153 index++;
00154 }
00155
00156
00157
00158
00159 data->dst[data->len] = 0;
00160
00161 return ((int) size);
00162 }
00163
00164 int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
00165 {
00166 vsnprintf_data_t data = {
00167 size,
00168 0,
00169 str
00170 };
00171 printf_spec_t ps = {
00172 (int(*) (const char *, size_t, void *)) vsnprintf_str_write,
00173 (int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
00174 &data
00175 };
00176
00177
00178 if (size > 0)
00179 str[0] = 0;
00180
00181
00182 return printf_core(fmt, &ps, ap);
00183 }
00184