PageRenderTime 70ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/MicroFrameworkPK_v4_2/CLR/Libraries/CorLib/corlib_native_System_String.cpp

https://bitbucket.org/pmfsampaio/netmf-lpc
C++ | 1075 lines | 773 code | 283 blank | 19 comment | 106 complexity | f4334292252718df8352f7f2dd02b20e MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  4. #include "CorLib.h"
  5. static const CLR_UINT16 c_WhiteSpaces[] =
  6. {
  7. 0x0009,
  8. 0x000A,
  9. 0x000B,
  10. 0x000C,
  11. 0x000D,
  12. 0x0020,
  13. 0x00A0,
  14. 0x2000,
  15. 0x2001,
  16. 0x2002,
  17. 0x2003,
  18. 0x2004,
  19. 0x2005,
  20. 0x2006,
  21. 0x2007,
  22. 0x2008,
  23. 0x2009,
  24. 0x200A,
  25. 0x200B,
  26. 0x3000,
  27. 0xFEFF,
  28. };
  29. //--//
  30. HRESULT Library_corlib_native_System_String::get_Chars___CHAR__I4( CLR_RT_StackFrame& stack )
  31. {
  32. NATIVE_PROFILE_CLR_CORE();
  33. TINYCLR_HEADER();
  34. LPCSTR szText;
  35. CLR_RT_UnicodeHelper uh;
  36. CLR_UINT16 buf[ 3 ];
  37. int len;
  38. int index;
  39. szText = stack.Arg0().RecoverString(); FAULT_ON_NULL(szText);
  40. uh.SetInputUTF8( szText );
  41. len = uh.CountNumberOfCharacters() ; if(len < 0 ) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
  42. index = stack.Arg1().NumericByRef().s4; if(index < 0 || index >= len) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  43. uh.m_outputUTF16 = buf;
  44. uh.m_outputUTF16_size = MAXSTRLEN(buf);
  45. //
  46. // First move to the character, then read it.
  47. //
  48. uh.ConvertFromUTF8( index, true );
  49. uh.ConvertFromUTF8( 1 , false );
  50. stack.SetResult( buf[ 0 ], DATATYPE_CHAR );
  51. TINYCLR_NOCLEANUP();
  52. }
  53. HRESULT Library_corlib_native_System_String::ToCharArray___SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  54. {
  55. NATIVE_PROFILE_CLR_CORE();
  56. TINYCLR_HEADER();
  57. TINYCLR_SET_AND_LEAVE(ToCharArray( stack, 0, -1 ));
  58. TINYCLR_NOCLEANUP();
  59. }
  60. HRESULT Library_corlib_native_System_String::ToCharArray___SZARRAY_CHAR__I4__I4( CLR_RT_StackFrame& stack )
  61. {
  62. NATIVE_PROFILE_CLR_CORE();
  63. TINYCLR_HEADER();
  64. TINYCLR_SET_AND_LEAVE(ToCharArray( stack, stack.Arg1().NumericByRef().s4, stack.Arg2().NumericByRef().s4 ));
  65. TINYCLR_NOCLEANUP();
  66. }
  67. HRESULT Library_corlib_native_System_String::get_Length___I4( CLR_RT_StackFrame& stack )
  68. {
  69. NATIVE_PROFILE_CLR_CORE();
  70. TINYCLR_HEADER();
  71. LPCSTR szText = stack.Arg0().RecoverString(); FAULT_ON_NULL(szText);
  72. CLR_RT_UnicodeHelper uh; uh.SetInputUTF8( szText );
  73. stack.SetResult_I4( uh.CountNumberOfCharacters() );
  74. TINYCLR_NOCLEANUP();
  75. }
  76. HRESULT Library_corlib_native_System_String::Split___SZARRAY_STRING__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  77. {
  78. NATIVE_PROFILE_CLR_CORE();
  79. TINYCLR_HEADER();
  80. TINYCLR_SET_AND_LEAVE(Split( stack, stack.Arg1(), 0x7FFFFFFF )); /// Sending INT_MAX instead of -1.
  81. TINYCLR_NOCLEANUP();
  82. }
  83. HRESULT Library_corlib_native_System_String::Split___SZARRAY_STRING__SZARRAY_CHAR__I4( CLR_RT_StackFrame& stack )
  84. {
  85. NATIVE_PROFILE_CLR_CORE();
  86. TINYCLR_HEADER();
  87. TINYCLR_SET_AND_LEAVE(Split( stack, stack.Arg1(), stack.Arg2().NumericByRef().s4 ));
  88. TINYCLR_NOCLEANUP();
  89. }
  90. HRESULT Library_corlib_native_System_String::Substring___STRING__I4( CLR_RT_StackFrame& stack )
  91. {
  92. NATIVE_PROFILE_CLR_CORE();
  93. TINYCLR_HEADER();
  94. TINYCLR_SET_AND_LEAVE(Substring( stack, stack.Arg1().NumericByRef().s4, -1 ));
  95. TINYCLR_NOCLEANUP();
  96. }
  97. HRESULT Library_corlib_native_System_String::Substring___STRING__I4__I4( CLR_RT_StackFrame& stack )
  98. {
  99. NATIVE_PROFILE_CLR_CORE();
  100. TINYCLR_HEADER();
  101. CLR_INT32 length = stack.Arg2().NumericByRef().s4;
  102. if(length < 0) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  103. TINYCLR_SET_AND_LEAVE(Substring( stack, stack.Arg1().NumericByRef().s4, length ));
  104. TINYCLR_NOCLEANUP();
  105. }
  106. HRESULT Library_corlib_native_System_String::Trim___STRING__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  107. {
  108. NATIVE_PROFILE_CLR_CORE();
  109. TINYCLR_HEADER();
  110. TINYCLR_SET_AND_LEAVE(Trim( stack, stack.Arg1().DereferenceArray(), true, true ));
  111. TINYCLR_NOCLEANUP();
  112. }
  113. HRESULT Library_corlib_native_System_String::TrimStart___STRING__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  114. {
  115. NATIVE_PROFILE_CLR_CORE();
  116. TINYCLR_HEADER();
  117. TINYCLR_SET_AND_LEAVE(Trim( stack, stack.Arg1().DereferenceArray(), true, false ));
  118. TINYCLR_NOCLEANUP();
  119. }
  120. HRESULT Library_corlib_native_System_String::TrimEnd___STRING__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  121. {
  122. NATIVE_PROFILE_CLR_CORE();
  123. TINYCLR_HEADER();
  124. TINYCLR_SET_AND_LEAVE(Trim( stack, stack.Arg1().DereferenceArray(), false, true ));
  125. TINYCLR_NOCLEANUP();
  126. }
  127. HRESULT Library_corlib_native_System_String::_ctor___VOID__SZARRAY_CHAR__I4__I4( CLR_RT_StackFrame& stack )
  128. {
  129. NATIVE_PROFILE_CLR_CORE();
  130. TINYCLR_HEADER();
  131. TINYCLR_SET_AND_LEAVE(FromCharArray( stack, stack.Arg2().NumericByRef().s4, stack.Arg3().NumericByRef().s4 ));
  132. TINYCLR_NOCLEANUP();
  133. }
  134. HRESULT Library_corlib_native_System_String::_ctor___VOID__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  135. {
  136. NATIVE_PROFILE_CLR_CORE();
  137. TINYCLR_HEADER();
  138. TINYCLR_SET_AND_LEAVE(FromCharArray( stack, 0, -1 ));
  139. TINYCLR_NOCLEANUP();
  140. }
  141. HRESULT Library_corlib_native_System_String::_ctor___VOID__CHAR__I4( CLR_RT_StackFrame& stack )
  142. {
  143. NATIVE_PROFILE_CLR_CORE();
  144. TINYCLR_HEADER();
  145. CLR_UINT16 ch = stack.Arg1().NumericByRef().u2;
  146. int len = stack.Arg2().NumericByRef().s4; if(len < 0) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  147. {
  148. CLR_RT_HeapBlock tmp; tmp.SetObjectReference( NULL );
  149. CLR_RT_ProtectFromGC gc( tmp );
  150. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( tmp, len, g_CLR_RT_WellKnownTypes.m_Char ));
  151. {
  152. CLR_RT_HeapBlock_Array* tmpArray = tmp.DereferenceArray();
  153. CLR_UINT16* pTmp = (CLR_UINT16*)tmpArray->GetFirstElement();
  154. CLR_UINT16* p;
  155. p = pTmp; while(len--) *p++ = ch;
  156. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( stack.Arg0(), pTmp, tmpArray->m_numOfElements ));
  157. }
  158. }
  159. TINYCLR_NOCLEANUP();
  160. }
  161. HRESULT Library_corlib_native_System_String::CompareTo___I4__OBJECT( CLR_RT_StackFrame& stack )
  162. {
  163. NATIVE_PROFILE_CLR_CORE();
  164. TINYCLR_HEADER();
  165. TINYCLR_SET_AND_LEAVE(Library_corlib_native_System_String::CompareTo___I4__STRING( stack ));
  166. TINYCLR_NOCLEANUP();
  167. }
  168. HRESULT Library_corlib_native_System_String::CompareTo___I4__STRING( CLR_RT_StackFrame& stack )
  169. {
  170. NATIVE_PROFILE_CLR_CORE();
  171. TINYCLR_HEADER();
  172. CLR_RT_HeapBlock& pThis = stack.Arg0(); // String references are special, they don't point to an object, they are the object. So use stack.Arg0() instead of stack.This()
  173. CLR_RT_HeapBlock& pArg = stack.Arg1();
  174. stack.SetResult_I4( CLR_RT_HeapBlock::Compare_Unsigned_Values( pThis, pArg ) );
  175. TINYCLR_NOCLEANUP_NOLABEL();
  176. }
  177. HRESULT Library_corlib_native_System_String::IndexOf___I4__CHAR( CLR_RT_StackFrame& stack )
  178. {
  179. NATIVE_PROFILE_CLR_CORE();
  180. TINYCLR_HEADER();
  181. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar ));
  182. TINYCLR_NOCLEANUP();
  183. }
  184. HRESULT Library_corlib_native_System_String::IndexOf___I4__CHAR__I4( CLR_RT_StackFrame& stack )
  185. {
  186. NATIVE_PROFILE_CLR_CORE();
  187. TINYCLR_HEADER();
  188. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar | c_IndexOf__StartIndex ));
  189. TINYCLR_NOCLEANUP();
  190. }
  191. HRESULT Library_corlib_native_System_String::IndexOf___I4__CHAR__I4__I4( CLR_RT_StackFrame& stack )
  192. {
  193. NATIVE_PROFILE_CLR_CORE();
  194. TINYCLR_HEADER();
  195. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar | c_IndexOf__StartIndex | c_IndexOf__Count ));
  196. TINYCLR_NOCLEANUP();
  197. }
  198. HRESULT Library_corlib_native_System_String::IndexOfAny___I4__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  199. {
  200. NATIVE_PROFILE_CLR_CORE();
  201. TINYCLR_HEADER();
  202. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars ));
  203. TINYCLR_NOCLEANUP();
  204. }
  205. HRESULT Library_corlib_native_System_String::IndexOfAny___I4__SZARRAY_CHAR__I4( CLR_RT_StackFrame& stack )
  206. {
  207. NATIVE_PROFILE_CLR_CORE();
  208. TINYCLR_HEADER();
  209. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars | c_IndexOf__StartIndex ));
  210. TINYCLR_NOCLEANUP();
  211. }
  212. HRESULT Library_corlib_native_System_String::IndexOfAny___I4__SZARRAY_CHAR__I4__I4( CLR_RT_StackFrame& stack )
  213. {
  214. NATIVE_PROFILE_CLR_CORE();
  215. TINYCLR_HEADER();
  216. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars | c_IndexOf__StartIndex | c_IndexOf__Count ));
  217. TINYCLR_NOCLEANUP();
  218. }
  219. HRESULT Library_corlib_native_System_String::IndexOf___I4__STRING( CLR_RT_StackFrame& stack )
  220. {
  221. NATIVE_PROFILE_CLR_CORE();
  222. TINYCLR_HEADER();
  223. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String ));
  224. TINYCLR_NOCLEANUP();
  225. }
  226. HRESULT Library_corlib_native_System_String::IndexOf___I4__STRING__I4( CLR_RT_StackFrame& stack )
  227. {
  228. NATIVE_PROFILE_CLR_CORE();
  229. TINYCLR_HEADER();
  230. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String | c_IndexOf__StartIndex ));
  231. TINYCLR_NOCLEANUP();
  232. }
  233. HRESULT Library_corlib_native_System_String::IndexOf___I4__STRING__I4__I4( CLR_RT_StackFrame& stack )
  234. {
  235. NATIVE_PROFILE_CLR_CORE();
  236. TINYCLR_HEADER();
  237. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String | c_IndexOf__StartIndex | c_IndexOf__Count ));
  238. TINYCLR_NOCLEANUP();
  239. }
  240. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__CHAR( CLR_RT_StackFrame& stack )
  241. {
  242. NATIVE_PROFILE_CLR_CORE();
  243. TINYCLR_HEADER();
  244. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar | c_IndexOf__Last ));
  245. TINYCLR_NOCLEANUP();
  246. }
  247. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__CHAR__I4( CLR_RT_StackFrame& stack )
  248. {
  249. NATIVE_PROFILE_CLR_CORE();
  250. TINYCLR_HEADER();
  251. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar | c_IndexOf__Last | c_IndexOf__StartIndex ));
  252. TINYCLR_NOCLEANUP();
  253. }
  254. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__CHAR__I4__I4( CLR_RT_StackFrame& stack )
  255. {
  256. NATIVE_PROFILE_CLR_CORE();
  257. TINYCLR_HEADER();
  258. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__SingleChar | c_IndexOf__Last | c_IndexOf__StartIndex | c_IndexOf__Count ));
  259. TINYCLR_NOCLEANUP();
  260. }
  261. HRESULT Library_corlib_native_System_String::LastIndexOfAny___I4__SZARRAY_CHAR( CLR_RT_StackFrame& stack )
  262. {
  263. NATIVE_PROFILE_CLR_CORE();
  264. TINYCLR_HEADER();
  265. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars | c_IndexOf__Last ));
  266. TINYCLR_NOCLEANUP();
  267. }
  268. HRESULT Library_corlib_native_System_String::LastIndexOfAny___I4__SZARRAY_CHAR__I4( CLR_RT_StackFrame& stack )
  269. {
  270. NATIVE_PROFILE_CLR_CORE();
  271. TINYCLR_HEADER();
  272. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars | c_IndexOf__Last | c_IndexOf__StartIndex ));
  273. TINYCLR_NOCLEANUP();
  274. }
  275. HRESULT Library_corlib_native_System_String::LastIndexOfAny___I4__SZARRAY_CHAR__I4__I4( CLR_RT_StackFrame& stack )
  276. {
  277. NATIVE_PROFILE_CLR_CORE();
  278. TINYCLR_HEADER();
  279. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__MultipleChars | c_IndexOf__Last | c_IndexOf__StartIndex | c_IndexOf__Count ));
  280. TINYCLR_NOCLEANUP();
  281. }
  282. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__STRING( CLR_RT_StackFrame& stack )
  283. {
  284. NATIVE_PROFILE_CLR_CORE();
  285. TINYCLR_HEADER();
  286. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String | c_IndexOf__Last ));
  287. TINYCLR_NOCLEANUP();
  288. }
  289. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__STRING__I4( CLR_RT_StackFrame& stack )
  290. {
  291. NATIVE_PROFILE_CLR_CORE();
  292. TINYCLR_HEADER();
  293. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String | c_IndexOf__Last | c_IndexOf__StartIndex ));
  294. TINYCLR_NOCLEANUP();
  295. }
  296. HRESULT Library_corlib_native_System_String::LastIndexOf___I4__STRING__I4__I4( CLR_RT_StackFrame& stack )
  297. {
  298. NATIVE_PROFILE_CLR_CORE();
  299. TINYCLR_HEADER();
  300. TINYCLR_SET_AND_LEAVE(IndexOf( stack, c_IndexOf__String | c_IndexOf__Last | c_IndexOf__StartIndex | c_IndexOf__Count ));
  301. TINYCLR_NOCLEANUP();
  302. }
  303. HRESULT Library_corlib_native_System_String::ToLower___STRING( CLR_RT_StackFrame& stack )
  304. {
  305. NATIVE_PROFILE_CLR_CORE();
  306. TINYCLR_HEADER();
  307. TINYCLR_SET_AND_LEAVE(ChangeCase( stack, false ));
  308. TINYCLR_NOCLEANUP();
  309. }
  310. HRESULT Library_corlib_native_System_String::ToUpper___STRING( CLR_RT_StackFrame& stack )
  311. {
  312. NATIVE_PROFILE_CLR_CORE();
  313. TINYCLR_HEADER();
  314. TINYCLR_SET_AND_LEAVE(ChangeCase( stack, true ));
  315. TINYCLR_NOCLEANUP();
  316. }
  317. HRESULT Library_corlib_native_System_String::Trim___STRING( CLR_RT_StackFrame& stack )
  318. {
  319. NATIVE_PROFILE_CLR_CORE();
  320. TINYCLR_HEADER();
  321. TINYCLR_SET_AND_LEAVE(Trim( stack, NULL, true, true ));
  322. TINYCLR_NOCLEANUP();
  323. }
  324. HRESULT Library_corlib_native_System_String::Equals___STATIC__BOOLEAN__STRING__STRING( CLR_RT_StackFrame& stack )
  325. {
  326. NATIVE_PROFILE_CLR_CORE();
  327. TINYCLR_HEADER();
  328. stack.SetResult_Boolean( CLR_RT_HeapBlock::Compare_Unsigned_Values( stack.Arg0(), stack.Arg1() ) == 0 );
  329. TINYCLR_NOCLEANUP_NOLABEL();
  330. }
  331. HRESULT Library_corlib_native_System_String::op_Equality___STATIC__BOOLEAN__STRING__STRING( CLR_RT_StackFrame& stack )
  332. {
  333. NATIVE_PROFILE_CLR_CORE();
  334. TINYCLR_HEADER();
  335. TINYCLR_SET_AND_LEAVE(Library_corlib_native_System_String::Equals___STATIC__BOOLEAN__STRING__STRING( stack ));
  336. TINYCLR_NOCLEANUP();
  337. }
  338. HRESULT Library_corlib_native_System_String::op_Inequality___STATIC__BOOLEAN__STRING__STRING( CLR_RT_StackFrame& stack )
  339. {
  340. NATIVE_PROFILE_CLR_CORE();
  341. TINYCLR_HEADER();
  342. TINYCLR_CHECK_HRESULT(Library_corlib_native_System_String::Equals___STATIC__BOOLEAN__STRING__STRING( stack ));
  343. stack.NegateResult();
  344. TINYCLR_NOCLEANUP();
  345. }
  346. HRESULT Library_corlib_native_System_String::Compare___STATIC__I4__STRING__STRING( CLR_RT_StackFrame& stack )
  347. {
  348. NATIVE_PROFILE_CLR_CORE();
  349. TINYCLR_HEADER();
  350. stack.SetResult_I4( CLR_RT_HeapBlock::Compare_Unsigned_Values( stack.Arg0(), stack.Arg1() ) );
  351. TINYCLR_NOCLEANUP_NOLABEL();
  352. }
  353. HRESULT Library_corlib_native_System_String::Concat___STATIC__STRING__STRING__STRING( CLR_RT_StackFrame& stack )
  354. {
  355. NATIVE_PROFILE_CLR_CORE();
  356. TINYCLR_HEADER();
  357. TINYCLR_SET_AND_LEAVE(Concat( stack, &stack.Arg0(), 2 ));
  358. TINYCLR_NOCLEANUP();
  359. }
  360. HRESULT Library_corlib_native_System_String::Concat___STATIC__STRING__STRING__STRING__STRING( CLR_RT_StackFrame& stack )
  361. {
  362. NATIVE_PROFILE_CLR_CORE();
  363. TINYCLR_HEADER();
  364. TINYCLR_SET_AND_LEAVE(Concat( stack, &stack.Arg0(), 3 ));
  365. TINYCLR_NOCLEANUP();
  366. }
  367. HRESULT Library_corlib_native_System_String::Concat___STATIC__STRING__STRING__STRING__STRING__STRING( CLR_RT_StackFrame& stack )
  368. {
  369. NATIVE_PROFILE_CLR_CORE();
  370. TINYCLR_HEADER();
  371. TINYCLR_SET_AND_LEAVE(Concat( stack, &stack.Arg0(), 4 ));
  372. TINYCLR_NOCLEANUP();
  373. }
  374. HRESULT Library_corlib_native_System_String::Concat___STATIC__STRING__SZARRAY_STRING( CLR_RT_StackFrame& stack )
  375. {
  376. NATIVE_PROFILE_CLR_CORE();
  377. TINYCLR_HEADER();
  378. CLR_RT_HeapBlock_Array* pArray = stack.Arg0().DereferenceArray(); FAULT_ON_NULL(pArray);
  379. TINYCLR_SET_AND_LEAVE(Concat( stack, (CLR_RT_HeapBlock*)pArray->GetFirstElement(), pArray->m_numOfElements ));
  380. TINYCLR_NOCLEANUP();
  381. }
  382. //--//
  383. HRESULT Library_corlib_native_System_String::FromCharArray( CLR_RT_StackFrame& stack, int startIndex, int length )
  384. {
  385. NATIVE_PROFILE_CLR_CORE();
  386. TINYCLR_HEADER();
  387. CLR_RT_HeapBlock_Array* array;
  388. CLR_UINT32 len;
  389. array = stack.Arg1().DereferenceArray(); if(!array) TINYCLR_SET_AND_LEAVE(S_OK);
  390. len = array->m_numOfElements ; if(!len ) TINYCLR_SET_AND_LEAVE(S_OK);
  391. if(length == -1) length = len - startIndex;
  392. if(CLR_RT_HeapBlock_Array::CheckRange( startIndex, length, len ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  393. TINYCLR_SET_AND_LEAVE(CLR_RT_HeapBlock_String::CreateInstance( stack.Arg0(), (CLR_UINT16*)array->GetElement( startIndex ), length ));
  394. TINYCLR_NOCLEANUP();
  395. }
  396. HRESULT Library_corlib_native_System_String::ToCharArray( CLR_RT_StackFrame& stack, int startIndex, int length )
  397. {
  398. NATIVE_PROFILE_CLR_CORE();
  399. TINYCLR_HEADER();
  400. CLR_RT_HeapBlock_Array* array;
  401. TINYCLR_SET_AND_LEAVE(ConvertToCharArray( stack, stack.PushValueAndClear(), array, startIndex, length ));
  402. TINYCLR_NOCLEANUP();
  403. }
  404. HRESULT Library_corlib_native_System_String::IndexOf( CLR_RT_StackFrame& stack, int mode )
  405. {
  406. NATIVE_PROFILE_CLR_CORE();
  407. TINYCLR_HEADER();
  408. LPCSTR szText;
  409. int startIndex;
  410. int count;
  411. int pos;
  412. LPCSTR pString;
  413. const CLR_UINT16* pChars;
  414. int iChars = 0;
  415. CLR_RT_UnicodeHelper uh;
  416. int len;
  417. szText = stack.Arg0().RecoverString(); if(!szText) szText = "";
  418. pos = -1;
  419. pString = NULL;
  420. pChars = NULL;
  421. if(mode & c_IndexOf__SingleChar)
  422. {
  423. pChars = (CLR_UINT16*)&stack.Arg1().NumericByRefConst().u2;
  424. iChars = 1;
  425. }
  426. else if(mode & c_IndexOf__MultipleChars)
  427. {
  428. CLR_RT_HeapBlock_Array* array = stack.Arg1().DereferenceArray(); FAULT_ON_NULL(array);
  429. pChars = (const CLR_UINT16*)array->GetFirstElement();
  430. iChars = array->m_numOfElements;
  431. }
  432. else if(mode & c_IndexOf__String)
  433. {
  434. pString = stack.Arg1().RecoverString(); FAULT_ON_NULL(pString);
  435. }
  436. uh.SetInputUTF8( szText );
  437. len = uh.CountNumberOfCharacters();
  438. //--//
  439. if(mode & c_IndexOf__StartIndex)
  440. {
  441. startIndex = stack.Arg2().NumericByRefConst().s4;
  442. if(startIndex < 0 || startIndex > len) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  443. }
  444. else
  445. {
  446. startIndex = 0;
  447. }
  448. if(mode & c_IndexOf__Count)
  449. {
  450. count = stack.Arg3().NumericByRefConst().s4;
  451. if(startIndex + count > len) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  452. }
  453. else
  454. {
  455. count = len - startIndex;
  456. }
  457. //--//
  458. //
  459. // First move to the character, then read it.
  460. //
  461. if(uh.ConvertFromUTF8( startIndex, true ))
  462. {
  463. if(pString)
  464. {
  465. while(count-- > 0)
  466. {
  467. CLR_RT_UnicodeHelper uh1; uh1.SetInputUTF8( (LPCSTR)uh.m_inputUTF8 );
  468. CLR_RT_UnicodeHelper uh2; uh2.SetInputUTF8( pString );
  469. while(true)
  470. {
  471. CLR_UINT16 buf1[ 3 ];
  472. CLR_UINT16 buf2[ 3 ];
  473. uh1.m_outputUTF16 = buf1;
  474. uh1.m_outputUTF16_size = MAXSTRLEN(buf1);
  475. uh2.m_outputUTF16 = buf2;
  476. uh2.m_outputUTF16_size = MAXSTRLEN(buf2);
  477. if(uh2.ConvertFromUTF8( 1, false ) == false)
  478. {
  479. if((mode & c_IndexOf__Last) || (pos == -1))
  480. {
  481. pos = startIndex;
  482. }
  483. break;
  484. }
  485. if(uh1.ConvertFromUTF8( 1, false ) == false)
  486. {
  487. break;
  488. }
  489. if(buf1[ 0 ] != buf2[ 0 ])
  490. {
  491. break;
  492. }
  493. }
  494. if(uh.ConvertFromUTF8( 1, true ) == false)
  495. {
  496. break;
  497. }
  498. startIndex++;
  499. }
  500. }
  501. if(pChars)
  502. {
  503. while(count-- > 0)
  504. {
  505. CLR_UINT16 buf[ 3 ];
  506. uh.m_outputUTF16 = buf;
  507. uh.m_outputUTF16_size = MAXSTRLEN(buf);
  508. if(uh.ConvertFromUTF8( 1, false ) == false)
  509. {
  510. break;
  511. }
  512. for(int i=0; i<iChars; i++)
  513. {
  514. if(buf[ 0 ] == pChars[ i ])
  515. {
  516. if((mode & c_IndexOf__Last) || (pos == -1))
  517. {
  518. pos = startIndex;
  519. }
  520. break;
  521. }
  522. }
  523. startIndex++;
  524. }
  525. }
  526. }
  527. stack.SetResult_I4( pos );
  528. TINYCLR_NOCLEANUP();
  529. }
  530. HRESULT Library_corlib_native_System_String::ChangeCase( CLR_RT_StackFrame& stack, bool fToUpper )
  531. {
  532. NATIVE_PROFILE_CLR_CORE();
  533. TINYCLR_HEADER();
  534. CLR_RT_HeapBlock refTmp; refTmp.SetObjectReference( NULL );
  535. CLR_RT_ProtectFromGC gc( refTmp );
  536. CLR_RT_HeapBlock_Array* arrayTmp;
  537. CLR_UINT16* ptr;
  538. TINYCLR_CHECK_HRESULT(ConvertToCharArray( stack, refTmp, arrayTmp, 0, -1 ));
  539. ptr = (CLR_UINT16*)arrayTmp->GetFirstElement();
  540. for(CLR_UINT32 i=0; i<arrayTmp->m_numOfElements; i++)
  541. {
  542. CLR_UINT16 c = *ptr;
  543. if(fToUpper)
  544. {
  545. if(c >= 'a' && c <= 'z') c += 'A' - 'a';
  546. }
  547. else
  548. {
  549. if(c >= 'A' && c <= 'Z') c -= 'A' - 'a';
  550. }
  551. *ptr++ = c;
  552. }
  553. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( stack.PushValue(), (CLR_UINT16*)arrayTmp->GetFirstElement(), arrayTmp->m_numOfElements ));
  554. TINYCLR_NOCLEANUP();
  555. }
  556. HRESULT Library_corlib_native_System_String::Substring( CLR_RT_StackFrame& stack, int startIndex, int length )
  557. {
  558. NATIVE_PROFILE_CLR_CORE();
  559. TINYCLR_HEADER();
  560. CLR_RT_HeapBlock refTmp; refTmp.SetObjectReference( NULL );
  561. CLR_RT_ProtectFromGC gc( refTmp );
  562. CLR_RT_HeapBlock_Array* arrayTmp;
  563. TINYCLR_CHECK_HRESULT(ConvertToCharArray( stack, refTmp, arrayTmp, 0, -1 ));
  564. if(startIndex < 0 || startIndex > (int)arrayTmp->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  565. if(length == -1)
  566. {
  567. length = arrayTmp->m_numOfElements - startIndex;
  568. }
  569. else
  570. {
  571. if(length < 0 || (startIndex + length) > (int)arrayTmp->m_numOfElements) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  572. }
  573. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( stack.PushValue(), (CLR_UINT16*)arrayTmp->GetElement( startIndex ), length ));
  574. TINYCLR_NOCLEANUP();
  575. }
  576. HRESULT Library_corlib_native_System_String::Trim( CLR_RT_StackFrame& stack, CLR_RT_HeapBlock_Array* arrayTrimChars, bool fStart, bool fEnd )
  577. {
  578. NATIVE_PROFILE_CLR_CORE();
  579. TINYCLR_HEADER();
  580. CLR_RT_HeapBlock refTmp; refTmp.SetObjectReference( NULL );
  581. CLR_RT_ProtectFromGC gc( refTmp );
  582. CLR_RT_HeapBlock_Array* arrayTmp;
  583. CLR_UINT16* pSrcStart;
  584. CLR_UINT16* pSrcEnd;
  585. TINYCLR_CHECK_HRESULT(ConvertToCharArray( stack, refTmp, arrayTmp, 0, -1 ));
  586. pSrcStart = (CLR_UINT16*)arrayTmp->GetFirstElement();
  587. pSrcEnd = &pSrcStart[ arrayTmp->m_numOfElements ];
  588. const CLR_UINT16* pTrim;
  589. CLR_UINT32 iTrim;
  590. if(arrayTrimChars && arrayTrimChars->m_numOfElements)
  591. {
  592. pTrim = (const CLR_UINT16*)arrayTrimChars->GetFirstElement();
  593. iTrim = arrayTrimChars->m_numOfElements;
  594. }
  595. else
  596. {
  597. pTrim = c_WhiteSpaces;
  598. iTrim = ARRAYSIZE(c_WhiteSpaces);
  599. }
  600. //--//
  601. if(fStart)
  602. {
  603. while(pSrcStart < pSrcEnd)
  604. {
  605. const CLR_UINT16* p = pTrim;
  606. CLR_UINT32 i;
  607. for(i=0; i<iTrim; i++, p++)
  608. {
  609. if(*p == pSrcStart[ 0 ]) break;
  610. }
  611. if(i == iTrim) break;
  612. pSrcStart++;
  613. }
  614. }
  615. if(fEnd)
  616. {
  617. while(pSrcStart < pSrcEnd)
  618. {
  619. const CLR_UINT16* p = pTrim;
  620. CLR_UINT32 i;
  621. for(i=0; i<iTrim; i++, p++)
  622. {
  623. if(*p == pSrcEnd[ -1 ]) break;
  624. }
  625. if(i == iTrim) break;
  626. pSrcEnd--;
  627. }
  628. }
  629. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( stack.PushValue(), pSrcStart, (CLR_UINT32)(pSrcEnd - pSrcStart) ));
  630. TINYCLR_NOCLEANUP();
  631. }
  632. HRESULT Library_corlib_native_System_String::Split( CLR_RT_StackFrame& stack, CLR_RT_HeapBlock& chars, int maxStrings )
  633. {
  634. NATIVE_PROFILE_CLR_CORE();
  635. TINYCLR_HEADER();
  636. CLR_RT_HeapBlock_Array* arraySrc;
  637. CLR_RT_HeapBlock_Array* arrayChars;
  638. CLR_RT_HeapBlock_Array* arrayDst;
  639. const CLR_UINT16* pChars;
  640. CLR_UINT32 cChars;
  641. if (maxStrings < 0)
  642. {
  643. TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE)
  644. }
  645. else if (maxStrings == 0)
  646. {
  647. CLR_RT_HeapBlock& refTarget = stack.PushValue();
  648. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( refTarget, 0, g_CLR_RT_WellKnownTypes.m_String ));
  649. arrayDst = refTarget.DereferenceArray();
  650. }
  651. else
  652. {
  653. arrayChars = chars.DereferenceArray();
  654. if(arrayChars != NULL && arrayChars->m_numOfElements > 0)
  655. {
  656. pChars = (CLR_UINT16*)arrayChars->GetFirstElement();
  657. cChars = arrayChars->m_numOfElements;
  658. }
  659. else
  660. {
  661. pChars = &c_WhiteSpaces[ 0 ];
  662. cChars = ARRAYSIZE(c_WhiteSpaces);
  663. }
  664. arrayDst = NULL;
  665. {
  666. CLR_RT_HeapBlock refSrc; refSrc.SetObjectReference( NULL );
  667. CLR_RT_ProtectFromGC gc( refSrc );
  668. TINYCLR_CHECK_HRESULT(ConvertToCharArray( stack, refSrc, arraySrc, 0, -1 ));
  669. for(int pass=0; pass<2; pass++)
  670. {
  671. CLR_UINT16* pSrcStart = (CLR_UINT16*)arraySrc->GetFirstElement();
  672. CLR_UINT16* pSrc = pSrcStart;
  673. int count = 0;
  674. bool fFound = false;
  675. bool fContinueSearching = true;
  676. for(CLR_UINT32 iSrc=0; iSrc <= arraySrc->m_numOfElements; iSrc++, pSrc++)
  677. {
  678. if(iSrc == arraySrc->m_numOfElements)
  679. {
  680. fFound = true;
  681. }
  682. else if ((count + 1) >= maxStrings)
  683. {
  684. fContinueSearching = false;
  685. }
  686. else if (fContinueSearching)
  687. {
  688. const CLR_UINT16* pCharsT = pChars;
  689. for(CLR_UINT32 iChars=0; iChars<cChars; iChars++)
  690. {
  691. if(pSrc[ 0 ] == *pCharsT++)
  692. {
  693. fFound = true;
  694. break;
  695. }
  696. }
  697. }
  698. if(fFound)
  699. {
  700. if(pass == 1)
  701. {
  702. CLR_RT_HeapBlock* str = (CLR_RT_HeapBlock*)arrayDst->GetElement( count );
  703. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_String::CreateInstance( *str, pSrcStart, (CLR_UINT32)(pSrc - pSrcStart) ));
  704. pSrcStart = pSrc + 1;
  705. }
  706. count++;
  707. fFound = false;
  708. }
  709. }
  710. if(pass == 0)
  711. {
  712. CLR_RT_HeapBlock& refTarget = stack.PushValue();
  713. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( refTarget, count, g_CLR_RT_WellKnownTypes.m_String ));
  714. arrayDst = refTarget.DereferenceArray();
  715. }
  716. }
  717. }
  718. }
  719. TINYCLR_NOCLEANUP();
  720. }
  721. //--//
  722. HRESULT Library_corlib_native_System_String::Concat( CLR_RT_StackFrame& stack, CLR_RT_HeapBlock* array, int num )
  723. {
  724. NATIVE_PROFILE_CLR_CORE();
  725. TINYCLR_HEADER();
  726. CLR_RT_HeapBlock* ptrSrc;
  727. LPCSTR szTextSrc;
  728. LPSTR szTextDst = NULL;
  729. CLR_UINT32 totLen;
  730. CLR_UINT32 len;
  731. totLen = 0;
  732. for(int i=0; i<2; i++)
  733. {
  734. ptrSrc = array;
  735. for(int iStr=0; iStr<num; iStr++)
  736. {
  737. _ASSERTE(ptrSrc->DataType() == DATATYPE_OBJECT);
  738. _ASSERTE(FIMPLIES(ptrSrc->Dereference(), ptrSrc->Dereference()->DataType() == DATATYPE_STRING));
  739. szTextSrc = ptrSrc->RecoverString();
  740. if(szTextSrc)
  741. {
  742. len = (CLR_UINT32)hal_strlen_s( szTextSrc );
  743. if(i==0)
  744. {
  745. totLen += len;
  746. }
  747. else
  748. {
  749. memcpy( szTextDst, szTextSrc, len );
  750. szTextDst += len;
  751. }
  752. }
  753. ptrSrc++;
  754. }
  755. if(i==0)
  756. {
  757. //push return value
  758. CLR_RT_HeapBlock& blkResult = stack.PushValue();
  759. CLR_RT_HeapBlock_String* str = CLR_RT_HeapBlock_String::CreateInstance( blkResult, totLen ); CHECK_ALLOCATION(str);
  760. szTextDst = (LPSTR)str->StringText();
  761. szTextDst[ totLen ] = 0;
  762. }
  763. }
  764. TINYCLR_NOCLEANUP();
  765. }
  766. HRESULT Library_corlib_native_System_String::ConvertToCharArray( LPCSTR szText, CLR_RT_HeapBlock& ref, CLR_RT_HeapBlock_Array*& array, int startIndex, int length )
  767. {
  768. NATIVE_PROFILE_CLR_CORE();
  769. TINYCLR_HEADER();
  770. CLR_RT_UnicodeHelper uh;
  771. int totLength;
  772. FAULT_ON_NULL(szText);
  773. uh.SetInputUTF8( szText );
  774. totLength = uh.CountNumberOfCharacters(); if(totLength < 0) TINYCLR_SET_AND_LEAVE(CLR_E_WRONG_TYPE);
  775. if(length == -1) length = totLength;
  776. if(CLR_RT_HeapBlock_Array::CheckRange( startIndex, length, totLength ) == false) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE);
  777. TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( ref, length, g_CLR_RT_WellKnownTypes.m_Char ));
  778. array = ref.DereferenceArray();
  779. uh.m_outputUTF16 = (CLR_UINT16*)array->GetFirstElement();
  780. uh.m_outputUTF16_size = array->m_numOfElements;
  781. //
  782. // First move to the character, then read it.
  783. //
  784. uh.ConvertFromUTF8( startIndex , true );
  785. uh.ConvertFromUTF8( array->m_numOfElements, false );
  786. TINYCLR_NOCLEANUP();
  787. }
  788. HRESULT Library_corlib_native_System_String::ConvertToCharArray( CLR_RT_StackFrame& stack, CLR_RT_HeapBlock& ref, CLR_RT_HeapBlock_Array*& array, int startIndex, int length )
  789. {
  790. NATIVE_PROFILE_CLR_CORE();
  791. return ConvertToCharArray( stack.Arg0().RecoverString(), ref, array, startIndex, length );
  792. }