/NULLC/includes/io.cpp

https://code.google.com/p/nullc/ · C++ · 248 lines · 214 code · 33 blank · 1 comment · 21 complexity · a6cbd78a2a7ddfb53ccc3f089d11ead7 MD5 · raw file

  1. #include "io.h"
  2. #include "../../NULLC/nullc.h"
  3. #if defined(_MSC_VER)
  4. #include <windows.h>
  5. #endif
  6. #include <stdio.h>
  7. #include <string.h>
  8. #if defined(_MSC_VER)
  9. #pragma warning(disable: 4996)
  10. #endif
  11. namespace NULLCIO
  12. {
  13. void InitConsole()
  14. {
  15. #if defined(_MSC_VER)
  16. AllocConsole();
  17. freopen("CONOUT$", "w", stdout);
  18. freopen("CONIN$", "r", stdin);
  19. #endif
  20. }
  21. void DeInitConsole()
  22. {
  23. #if defined(_MSC_VER)
  24. FreeConsole();
  25. #endif
  26. }
  27. int abs(int x){ return x < 0 ? -x : x; }
  28. void WriteToConsole(NULLCArray data)
  29. {
  30. InitConsole();
  31. // Empty arrays are silently ignored
  32. if(!data.ptr)
  33. return;
  34. printf("%.*s", data.len, data.ptr);
  35. }
  36. void WriteLongConsole(long long number, int base)
  37. {
  38. InitConsole();
  39. if(!(base > 1 && base <= 16))
  40. {
  41. nullcThrowError("ERROR: incorrect base %d", base);
  42. return;
  43. }
  44. static char symb[] = "0123456789abcdef";
  45. bool sign = 0;
  46. char buf[128];
  47. char *curr = buf;
  48. if(number < 0)
  49. sign = 1;
  50. *curr++ = *(abs(number % base) + symb);
  51. while(number /= base)
  52. *curr++ = *(abs(number % base) + symb);
  53. if(sign)
  54. *curr++ = '-';
  55. *curr = 0;
  56. int size = int(curr - buf), halfsize = size >> 1;
  57. for(int i = 0; i < halfsize; i++)
  58. {
  59. char tmp = buf[i];
  60. buf[i] = buf[size-i-1];
  61. buf[size-i-1] = tmp;
  62. }
  63. printf("%s", buf);
  64. }
  65. void WriteIntConsole(int number, int base)
  66. {
  67. WriteLongConsole(number, base);
  68. }
  69. void WriteDoubleConsole(double num, int precision)
  70. {
  71. InitConsole();
  72. printf("%.*f", precision, num);
  73. }
  74. void WriteCharConsole(char ch)
  75. {
  76. InitConsole();
  77. printf("%c", ch);
  78. }
  79. void ReadIntFromConsole(int* val)
  80. {
  81. if(!val)
  82. {
  83. nullcThrowError("ERROR: argument should not be a nullptr");
  84. return;
  85. }
  86. InitConsole();
  87. scanf("%d", val);
  88. }
  89. int ReadTextFromConsole(NULLCArray data)
  90. {
  91. char buffer[2048];
  92. if(!data.ptr)
  93. {
  94. nullcThrowError("ERROR: argument should not be a nullptr");
  95. return 0;
  96. }
  97. InitConsole();
  98. if(fgets(buffer, 2048, stdin))
  99. {
  100. char *pos = strchr(buffer, '\n');
  101. if(pos)
  102. *pos = '\0';
  103. }
  104. if(!data.len)
  105. return 0;
  106. unsigned int len = (unsigned int)strlen(buffer) + 1;
  107. char *target = data.ptr;
  108. for(unsigned int i = 0; i < (data.len < len ? data.len : len); i++)
  109. target[i] = buffer[i];
  110. target[data.len - 1] = 0;
  111. return ((unsigned int)len < data.len - 1 ? len : data.len - 1);
  112. }
  113. void WriteToConsoleExact(NULLCArray data)
  114. {
  115. if(!data.ptr)
  116. {
  117. nullcThrowError("ERROR: argument should not be a nullptr");
  118. return;
  119. }
  120. InitConsole();
  121. fwrite(data.ptr, 1, data.len, stdout);
  122. }
  123. void SetConsoleCursorPos(int x, int y)
  124. {
  125. #if !defined(_MSC_VER)
  126. nullcThrowError("SetConsoleCursorPos: supported only under Windows");
  127. #else
  128. if(x < 0 || y < 0)
  129. {
  130. nullcThrowError("SetConsoleCursorPos: Negative values are not allowed");
  131. return;
  132. }
  133. COORD coords;
  134. coords.X = (short)x;
  135. coords.Y = (short)y;
  136. HANDLE conStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
  137. SetConsoleCursorPosition(conStdOut, coords);
  138. #endif
  139. }
  140. void GetKeyboardState(NULLCArray arr)
  141. {
  142. #if !defined(_MSC_VER)
  143. nullcThrowError("GetKeyboardState: supported only under Windows");
  144. #else
  145. if(arr.len < 256)
  146. nullcThrowError("GetKeyboardState requires array with 256 or more elements");
  147. ::GetKeyboardState((unsigned char*)arr.ptr);
  148. #endif
  149. }
  150. void GetMouseState(int* x, int* y)
  151. {
  152. #if !defined(_MSC_VER)
  153. nullcThrowError("GetMouseState: supported only under Windows");
  154. #else
  155. if(!x)
  156. {
  157. nullcThrowError("ERROR: 'x' argument should not be a nullptr");
  158. return;
  159. }
  160. if(!y)
  161. {
  162. nullcThrowError("ERROR: 'y' argument should not be a nullptr");
  163. return;
  164. }
  165. POINT pos;
  166. GetCursorPos(&pos);
  167. *x = pos.x;
  168. *y = pos.y;
  169. #endif
  170. }
  171. bool IsPressed(int key)
  172. {
  173. #if !defined(_MSC_VER)
  174. nullcThrowError("GetMouseState: supported only under Windows");
  175. return false;
  176. #else
  177. unsigned char arr[256];
  178. ::GetKeyboardState(arr);
  179. if(arr[key & 0xff] > 1)
  180. key = key;
  181. return !!(arr[key & 0xff] & 0x80);
  182. #endif
  183. }
  184. bool IsToggled(int key)
  185. {
  186. #if !defined(_MSC_VER)
  187. nullcThrowError("GetMouseState: supported only under Windows");
  188. return false;
  189. #else
  190. unsigned char arr[256];
  191. ::GetKeyboardState(arr);
  192. return !!(arr[key & 0xff] & 0x1);
  193. #endif
  194. }
  195. }
  196. #define REGISTER_FUNC(funcPtr, name, index) if(!nullcBindModuleFunction("std.io", (void(*)())NULLCIO::funcPtr, name, index)) return false;
  197. bool nullcInitIOModule()
  198. {
  199. REGISTER_FUNC(WriteToConsole, "Print", 0);
  200. REGISTER_FUNC(WriteIntConsole, "Print", 1);
  201. REGISTER_FUNC(WriteDoubleConsole, "Print", 2);
  202. REGISTER_FUNC(WriteLongConsole, "Print", 3);
  203. REGISTER_FUNC(WriteCharConsole, "Print", 4);
  204. REGISTER_FUNC(ReadTextFromConsole, "Input", 0);
  205. REGISTER_FUNC(ReadIntFromConsole, "Input", 1);
  206. REGISTER_FUNC(WriteToConsoleExact, "Write", 0);
  207. REGISTER_FUNC(SetConsoleCursorPos, "SetConsoleCursorPos", 0);
  208. REGISTER_FUNC(GetKeyboardState, "GetKeyboardState", 0);
  209. REGISTER_FUNC(GetMouseState, "GetMouseState", 0);
  210. REGISTER_FUNC(IsPressed, "IsPressed", 0);
  211. REGISTER_FUNC(IsToggled, "IsToggled", 0);
  212. REGISTER_FUNC(IsPressed, "IsPressed", 1);
  213. REGISTER_FUNC(IsToggled, "IsToggled", 1);
  214. return true;
  215. }