Changeset f2b8cdc in mainline for uspace/lib/libc/generic/io/vsnprintf.c
- Timestamp:
- 2009-04-04T22:04:28Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade
- Children:
- b27eb71
- Parents:
- 4527fb5
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libc/generic/io/vsnprintf.c
r4527fb5 rf2b8cdc 37 37 #include <string.h> 38 38 #include <io/printf_core.h> 39 #include <errno.h> 39 40 40 struct vsnprintf_data{41 size_t size; /* total space for string*/42 size_t len; /* count of currently used characters */43 char * string; /* destination string*/44 } ;41 typedef struct { 42 size_t size; /* Total size of the buffer (in bytes) */ 43 size_t len; /* Number of already used bytes */ 44 char *dst; /* Destination */ 45 } vsnprintf_data_t; 45 46 46 47 /** Write string to given buffer. 47 * Write at most data->size characters including trailing zero. According to C9948 * has snprintf to return number of characters that would have been written if49 * enough space had been available. Hence the return value is not number of50 * really printed characters but size of input string. Number of really used51 * characters is stored in data->len.52 48 * 53 * @param str Source string to print. 54 * @param count Size of the source string. 55 * @param data Structure with destination string, counter of used space 56 * and total string size. 57 * @return Number of characters to print (not characters really 58 * printed!) 49 * Write at most data->size plain characters including trailing zero. 50 * According to C99, snprintf() has to return number of characters that 51 * would have been written if enough space had been available. Hence 52 * the return value is not the number of actually printed characters 53 * but size of the input string. 54 * 55 * @param str Source string to print. 56 * @param size Number of plain characters in str. 57 * @param data Structure describing destination string, counter 58 * of used space and total string size. 59 * 60 * @return Number of characters to print (not characters actually 61 * printed). 62 * 59 63 */ 60 static int 61 vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) 64 static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data) 62 65 { 63 size_t i; 64 i = data->size - data->len; 65 66 if (i == 0) { 67 return count; 66 size_t left = data->size - data->len; 67 68 if (left == 0) 69 return ((int) size); 70 71 if (left == 1) { 72 /* We have only one free byte left in buffer 73 * -> store trailing zero 74 */ 75 data->dst[data->size - 1] = 0; 76 data->len = data->size; 77 return ((int) size); 68 78 } 69 79 70 if ( i == 1) {71 /* 72 * We have only one free byte left in buffer => write there73 * trailing zero.80 if (left <= size) { 81 /* We do not have enough space for the whole string 82 * with the trailing zero => print only a part 83 * of string 74 84 */ 75 data->string[data->size - 1] = 0; 76 data->len = data->size; 77 return count; 85 index_t index = 0; 86 87 while (index < size) { 88 wchar_t uc = str_decode(str, &index, size); 89 90 if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK) 91 break; 92 } 93 94 /* Put trailing zero at end, but not count it 95 * into data->len so it could be rewritten next time 96 */ 97 data->dst[data->len] = 0; 98 99 return ((int) size); 78 100 } 79 101 80 if (i <= count) { 81 /* 82 * We have not enought space for whole string with the trailing 83 * zero => print only a part of string. 84 */ 85 memcpy((void *)(data->string + data->len), (void *)str, i - 1); 86 data->string[data->size - 1] = 0; 87 data->len = data->size; 88 return count; 102 /* Buffer is big enought to print the whole string */ 103 memcpy((void *)(data->dst + data->len), (void *) str, size); 104 data->len += size; 105 106 /* Put trailing zero at end, but not count it 107 * into data->len so it could be rewritten next time 108 */ 109 data->dst[data->len] = 0; 110 111 return ((int) size); 112 } 113 114 /** Write wide string to given buffer. 115 * 116 * Write at most data->size plain characters including trailing zero. 117 * According to C99, snprintf() has to return number of characters that 118 * would have been written if enough space had been available. Hence 119 * the return value is not the number of actually printed characters 120 * but size of the input string. 121 * 122 * @param str Source wide string to print. 123 * @param size Number of bytes in str. 124 * @param data Structure describing destination string, counter 125 * of used space and total string size. 126 * 127 * @return Number of wide characters to print (not characters actually 128 * printed). 129 * 130 */ 131 static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data) 132 { 133 index_t index = 0; 134 135 while (index < (size / sizeof(wchar_t))) { 136 size_t left = data->size - data->len; 137 138 if (left == 0) 139 return ((int) size); 140 141 if (left == 1) { 142 /* We have only one free byte left in buffer 143 * -> store trailing zero 144 */ 145 data->dst[data->size - 1] = 0; 146 data->len = data->size; 147 return ((int) size); 148 } 149 150 if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK) 151 break; 152 153 index++; 89 154 } 90 155 91 /* Buffer is big enought to print whole string */ 92 memcpy((void *)(data->string + data->len), (void *)str, count); 93 data->len += count; 94 /* 95 * Put trailing zero at end, but not count it into data->len so it could 96 * be rewritten next time. 156 /* Put trailing zero at end, but not count it 157 * into data->len so it could be rewritten next time 97 158 */ 98 data-> string[data->len] = 0;99 100 return count;159 data->dst[data->len] = 0; 160 161 return ((int) size); 101 162 } 102 163 103 /** Print formatted to the given buffer with limited size.104 * @param str Buffer.105 * @param size Bffer size.106 * @param fmt Format string.107 * \see For more details about format string see printf_core.108 */109 164 int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) 110 165 { 111 struct vsnprintf_data data = {size, 0, str}; 112 struct printf_spec ps = { 113 (int(*)(void *, size_t, void *)) vsnprintf_write, 166 vsnprintf_data_t data = { 167 size, 168 0, 169 str 170 }; 171 printf_spec_t ps = { 172 (int(*) (const char *, size_t, void *)) vsnprintf_str_write, 173 (int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write, 114 174 &data 115 175 }; 116 117 /* 118 * Print 0 at end of string - fix the case that nothing will be printed. 119 */ 176 177 /* Print 0 at end of string - fix the case that nothing will be printed */ 120 178 if (size > 0) 121 179 str[0] = 0;
Note:
See TracChangeset
for help on using the changeset viewer.