You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
преди 10 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /* FatLib Library
  2. * Copyright (C) 2013 by William Greiman
  3. *
  4. * This file is part of the FatLib Library
  5. *
  6. * This Library is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This Library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with the FatLib Library. If not, see
  18. * <http://www.gnu.org/licenses/>.
  19. */
  20. #include <string.h>
  21. #include "ostream.h"
  22. #ifndef PSTR
  23. #define PSTR(x) x
  24. #endif
  25. //------------------------------------------------------------------------------
  26. void ostream::do_fill(unsigned len) {
  27. for (; len < width(); len++) {
  28. putch(fill());
  29. }
  30. width(0);
  31. }
  32. //------------------------------------------------------------------------------
  33. void ostream::fill_not_left(unsigned len) {
  34. if ((flags() & adjustfield) != left) {
  35. do_fill(len);
  36. }
  37. }
  38. //------------------------------------------------------------------------------
  39. char* ostream::fmtNum(uint32_t n, char *ptr, uint8_t base) {
  40. char a = flags() & uppercase ? 'A' - 10 : 'a' - 10;
  41. do {
  42. uint32_t m = n;
  43. n /= base;
  44. char c = m - base * n;
  45. *--ptr = c < 10 ? c + '0' : c + a;
  46. } while (n);
  47. return ptr;
  48. }
  49. //------------------------------------------------------------------------------
  50. void ostream::putBool(bool b) {
  51. if (flags() & boolalpha) {
  52. if (b) {
  53. putPgm(PSTR("true"));
  54. } else {
  55. putPgm(PSTR("false"));
  56. }
  57. } else {
  58. putChar(b ? '1' : '0');
  59. }
  60. }
  61. //------------------------------------------------------------------------------
  62. void ostream::putChar(char c) {
  63. fill_not_left(1);
  64. putch(c);
  65. do_fill(1);
  66. }
  67. //------------------------------------------------------------------------------
  68. void ostream::putDouble(double n) {
  69. uint8_t nd = precision();
  70. double round = 0.5;
  71. char sign;
  72. char buf[13]; // room for sign, 10 digits, '.', and zero byte
  73. char *end = buf + sizeof(buf) - 1;
  74. char *str = end;
  75. // terminate string
  76. *end = '\0';
  77. // get sign and make nonnegative
  78. if (n < 0.0) {
  79. sign = '-';
  80. n = -n;
  81. } else {
  82. sign = flags() & showpos ? '+' : '\0';
  83. }
  84. // check for larger than uint32_t
  85. if (n > 4.0E9) {
  86. putPgm(PSTR("BIG FLT"));
  87. return;
  88. }
  89. // round up and separate int and fraction parts
  90. for (uint8_t i = 0; i < nd; ++i) {
  91. round *= 0.1;
  92. }
  93. n += round;
  94. uint32_t intPart = n;
  95. double fractionPart = n - intPart;
  96. // format intPart and decimal point
  97. if (nd || (flags() & showpoint)) {
  98. *--str = '.';
  99. }
  100. str = fmtNum(intPart, str, 10);
  101. // calculate length for fill
  102. uint8_t len = sign ? 1 : 0;
  103. len += nd + end - str;
  104. // extract adjust field
  105. fmtflags adj = flags() & adjustfield;
  106. if (adj == internal) {
  107. if (sign) {
  108. putch(sign);
  109. }
  110. do_fill(len);
  111. } else {
  112. // do fill for internal or right
  113. fill_not_left(len);
  114. if (sign) {
  115. *--str = sign;
  116. }
  117. }
  118. putstr(str);
  119. // output fraction
  120. while (nd-- > 0) {
  121. fractionPart *= 10.0;
  122. int digit = static_cast<int>(fractionPart);
  123. putch(digit + '0');
  124. fractionPart -= digit;
  125. }
  126. // do fill if not done above
  127. do_fill(len);
  128. }
  129. //------------------------------------------------------------------------------
  130. void ostream::putNum(int32_t n) {
  131. bool neg = n < 0 && flagsToBase() == 10;
  132. if (neg) {
  133. n = -n;
  134. }
  135. putNum(n, neg);
  136. }
  137. //------------------------------------------------------------------------------
  138. void ostream::putNum(uint32_t n, bool neg) {
  139. char buf[13];
  140. char* end = buf + sizeof(buf) - 1;
  141. char* num;
  142. char* str;
  143. uint8_t base = flagsToBase();
  144. *end = '\0';
  145. str = num = fmtNum(n, end, base);
  146. if (base == 10) {
  147. if (neg) {
  148. *--str = '-';
  149. } else if (flags() & showpos) {
  150. *--str = '+';
  151. }
  152. } else if (flags() & showbase) {
  153. if (flags() & hex) {
  154. *--str = flags() & uppercase ? 'X' : 'x';
  155. }
  156. *--str = '0';
  157. }
  158. uint8_t len = end - str;
  159. fmtflags adj = flags() & adjustfield;
  160. if (adj == internal) {
  161. while (str < num) {
  162. putch(*str++);
  163. }
  164. }
  165. if (adj != left) {
  166. do_fill(len);
  167. }
  168. putstr(str);
  169. do_fill(len);
  170. }
  171. //------------------------------------------------------------------------------
  172. void ostream::putPgm(const char* str) {
  173. int n;
  174. for (n = 0; pgm_read_byte(&str[n]); n++) {}
  175. fill_not_left(n);
  176. for (uint8_t c; (c = pgm_read_byte(str)); str++) {
  177. putch(c);
  178. }
  179. do_fill(n);
  180. }
  181. //------------------------------------------------------------------------------
  182. void ostream::putStr(const char *str) {
  183. unsigned n = strlen(str);
  184. fill_not_left(n);
  185. putstr(str);
  186. do_fill(n);
  187. }