reststrvar.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. #include "restvar.h"
  2. #include "conv.h"
  3. #define _IS_VALID_VT(vt) ((vt > CRestStringVariable::VT_Invalid) && (vt < CRestStringVariable::VT_Last))
  4. /////////////////////////////////////////////////////////////////////////////
  5. CRestStringVariable::CRestStringVariable(void *pData, size_t nCChData, VT vt, const std::type_info &rti, HSHM hShm, const char *pszName, int nIndex, CRest *pParent)
  6. : m_name(pszName), m_pszPath(NULL), m_nIndex(nIndex), m_vt(VT_Invalid), m_data({NULL}), m_nCbBuffer(0), m_pszUTF8(NULL), m_nCbUTF8(0),
  7. m_pParent(pParent), m_nCbVarpath(0)
  8. {
  9. if(!pData || !hShm || !nCChData || !_IS_VALID_VT(vt))
  10. {
  11. ASSERT(false);
  12. return;
  13. }
  14. m_vt = vt;
  15. m_data.pVoid = pData;
  16. m_hShm = hShm;
  17. if( (rti == typeid(char)) ||
  18. (rti == typeid(signed char)) ||
  19. (rti == typeid(unsigned char)))
  20. {
  21. switch(vt)
  22. {
  23. case VT_Latin1:
  24. case VT_UTF_8:
  25. m_nCbBuffer = nCChData;
  26. zeroTerm(m_data, nCChData - 1);
  27. break;
  28. default:
  29. ASSERT(false);
  30. return;
  31. }
  32. }
  33. else if(rti == typeid(char16_t))
  34. {
  35. switch(vt)
  36. {
  37. case VT_UTF_16:
  38. m_nCbBuffer = nCChData * sizeof(char16_t);
  39. zeroTerm(m_data, nCChData - 1);
  40. break;
  41. default:
  42. ASSERT(false);
  43. return;
  44. }
  45. }
  46. else if(rti == typeid(char32_t))
  47. {
  48. switch(vt)
  49. {
  50. case VT_UTF_32:
  51. m_nCbBuffer = nCChData * sizeof(char32_t);
  52. zeroTerm(m_data, nCChData - 1);
  53. break;
  54. default:
  55. ASSERT(false);
  56. return;
  57. }
  58. }
  59. else if(rti == typeid(wchar_t))
  60. {
  61. switch(vt)
  62. {
  63. case VT_Unicode:
  64. m_nCbBuffer = nCChData * sizeof(wchar_t);
  65. zeroTerm(m_data, nCChData - 1);
  66. break;
  67. default:
  68. ASSERT(false);
  69. return;
  70. }
  71. }
  72. else
  73. {
  74. ASSERT(false);
  75. }
  76. m_nCbUTF8 = m_nCbBuffer * 4;
  77. m_pszUTF8 = new char[m_nCbUTF8];
  78. memset(m_pszUTF8, 0, m_nCbUTF8);
  79. }
  80. CRestStringVariable::~CRestStringVariable(void)
  81. {
  82. if(m_pszUTF8)
  83. delete [] m_pszUTF8;
  84. }
  85. /////////////////////////////////////////////////////////////////////////////
  86. void CRestStringVariable::CreateMembersTable(CRestVarTable &vt)
  87. {
  88. vt.AddVar(static_cast<CRest*>(this));
  89. }
  90. void CRestStringVariable::InitPath(CRest *pParent, const char *pszMemberName, int nIndex)
  91. {
  92. CRest::CreatePath(pParent, pszMemberName, nIndex, m_path);
  93. m_pszPath = m_path.c_str();
  94. m_nCbVarpath = m_path.length();
  95. }
  96. void CRestStringVariable::GetValue(int nReqIndex, json_t* pjtMap)
  97. {
  98. json_array_append_new(pjtMap, GetValue(nReqIndex));
  99. }
  100. json_t* CRestStringVariable::GetValue(int nReqIndex)
  101. {
  102. json_t *pjtVal = NULL;
  103. size_t nCChBuf = 0;
  104. size_t nCChString = 0;
  105. memset(m_pszUTF8, 0, m_nCbUTF8);
  106. Lock();
  107. switch(m_vt)
  108. {
  109. case VT_Latin1:
  110. nCChBuf = m_nCbBuffer - 1;
  111. zeroTerm(m_data, nCChBuf);
  112. nCChString = strlen(m_data.pszMbs);
  113. ::Latin1ToUtf8(m_data.pszMbs, nCChString, m_pszUTF8, m_nCbUTF8);
  114. pjtVal = json_string(m_pszUTF8);
  115. break;
  116. case VT_UTF_8:
  117. nCChBuf = m_nCbBuffer - 1;
  118. zeroTerm(m_data, nCChBuf);
  119. nCChString = strlen(m_data.pszMbs);
  120. memcpy(m_pszUTF8, m_data.pszMbs, nCChString);
  121. pjtVal = json_string(m_pszUTF8);
  122. break;
  123. case VT_UTF_16:
  124. nCChBuf = m_nCbBuffer / sizeof(char16_t) - 1;
  125. zeroTerm(m_data, nCChBuf);
  126. nCChString = wcs16len(m_data.pszWc16);
  127. ::Utf16ToUtf8(m_data.pszWc16, nCChString, m_pszUTF8, m_nCbUTF8);
  128. pjtVal = json_string(m_pszUTF8);
  129. break;
  130. case VT_UTF_32:
  131. nCChBuf = m_nCbBuffer / sizeof(char32_t) - 1;
  132. zeroTerm(m_data, nCChBuf);
  133. nCChString = wcs32len(m_data.pszWc32);
  134. ::Utf32ToUtf8(m_data.pszWc32, nCChString, m_pszUTF8, m_nCbUTF8);
  135. pjtVal = json_string(m_pszUTF8);
  136. break;
  137. case VT_Unicode:
  138. nCChBuf = m_nCbBuffer / sizeof(wchar_t) - 1;
  139. zeroTerm(m_data, nCChBuf);
  140. nCChString = wcslen(m_data.pszWcs);
  141. ::WcsToUtf8(m_data.pszWcs, nCChString, m_pszUTF8, m_nCbUTF8);
  142. pjtVal = json_string(m_pszUTF8);
  143. break;
  144. default:
  145. ASSERT(false);
  146. break;
  147. }
  148. Unlock();
  149. if(pjtVal)
  150. return CreateValueObject(nReqIndex, m_pszPath, m_nIndex, json_typeof(pjtVal), m_name.c_str(), pjtVal);
  151. else
  152. return CreateStatusObject(nReqIndex, -1, "Unexpected Error!", m_pszPath);
  153. }
  154. json_t* CRestStringVariable::SetValue(int nReqIndex, json_t *pjtVal)
  155. {
  156. if(!pjtVal)
  157. return CreateStatusObject(nReqIndex, -1, "Unexpected error!", GetPath());
  158. int nCode = 0;
  159. const char *pszMsg = NULL;
  160. size_t nCChBuf = 0, nCChString = 0;
  161. int nType = json_typeof(pjtVal);
  162. if(nType == JSON_STRING)
  163. {
  164. const char *pszUtf8 = json_string_value(pjtVal);
  165. size_t nLen = strlen(pszUtf8);
  166. Lock();
  167. switch(m_vt)
  168. {
  169. case VT_Latin1:
  170. nCChBuf = m_nCbBuffer;
  171. nCChString = ::Utf8ToLatin1(pszUtf8, nLen, m_data.pszMbs, nCChBuf);
  172. zeroTerm(m_data, nCChString);
  173. break;
  174. case VT_UTF_8:
  175. nCChBuf = m_nCbBuffer - 1;
  176. nCChString = __min(nLen, nCChBuf);
  177. memcpy(m_data.pszMbs, pszUtf8, nCChString);
  178. zeroTerm(m_data, nCChString);
  179. break;
  180. case VT_UTF_16:
  181. nCChBuf = m_nCbBuffer / sizeof(char16_t);
  182. nCChString = ::Utf8ToUtf16(pszUtf8, nLen, m_data.pszWc16, nCChBuf) / sizeof(char16_t);
  183. zeroTerm(m_data, nCChString);
  184. break;
  185. case VT_UTF_32:
  186. nCChBuf = m_nCbBuffer / sizeof(char32_t);
  187. nCChString = ::Utf8ToUtf32(pszUtf8, nLen, m_data.pszWc32, nCChBuf) / sizeof(char32_t);
  188. zeroTerm(m_data, nCChString);
  189. break;
  190. case VT_Unicode:
  191. nCChBuf = m_nCbBuffer / sizeof(wchar_t);
  192. nCChString = ::Utf8ToWcs(pszUtf8, nLen, m_data.pszWcs, nCChBuf) / sizeof(wchar_t);
  193. zeroTerm(m_data, nCChString);
  194. break;
  195. default:
  196. ASSERT(false);
  197. break;
  198. }
  199. Unlock();
  200. }
  201. else
  202. {
  203. pszMsg = "Cannot assign incompatible JSON type to string variable!";
  204. nCode = 1;
  205. }
  206. return CreateStatusObject(nReqIndex, nCode, pszMsg, GetPath());
  207. }
  208. /////////////////////////////////////////////////////////////////////////////
  209. void CRestStringVariable::Lock(void)
  210. {
  211. ::GfaIpcLockSHM(m_hShm);
  212. }
  213. void CRestStringVariable::Unlock(void)
  214. {
  215. ::GfaIpcUnlockSHM(m_hShm);
  216. }
  217. void CRestStringVariable::zeroTerm(volatile V_Ptr &rp, size_t at)
  218. {
  219. switch(m_vt)
  220. {
  221. case VT_Latin1:
  222. case VT_UTF_8:
  223. rp.pszMbs[at] = '\0';
  224. break;
  225. case VT_UTF_16:
  226. rp.pszWc16[at] = (char16_t)0;
  227. break;
  228. case VT_UTF_32:
  229. rp.pszWc32[at] = (char32_t)0;
  230. break;
  231. case VT_Unicode:
  232. rp.pszWcs[at] = L'\0';
  233. break;
  234. default:
  235. ASSERT(false);
  236. break;
  237. }
  238. }