Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
pirms 10 gadiem
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  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 <ctype.h>
  21. #include <float.h>
  22. #include <ctype.h>
  23. #include "istream.h"
  24. //------------------------------------------------------------------------------
  25. int istream::get() {
  26. int c;
  27. m_gcount = 0;
  28. c = getch();
  29. if (c < 0) {
  30. setstate(failbit);
  31. } else {
  32. m_gcount = 1;
  33. }
  34. return c;
  35. }
  36. //------------------------------------------------------------------------------
  37. istream& istream::get(char& c) {
  38. int tmp = get();
  39. if (tmp >= 0) {
  40. c = tmp;
  41. }
  42. return *this;
  43. }
  44. //------------------------------------------------------------------------------
  45. istream& istream::get(char *str, streamsize n, char delim) {
  46. int c;
  47. FatPos_t pos;
  48. m_gcount = 0;
  49. while ((m_gcount + 1) < n) {
  50. c = getch(&pos);
  51. if (c < 0) {
  52. break;
  53. }
  54. if (c == delim) {
  55. setpos(&pos);
  56. break;
  57. }
  58. str[m_gcount++] = c;
  59. }
  60. if (n > 0) {
  61. str[m_gcount] = '\0';
  62. }
  63. if (m_gcount == 0) {
  64. setstate(failbit);
  65. }
  66. return *this;
  67. }
  68. //------------------------------------------------------------------------------
  69. void istream::getBool(bool *b) {
  70. if ((flags() & boolalpha) == 0) {
  71. getNumber(b);
  72. return;
  73. }
  74. PGM_P truePtr = PSTR("true");
  75. PGM_P falsePtr = PSTR("false");
  76. const uint8_t true_len = 4;
  77. const uint8_t false_len = 5;
  78. bool trueOk = true;
  79. bool falseOk = true;
  80. uint8_t i = 0;
  81. int c = readSkip();
  82. while (1) {
  83. falseOk = falseOk && c == pgm_read_byte(falsePtr + i);
  84. trueOk = trueOk && c == pgm_read_byte(truePtr + i);
  85. if (trueOk == false && falseOk == false) {
  86. break;
  87. }
  88. i++;
  89. if (trueOk && i == true_len) {
  90. *b = true;
  91. return;
  92. }
  93. if (falseOk && i == false_len) {
  94. *b = false;
  95. return;
  96. }
  97. c = getch();
  98. }
  99. setstate(failbit);
  100. }
  101. //------------------------------------------------------------------------------
  102. void istream::getChar(char* ch) {
  103. int16_t c = readSkip();
  104. if (c < 0) {
  105. setstate(failbit);
  106. } else {
  107. *ch = c;
  108. }
  109. }
  110. //------------------------------------------------------------------------------
  111. //
  112. // http://www.exploringbinary.com/category/numbers-in-computers/
  113. //
  114. int16_t const EXP_LIMIT = 100;
  115. static const uint32_t uint32_max = (uint32_t)-1;
  116. bool istream::getDouble(double* value) {
  117. bool got_digit = false;
  118. bool got_dot = false;
  119. bool neg;
  120. int16_t c;
  121. bool expNeg = false;
  122. int16_t exp = 0;
  123. int16_t fracExp = 0;
  124. uint32_t frac = 0;
  125. FatPos_t endPos;
  126. double pow10;
  127. double v;
  128. getpos(&endPos);
  129. c = readSkip();
  130. neg = c == '-';
  131. if (c == '-' || c == '+') {
  132. c = getch();
  133. }
  134. while (1) {
  135. if (isdigit(c)) {
  136. got_digit = true;
  137. if (frac < uint32_max/10) {
  138. frac = frac * 10 + (c - '0');
  139. if (got_dot) {
  140. fracExp--;
  141. }
  142. } else {
  143. if (!got_dot) {
  144. fracExp++;
  145. }
  146. }
  147. } else if (!got_dot && c == '.') {
  148. got_dot = true;
  149. } else {
  150. break;
  151. }
  152. if (fracExp < -EXP_LIMIT || fracExp > EXP_LIMIT) {
  153. goto fail;
  154. }
  155. c = getch(&endPos);
  156. }
  157. if (!got_digit) {
  158. goto fail;
  159. }
  160. if (c == 'e' || c == 'E') {
  161. c = getch();
  162. expNeg = c == '-';
  163. if (c == '-' || c == '+') {
  164. c = getch();
  165. }
  166. while (isdigit(c)) {
  167. if (exp > EXP_LIMIT) {
  168. goto fail;
  169. }
  170. exp = exp * 10 + (c - '0');
  171. c = getch(&endPos);
  172. }
  173. }
  174. v = static_cast<double>(frac);
  175. exp = expNeg ? fracExp - exp : fracExp + exp;
  176. expNeg = exp < 0;
  177. if (expNeg) {
  178. exp = -exp;
  179. }
  180. pow10 = 10.0;
  181. while (exp) {
  182. if (exp & 1) {
  183. if (expNeg) {
  184. // check for underflow
  185. if (v < FLT_MIN * pow10 && frac != 0) {
  186. goto fail;
  187. }
  188. v /= pow10;
  189. } else {
  190. // check for overflow
  191. if (v > FLT_MAX / pow10) {
  192. goto fail;
  193. }
  194. v *= pow10;
  195. }
  196. }
  197. pow10 *= pow10;
  198. exp >>= 1;
  199. }
  200. setpos(&endPos);
  201. *value = neg ? -v : v;
  202. return true;
  203. fail:
  204. // error restore position to last good place
  205. setpos(&endPos);
  206. setstate(failbit);
  207. return false;
  208. }
  209. //------------------------------------------------------------------------------
  210. istream& istream::getline(char *str, streamsize n, char delim) {
  211. FatPos_t pos;
  212. int c;
  213. m_gcount = 0;
  214. if (n > 0) {
  215. str[0] = '\0';
  216. }
  217. while (1) {
  218. c = getch(&pos);
  219. if (c < 0) {
  220. break;
  221. }
  222. if (c == delim) {
  223. m_gcount++;
  224. break;
  225. }
  226. if ((m_gcount + 1) >= n) {
  227. setpos(&pos);
  228. setstate(failbit);
  229. break;
  230. }
  231. str[m_gcount++] = c;
  232. str[m_gcount] = '\0';
  233. }
  234. if (m_gcount == 0) {
  235. setstate(failbit);
  236. }
  237. return *this;
  238. }
  239. //------------------------------------------------------------------------------
  240. bool istream::getNumber(uint32_t posMax, uint32_t negMax, uint32_t* num) {
  241. int16_t c;
  242. int8_t any = 0;
  243. int8_t have_zero = 0;
  244. uint8_t neg;
  245. uint32_t val = 0;
  246. uint32_t cutoff;
  247. uint8_t cutlim;
  248. FatPos_t endPos;
  249. uint8_t f = flags() & basefield;
  250. uint8_t base = f == oct ? 8 : f != hex ? 10 : 16;
  251. getpos(&endPos);
  252. c = readSkip();
  253. neg = c == '-' ? 1 : 0;
  254. if (c == '-' || c == '+') {
  255. c = getch();
  256. }
  257. if (base == 16 && c == '0') { // TESTSUITE
  258. c = getch(&endPos);
  259. if (c == 'X' || c == 'x') {
  260. c = getch();
  261. // remember zero in case no hex digits follow x/X
  262. have_zero = 1;
  263. } else {
  264. any = 1;
  265. }
  266. }
  267. // set values for overflow test
  268. cutoff = neg ? negMax : posMax;
  269. cutlim = cutoff % base;
  270. cutoff /= base;
  271. while (1) {
  272. if (isdigit(c)) {
  273. c -= '0';
  274. } else if (isalpha(c)) {
  275. c -= isupper(c) ? 'A' - 10 : 'a' - 10;
  276. } else {
  277. break;
  278. }
  279. if (c >= base) {
  280. break;
  281. }
  282. if (val > cutoff || (val == cutoff && c > cutlim)) {
  283. // indicate overflow error
  284. any = -1;
  285. break;
  286. }
  287. val = val * base + c;
  288. c = getch(&endPos);
  289. any = 1;
  290. }
  291. setpos(&endPos);
  292. if (any > 0 || (have_zero && any >= 0)) {
  293. *num = neg ? -val : val;
  294. return true;
  295. }
  296. setstate(failbit);
  297. return false;
  298. }
  299. //------------------------------------------------------------------------------
  300. void istream::getStr(char *str) {
  301. FatPos_t pos;
  302. uint16_t i = 0;
  303. uint16_t m = width() ? width() - 1 : 0XFFFE;
  304. if (m != 0) {
  305. getpos(&pos);
  306. int c = readSkip();
  307. while (i < m) {
  308. if (c < 0) {
  309. break;
  310. }
  311. if (isspace(c)) {
  312. setpos(&pos);
  313. break;
  314. }
  315. str[i++] = c;
  316. c = getch(&pos);
  317. }
  318. }
  319. str[i] = '\0';
  320. if (i == 0) {
  321. setstate(failbit);
  322. }
  323. width(0);
  324. }
  325. //------------------------------------------------------------------------------
  326. istream& istream::ignore(streamsize n, int delim) {
  327. int c;
  328. m_gcount = 0;
  329. while (m_gcount < n) {
  330. c = getch();
  331. if (c < 0) {
  332. break;
  333. }
  334. m_gcount++;
  335. if (c == delim) {
  336. break;
  337. }
  338. }
  339. return *this;
  340. }
  341. //------------------------------------------------------------------------------
  342. int istream::peek() {
  343. int16_t c;
  344. FatPos_t pos;
  345. m_gcount = 0;
  346. getpos(&pos);
  347. c = getch();
  348. if (c < 0) {
  349. if (!bad()) {
  350. setstate(eofbit);
  351. }
  352. } else {
  353. setpos(&pos);
  354. }
  355. return c;
  356. }
  357. //------------------------------------------------------------------------------
  358. int16_t istream::readSkip() {
  359. int16_t c;
  360. do {
  361. c = getch();
  362. } while (isspace(c) && (flags() & skipws));
  363. return c;
  364. }
  365. //------------------------------------------------------------------------------
  366. /** used to implement ws() */
  367. void istream::skipWhite() {
  368. int c;
  369. FatPos_t pos;
  370. do {
  371. c = getch(&pos);
  372. } while (isspace(c));
  373. setpos(&pos);
  374. }