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