Source code of Windows XP (NT5)
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.

3186 lines
92 KiB

  1. /***************************************************************************/
  2. /* UTIL.C */
  3. /* Copyright (C) 1995-96 SYWARE Inc., All rights reserved */
  4. /***************************************************************************/
  5. // Commenting #define out - causing compiler error - not sure if needed, compiles
  6. // okay without it.
  7. //#define WINVER 0x0400
  8. #include "precomp.h"
  9. #include "wbemidl.h"
  10. #include <comdef.h>
  11. //smart pointer
  12. _COM_SMARTPTR_TYPEDEF(IWbemServices, IID_IWbemServices);
  13. _COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, IID_IEnumWbemClassObject);
  14. //_COM_SMARTPTR_TYPEDEF(IWbemContext, IID_IWbemContext );
  15. _COM_SMARTPTR_TYPEDEF(IWbemLocator, IID_IWbemLocator);
  16. #include "drdbdr.h"
  17. #include <stdio.h>
  18. #include <time.h>
  19. /***************************************************************************/
  20. #define BIT_LOW_D ( 0.0)
  21. #define BIT_HIGH_D ( 1.0)
  22. #define STINY_LOW_D ( -128.0)
  23. #define STINY_HIGH_D ( 127.0)
  24. #define UTINY_LOW_D ( 0.0)
  25. #define UTINY_HIGH_D ( 255.0)
  26. #define SSHORT_LOW_D ( -32768.0)
  27. #define SSHORT_HIGH_D ( 32767.0)
  28. #define USHORT_LOW_D ( 0.0)
  29. #define USHORT_HIGH_D ( 65535.0)
  30. #define SLONG_LOW_D (-2147483648.0)
  31. #define SLONG_HIGH_D ( 2147483647.0)
  32. #define ULONG_LOW_D ( 0.0)
  33. #define ULONG_HIGH_D ( 4294967296.0)
  34. #define FLOAT_LOW_D ( -3.4E38)
  35. #define FLOAT_HIGH_D ( 3.4E38)
  36. #define DOUBLE_LOW_D ( -1.7E308)
  37. #define DOUBLE_HIGH_D ( 1.7E308)
  38. #define BIT_LOW_I ( 0)
  39. #define BIT_HIGH_I ( 1)
  40. #define STINY_LOW_I ( -128)
  41. #define STINY_HIGH_I ( 127)
  42. #define UTINY_LOW_I ( 0)
  43. #define UTINY_HIGH_I ( 255)
  44. #define SSHORT_LOW_I ( -32768)
  45. #define SSHORT_HIGH_I ( 32767)
  46. #define USHORT_LOW_I ( 0)
  47. #define USHORT_HIGH_I ( 65535)
  48. #define SLONG_LOW_I (-2147483648)
  49. #define SLONG_HIGH_I ( 2147483647)
  50. #define ULONG_LOW_I ( 0)
  51. #define ULONG_HIGH_I ( 4294967295)
  52. /***************************************************************************/
  53. RETCODE INTFUNC CharToDouble (
  54. LPUSTR lpChar,
  55. SDWORD cbChar,
  56. BOOL fIntegerOnly,
  57. double dblLowBound,
  58. double dblHighBound,
  59. double FAR *lpDouble)
  60. {
  61. BOOL fNegative;
  62. SWORD iScale;
  63. RETCODE rc;
  64. BOOL fNegExp;
  65. SWORD iExponent;
  66. BOOL fFirstDigit;
  67. double scaleFactor;
  68. /* Deal with "bad" lengths */
  69. if (cbChar == SQL_NTS)
  70. cbChar = s_lstrlen(lpChar);
  71. if (cbChar < 0)
  72. cbChar = 0;
  73. /* Strip off leading blanks */
  74. while ((cbChar != 0) && (*lpChar == ' ')) {
  75. lpChar++;
  76. cbChar--;
  77. }
  78. /* Start looking for the number */
  79. fFirstDigit = TRUE;
  80. /* Get sign */
  81. if (cbChar != 0) {
  82. switch (*lpChar) {
  83. case '-':
  84. fNegative = TRUE;
  85. lpChar++;
  86. cbChar--;
  87. fFirstDigit = FALSE;
  88. break;
  89. case '+':
  90. fNegative = FALSE;
  91. lpChar++;
  92. cbChar--;
  93. fFirstDigit = FALSE;
  94. break;
  95. default:
  96. fNegative = FALSE;
  97. break;
  98. }
  99. }
  100. /* Error if empty */
  101. // if (cbChar == 0)
  102. // return ERR_ASSIGNMENTERROR;
  103. /* Get number */
  104. iScale = -1;
  105. *lpDouble = 0.0;
  106. rc = ERR_SUCCESS;
  107. fNegExp = FALSE;
  108. iExponent = 0;
  109. while ((cbChar != 0) && (*lpChar != ' ')) {
  110. switch (*lpChar) {
  111. case '0':
  112. *lpDouble = (*lpDouble * 10.0) + (*lpChar - '0');
  113. if (iScale != -1)
  114. iScale++;
  115. fFirstDigit = FALSE;
  116. break;
  117. case '1':
  118. case '2':
  119. case '3':
  120. case '4':
  121. case '5':
  122. case '6':
  123. case '7':
  124. case '8':
  125. case '9':
  126. *lpDouble = (*lpDouble * 10.0) + (*lpChar - '0');
  127. if (iScale != -1) {
  128. if (fIntegerOnly)
  129. rc = ERR_DATATRUNCATED;
  130. iScale++;
  131. }
  132. fFirstDigit = FALSE;
  133. break;
  134. case '.':
  135. if (iScale != -1)
  136. return ERR_ASSIGNMENTERROR;
  137. iScale = 0;
  138. fFirstDigit = FALSE;
  139. break;
  140. case 'E':
  141. case 'e':
  142. if (fFirstDigit)
  143. return ERR_ASSIGNMENTERROR;
  144. lpChar++;
  145. cbChar--;
  146. if (cbChar == 0)
  147. return ERR_ASSIGNMENTERROR;
  148. switch (*lpChar)
  149. {
  150. case '-':
  151. fNegExp = TRUE;
  152. lpChar++;
  153. cbChar--;
  154. break;
  155. case '+':
  156. lpChar++;
  157. cbChar--;
  158. break;
  159. default:
  160. break;
  161. }
  162. if ((cbChar == 0) || (*lpChar == ' '))
  163. return ERR_ASSIGNMENTERROR;
  164. while ((cbChar != 0) && (*lpChar != ' '))
  165. {
  166. switch (*lpChar)
  167. {
  168. case '0':
  169. case '1':
  170. case '2':
  171. case '3':
  172. case '4':
  173. case '5':
  174. case '6':
  175. case '7':
  176. case '8':
  177. case '9':
  178. iExponent = (iExponent * 10) + (*lpChar - '0');
  179. break;
  180. default:
  181. return ERR_ASSIGNMENTERROR;
  182. }
  183. lpChar++;
  184. cbChar--;
  185. }
  186. lpChar--;
  187. cbChar++;
  188. break;
  189. default:
  190. return ERR_ASSIGNMENTERROR;
  191. }
  192. lpChar++;
  193. cbChar--;
  194. }
  195. /* Strip off trailing blanks */
  196. while ((cbChar != 0) && (*lpChar == ' ')) {
  197. lpChar++;
  198. cbChar--;
  199. }
  200. /* Error if garbage at the end of the string */
  201. if (cbChar != 0)
  202. return ERR_ASSIGNMENTERROR;
  203. /* Adjust for scale */
  204. if (iScale == -1)
  205. iScale = 0;
  206. iScale = -iScale;
  207. if (fNegExp)
  208. iScale -= (iExponent);
  209. else
  210. iScale += (iExponent);
  211. scaleFactor = 1.0;
  212. while (iScale > 0) {
  213. scaleFactor = scaleFactor * 10.0;
  214. iScale--;
  215. }
  216. *lpDouble = *lpDouble * scaleFactor;
  217. scaleFactor = 1.0;
  218. while (iScale < 0) {
  219. scaleFactor = scaleFactor * 10.0;
  220. iScale++;
  221. }
  222. *lpDouble = *lpDouble / scaleFactor;
  223. /* Adjust for negative */
  224. if (fNegative)
  225. *lpDouble = -(*lpDouble);
  226. /* Error if out of range */
  227. if ((dblLowBound > *lpDouble) || (*lpDouble > dblHighBound))
  228. return ERR_OUTOFRANGE;
  229. return rc;
  230. }
  231. /***************************************************************************/
  232. BOOL INTFUNC DoubleToChar (
  233. double dbl,
  234. BOOL ScientificNotationOK,
  235. LPUSTR lpChar,
  236. SDWORD cbChar)
  237. {
  238. #ifdef WIN32
  239. UCHAR szBuffer[350];
  240. #else
  241. #ifdef _UNIX_
  242. UCHAR szBuffer[350];
  243. #else
  244. static UCHAR szBuffer[350];
  245. #endif
  246. #endif
  247. LPUSTR ptr;
  248. szBuffer[0] = 0;
  249. sprintf ((char*)szBuffer, "%lf", dbl);
  250. ptr = szBuffer;
  251. while (*ptr != '\0')
  252. {
  253. if (*ptr == '.')
  254. {
  255. ptr = (szBuffer) + s_lstrlen(szBuffer) - 1;
  256. while (ptr > (LPUSTR)szBuffer)
  257. {
  258. if (*ptr == '.')
  259. {
  260. *ptr = '\0';
  261. break;
  262. }
  263. if (*ptr != '0')
  264. break;
  265. *ptr = '\0';
  266. ptr--;
  267. }
  268. break;
  269. }
  270. ptr++;
  271. }
  272. if (s_lstrlen((char*)szBuffer) < cbChar)
  273. {
  274. if (!s_lstrcmp((char*)szBuffer, "0") && (dbl != 0.0) && ScientificNotationOK)
  275. {
  276. sprintf((char*)szBuffer, "%lE", dbl);
  277. if (s_lstrlen((char*)szBuffer) >= cbChar)
  278. return DoubleToChar(dbl, FALSE, lpChar, cbChar);
  279. }
  280. s_lstrcpy(lpChar, (char*)szBuffer);
  281. return FALSE;
  282. }
  283. else if (ScientificNotationOK)
  284. {
  285. sprintf((char*)szBuffer, "%lE", dbl);
  286. if (s_lstrlen((char*)szBuffer) >= cbChar)
  287. return DoubleToChar(dbl, FALSE, lpChar, cbChar);
  288. lstrcpy((char*)lpChar, (char*)szBuffer);
  289. return FALSE;
  290. }
  291. else
  292. {
  293. _fmemcpy(lpChar, szBuffer, (SWORD) cbChar);
  294. return TRUE;
  295. }
  296. }
  297. /***************************************************************************/
  298. RETCODE INTFUNC ReturnString (
  299. PTR rgbValue,
  300. SWORD cbValueMax,
  301. SWORD FAR *pcbValue,
  302. LPCUSTR lpstr)
  303. {
  304. SWORD len;
  305. /* Get the length of the string */
  306. len = (SWORD) s_lstrlen(lpstr);
  307. /* Return length if need be */
  308. if (pcbValue != NULL)
  309. *pcbValue = len;
  310. /* Return string value if need be */
  311. if (rgbValue != NULL) {
  312. /* If string fits, just copy it */
  313. if (cbValueMax > len)
  314. s_lstrcpy((char*)rgbValue, lpstr);
  315. /* Otherwise truncate it to fit */
  316. else {
  317. if (cbValueMax > 0) {
  318. _fmemcpy(rgbValue, lpstr, cbValueMax);
  319. ((LPSTR)rgbValue)[cbValueMax-1] = '\0';
  320. }
  321. return ERR_DATATRUNCATED;
  322. }
  323. }
  324. return ERR_SUCCESS;
  325. }
  326. /***************************************************************************/
  327. RETCODE INTFUNC ReturnStringD (
  328. PTR rgbValue,
  329. SDWORD cbValueMax,
  330. SDWORD FAR *pcbValue,
  331. LPCUSTR lpstr)
  332. {
  333. SWORD len;
  334. /* Get the length of the string */
  335. len = (SWORD) s_lstrlen(lpstr);
  336. /* Return length if need be */
  337. if (pcbValue != NULL)
  338. *pcbValue = len;
  339. /* Return string value if need be */
  340. if (rgbValue != NULL) {
  341. /* If string fits, just copy it */
  342. if (cbValueMax > len)
  343. s_lstrcpy((char*)rgbValue, lpstr);
  344. /* Otherwise truncate it to fit */
  345. else {
  346. if (cbValueMax > 0) {
  347. _fmemcpy(rgbValue, lpstr, cbValueMax);
  348. ((LPSTR)rgbValue)[cbValueMax-1] = '\0';
  349. }
  350. return ERR_DATATRUNCATED;
  351. }
  352. }
  353. return ERR_SUCCESS;
  354. }
  355. /***************************************************************************/
  356. RETCODE INTFUNC ConvertSqlToC (
  357. SWORD fSqlTypeIn,
  358. BOOL fUnsignedAttributeIn,
  359. PTR rgbValueIn,
  360. SDWORD cbValueIn,
  361. SDWORD FAR *pcbOffset,
  362. SWORD fCTypeOut,
  363. PTR rgbValueOut,
  364. SDWORD cbValueOutMax,
  365. SDWORD FAR *pcbValueOut)
  366. {
  367. SDWORD cbValue;
  368. BOOL fTruncated;
  369. RETCODE rc;
  370. UCHAR szBuffer[32];
  371. unsigned char uchar;
  372. char schar;
  373. unsigned short ushort;
  374. short sshort;
  375. unsigned long ulong;
  376. long slong;
  377. double dbl;
  378. float flt;
  379. DATE_STRUCT sDate;
  380. TIME_STRUCT sTime;
  381. TIMESTAMP_STRUCT sTimestamp;
  382. DATE_STRUCT FAR * lpDate;
  383. TIME_STRUCT FAR * lpTime;
  384. TIMESTAMP_STRUCT FAR * lpTimestamp;
  385. static time_t t;
  386. struct tm *ts;
  387. LPUSTR lpFrom;
  388. LPUSTR lpTo;
  389. SDWORD i;
  390. UCHAR nibble;
  391. /* If input is NULL, return NULL */
  392. if ((cbValueIn == SQL_NULL_DATA) || (rgbValueIn == NULL)) {
  393. /* Return NULL */
  394. if (pcbValueOut != NULL)
  395. *pcbValueOut = cbValueIn;
  396. /* If an rgbValueOut was given, put some reasonable value in it also */
  397. if ((rgbValueOut != NULL) && (cbValueIn == SQL_NULL_DATA)) {
  398. /* Convert SQL_C_DEFAULT to a real SQL_C_* type */
  399. if (SQL_C_DEFAULT == fCTypeOut) {
  400. switch (fSqlTypeIn) {
  401. case SQL_CHAR:
  402. case SQL_VARCHAR:
  403. case SQL_LONGVARCHAR:
  404. fCTypeOut = SQL_C_CHAR;
  405. break;
  406. case SQL_BIT:
  407. fCTypeOut = SQL_C_BIT;
  408. break;
  409. case SQL_TINYINT:
  410. fCTypeOut = SQL_C_TINYINT;
  411. break;
  412. case SQL_SMALLINT:
  413. fCTypeOut = SQL_C_SHORT;
  414. break;
  415. case SQL_INTEGER:
  416. fCTypeOut = SQL_C_LONG;
  417. break;
  418. case SQL_REAL:
  419. fCTypeOut = SQL_C_FLOAT;
  420. break;
  421. case SQL_DECIMAL:
  422. case SQL_NUMERIC:
  423. case SQL_BIGINT:
  424. fCTypeOut = SQL_C_CHAR;
  425. break;
  426. case SQL_FLOAT:
  427. case SQL_DOUBLE:
  428. fCTypeOut = SQL_C_DOUBLE;
  429. break;
  430. case SQL_BINARY:
  431. case SQL_VARBINARY:
  432. case SQL_LONGVARBINARY:
  433. fCTypeOut = SQL_C_BINARY;
  434. break;
  435. case SQL_DATE:
  436. fCTypeOut = SQL_C_DATE;
  437. break;
  438. case SQL_TIME:
  439. fCTypeOut = SQL_C_TIME;
  440. break;
  441. case SQL_TIMESTAMP:
  442. fCTypeOut = SQL_C_TIMESTAMP;
  443. break;
  444. default:
  445. return ERR_NOTCAPABLE;
  446. }
  447. }
  448. /* Return a NULL value */
  449. switch (fCTypeOut) {
  450. case SQL_C_CHAR:
  451. if (cbValueOutMax > 0)
  452. *((LPSTR) rgbValueOut) = '\0';
  453. break;
  454. case SQL_C_SHORT:
  455. case SQL_C_SSHORT:
  456. case SQL_C_USHORT:
  457. *((short far *) rgbValueOut) = 0;
  458. break;
  459. case SQL_C_LONG:
  460. case SQL_C_SLONG:
  461. case SQL_C_ULONG:
  462. *((long far *) rgbValueOut) = 0;
  463. break;
  464. case SQL_C_FLOAT:
  465. *((float far *) rgbValueOut) = (float) 0.0;
  466. break;
  467. case SQL_C_DOUBLE:
  468. *((double far *) rgbValueOut) = 0.0;
  469. break;
  470. case SQL_C_BIT:
  471. *((char far *) rgbValueOut) = 0;
  472. break;
  473. case SQL_C_TINYINT:
  474. case SQL_C_STINYINT:
  475. case SQL_C_UTINYINT:
  476. *((char far *) rgbValueOut) = 0;
  477. break;
  478. case SQL_C_BINARY:
  479. break;
  480. case SQL_C_DATE:
  481. ((DATE_STRUCT far *) rgbValueOut)->year = 0;
  482. ((DATE_STRUCT far *) rgbValueOut)->month = 0;
  483. ((DATE_STRUCT far *) rgbValueOut)->day = 0;
  484. break;
  485. case SQL_C_TIME:
  486. ((TIME_STRUCT far *) rgbValueOut)->hour = 0;
  487. ((TIME_STRUCT far *) rgbValueOut)->minute = 0;
  488. ((TIME_STRUCT far *) rgbValueOut)->second = 0;
  489. break;
  490. case SQL_C_TIMESTAMP:
  491. ((TIMESTAMP_STRUCT far *) rgbValueOut)->year = 0;
  492. ((TIMESTAMP_STRUCT far *) rgbValueOut)->month = 0;
  493. ((TIMESTAMP_STRUCT far *) rgbValueOut)->day = 0;
  494. ((TIMESTAMP_STRUCT far *) rgbValueOut)->hour = 0;
  495. ((TIMESTAMP_STRUCT far *) rgbValueOut)->minute = 0;
  496. ((TIMESTAMP_STRUCT far *) rgbValueOut)->second = 0;
  497. ((TIMESTAMP_STRUCT far *) rgbValueOut)->fraction = 0;
  498. break;
  499. default:
  500. return ERR_NOTCONVERTABLE;
  501. }
  502. }
  503. return ERR_SUCCESS;
  504. }
  505. /* Figure out if the type is signed or unsigned */
  506. // lpSqlType = GetType(fSqlTypeIn);
  507. // if (lpSqlType == NULL)
  508. // unsignedAttribute = FALSE;
  509. // else if (lpSqlType->unsignedAttribute == -1)
  510. // unsignedAttribute = FALSE;
  511. // else
  512. // unsignedAttribute = lpSqlType->unsignedAttribute;
  513. //
  514. // //If signed column info is passed through used this
  515. // if (fIsSigned)
  516. // unsignedAttribute = -1;
  517. /* Convert the data */
  518. fTruncated = FALSE;
  519. switch (fSqlTypeIn) {
  520. case SQL_CHAR:
  521. case SQL_VARCHAR:
  522. case SQL_LONGVARCHAR:
  523. case SQL_DECIMAL:
  524. case SQL_NUMERIC:
  525. case SQL_BIGINT:
  526. switch (fCTypeOut) {
  527. case SQL_C_DEFAULT:
  528. case SQL_C_CHAR:
  529. /* Get length of input string */
  530. if (cbValueIn == SQL_NTS)
  531. cbValueIn = s_lstrlen((char*)rgbValueIn);
  532. else if (cbValueIn < 0)
  533. cbValueIn = 0;
  534. /* Figure out how many bytes to copy */
  535. cbValue = cbValueIn - *pcbOffset;
  536. if (cbValue >= cbValueOutMax) {
  537. cbValue = cbValueOutMax-1;
  538. fTruncated = TRUE;
  539. }
  540. /* Copy the string */
  541. if (rgbValueOut != NULL) {
  542. _fmemcpy(rgbValueOut, ((LPSTR) rgbValueIn) + *pcbOffset,
  543. (SWORD) cbValue);
  544. ((LPSTR) rgbValueOut)[cbValue] = '\0';
  545. }
  546. if (pcbValueOut != NULL)
  547. *pcbValueOut = cbValueIn - *pcbOffset;
  548. /* Adjust offset */
  549. *pcbOffset += (cbValue);
  550. break;
  551. case SQL_C_SHORT:
  552. case SQL_C_SSHORT:
  553. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, SSHORT_LOW_D,
  554. SSHORT_HIGH_D, &dbl);
  555. if (rc == ERR_DATATRUNCATED)
  556. fTruncated = TRUE;
  557. else if (rc != ERR_SUCCESS)
  558. return rc;
  559. if (rgbValueOut != NULL)
  560. *((short far *) rgbValueOut) = (short) dbl;
  561. if (pcbValueOut != NULL)
  562. *pcbValueOut = 2;
  563. break;
  564. case SQL_C_USHORT:
  565. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, USHORT_LOW_D,
  566. USHORT_HIGH_D, &dbl);
  567. if (rc == ERR_DATATRUNCATED)
  568. fTruncated = TRUE;
  569. else if (rc != ERR_SUCCESS)
  570. return rc;
  571. if (rgbValueOut != NULL)
  572. *((unsigned short far *) rgbValueOut) = (unsigned short) dbl;
  573. if (pcbValueOut != NULL)
  574. *pcbValueOut = 2;
  575. break;
  576. case SQL_C_LONG:
  577. case SQL_C_SLONG:
  578. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, SLONG_LOW_D,
  579. SLONG_HIGH_D, &dbl);
  580. if (rc == ERR_DATATRUNCATED)
  581. fTruncated = TRUE;
  582. else if (rc != ERR_SUCCESS)
  583. return rc;
  584. if (rgbValueOut != NULL)
  585. *((long far *) rgbValueOut) = (long) dbl;
  586. if (pcbValueOut != NULL)
  587. *pcbValueOut = 4;
  588. break;
  589. case SQL_C_ULONG:
  590. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, ULONG_LOW_D,
  591. ULONG_HIGH_D, &dbl);
  592. if (rc == ERR_DATATRUNCATED)
  593. fTruncated = TRUE;
  594. else if (rc != ERR_SUCCESS)
  595. return rc;
  596. if (rgbValueOut != NULL)
  597. *((unsigned long far *) rgbValueOut) = (unsigned long) dbl;
  598. if (pcbValueOut != NULL)
  599. *pcbValueOut = 4;
  600. break;
  601. case SQL_C_FLOAT:
  602. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, FALSE, FLOAT_LOW_D,
  603. FLOAT_HIGH_D, &dbl);
  604. if (rc != ERR_SUCCESS)
  605. return rc;
  606. if (rgbValueOut != NULL)
  607. *((float far *) rgbValueOut) = (float) dbl;
  608. if (pcbValueOut != NULL)
  609. *pcbValueOut = 4;
  610. break;
  611. case SQL_C_DOUBLE:
  612. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, FALSE, DOUBLE_LOW_D,
  613. DOUBLE_HIGH_D, &dbl);
  614. if (rc != ERR_SUCCESS)
  615. return rc;
  616. if (rgbValueOut != NULL)
  617. *((double far *) rgbValueOut) = (double) dbl;
  618. if (pcbValueOut != NULL)
  619. *pcbValueOut = 8;
  620. break;
  621. case SQL_C_BIT:
  622. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, BIT_LOW_D,
  623. BIT_HIGH_D, &dbl);
  624. if (rc == ERR_DATATRUNCATED)
  625. fTruncated = TRUE;
  626. else if (rc != ERR_SUCCESS)
  627. return rc;
  628. if (rgbValueOut != NULL)
  629. *((unsigned char far *) rgbValueOut) = (unsigned char) dbl;
  630. if (pcbValueOut != NULL)
  631. *pcbValueOut = 1;
  632. break;
  633. case SQL_C_TINYINT:
  634. case SQL_C_STINYINT:
  635. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, STINY_LOW_D,
  636. STINY_HIGH_D, &dbl);
  637. if (rc == ERR_DATATRUNCATED)
  638. fTruncated = TRUE;
  639. else if (rc != ERR_SUCCESS)
  640. return rc;
  641. if (rgbValueOut != NULL)
  642. *((char far *) rgbValueOut) = (char) dbl;
  643. if (pcbValueOut != NULL)
  644. *pcbValueOut = 1;
  645. break;
  646. case SQL_C_UTINYINT:
  647. rc = CharToDouble((LPUSTR)rgbValueIn, cbValueIn, TRUE, UTINY_LOW_D,
  648. UTINY_HIGH_D, &dbl);
  649. if (rc == ERR_DATATRUNCATED)
  650. fTruncated = TRUE;
  651. else if (rc != ERR_SUCCESS)
  652. return rc;
  653. if (rgbValueOut != NULL)
  654. *((unsigned char far *) rgbValueOut) = (unsigned char) dbl;
  655. if (pcbValueOut != NULL)
  656. *pcbValueOut = 1;
  657. break;
  658. case SQL_C_DATE:
  659. rc = CharToDate((LPUSTR)rgbValueIn, cbValueIn, &sDate);
  660. if (rc == ERR_DATATRUNCATED)
  661. fTruncated = TRUE;
  662. else if (rc != ERR_SUCCESS)
  663. return rc;
  664. if (rgbValueOut != NULL)
  665. *((DATE_STRUCT far *) rgbValueOut) = sDate;
  666. if (pcbValueOut != NULL)
  667. *pcbValueOut = 6;
  668. break;
  669. case SQL_C_TIME:
  670. rc = CharToTime((LPUSTR)rgbValueIn, cbValueIn, &sTime);
  671. if (rc == ERR_DATATRUNCATED)
  672. fTruncated = TRUE;
  673. else if (rc != ERR_SUCCESS)
  674. return rc;
  675. if (rgbValueOut != NULL)
  676. *((TIME_STRUCT far *) rgbValueOut) = sTime;
  677. if (pcbValueOut != NULL)
  678. *pcbValueOut = 6;
  679. break;
  680. case SQL_C_TIMESTAMP:
  681. rc = CharToTimestamp((LPUSTR)rgbValueIn, cbValueIn, &sTimestamp);
  682. if (rc == ERR_DATATRUNCATED)
  683. fTruncated = TRUE;
  684. else if (rc != ERR_SUCCESS)
  685. return rc;
  686. if (rgbValueOut != NULL)
  687. *((TIMESTAMP_STRUCT far *) rgbValueOut) = sTimestamp;
  688. if (pcbValueOut != NULL)
  689. *pcbValueOut = 16;
  690. break;
  691. case SQL_C_BINARY:
  692. /* Get length of input string */
  693. if (cbValueIn == SQL_NTS)
  694. cbValueIn = s_lstrlen((char*)rgbValueIn);
  695. else if (cbValueIn < 0)
  696. cbValueIn = 0;
  697. /* Figure out how many bytes to copy */
  698. cbValue = cbValueIn - *pcbOffset;
  699. if (cbValue >= cbValueOutMax) {
  700. cbValue = cbValueOutMax;
  701. fTruncated = TRUE;
  702. }
  703. /* Copy the string */
  704. if (rgbValueOut != NULL) {
  705. _fmemcpy(rgbValueOut, ((LPSTR) rgbValueIn) + *pcbOffset,
  706. (SWORD) cbValue);
  707. }
  708. if (pcbValueOut != NULL)
  709. *pcbValueOut = cbValueIn - *pcbOffset;
  710. /* Adjust offset */
  711. *pcbOffset += (cbValue);
  712. break;
  713. default:
  714. return ERR_NOTCONVERTABLE;
  715. }
  716. break;
  717. case SQL_BIT:
  718. if (*((unsigned char far *) rgbValueIn))
  719. uchar = 1;
  720. else
  721. uchar = 0;
  722. switch (fCTypeOut) {
  723. case SQL_C_CHAR:
  724. if (uchar)
  725. return ConvertSqlToC(SQL_VARCHAR, FALSE, "1", 1,
  726. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  727. pcbValueOut);
  728. else
  729. return ConvertSqlToC(SQL_VARCHAR, FALSE, "0", 1,
  730. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  731. pcbValueOut);
  732. case SQL_C_SHORT:
  733. case SQL_C_SSHORT:
  734. if (rgbValueOut != NULL)
  735. *((short far *) rgbValueOut) = (short) uchar;
  736. if (pcbValueOut != NULL)
  737. *pcbValueOut = 2;
  738. break;
  739. case SQL_C_USHORT:
  740. if (rgbValueOut != NULL)
  741. *((unsigned short far *) rgbValueOut) = (unsigned short) uchar;
  742. if (pcbValueOut != NULL)
  743. *pcbValueOut = 2;
  744. break;
  745. case SQL_C_LONG:
  746. case SQL_C_SLONG:
  747. if (rgbValueOut != NULL)
  748. *((long far *) rgbValueOut) = (long) uchar;
  749. if (pcbValueOut != NULL)
  750. *pcbValueOut = 4;
  751. break;
  752. case SQL_C_ULONG:
  753. if (rgbValueOut != NULL)
  754. *((unsigned long far *) rgbValueOut) = (unsigned long) uchar;
  755. if (pcbValueOut != NULL)
  756. *pcbValueOut = 4;
  757. break;
  758. case SQL_C_FLOAT:
  759. if (rgbValueOut != NULL)
  760. *((float far *) rgbValueOut) = (float) uchar;
  761. if (pcbValueOut != NULL)
  762. *pcbValueOut = 4;
  763. break;
  764. case SQL_C_DOUBLE:
  765. if (rgbValueOut != NULL)
  766. *((double far *) rgbValueOut) = (double) uchar;
  767. if (pcbValueOut != NULL)
  768. *pcbValueOut = 8;
  769. break;
  770. case SQL_C_DEFAULT:
  771. case SQL_C_BIT:
  772. if (rgbValueOut != NULL)
  773. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  774. if (pcbValueOut != NULL)
  775. *pcbValueOut = 1;
  776. break;
  777. case SQL_C_TINYINT:
  778. case SQL_C_STINYINT:
  779. if (rgbValueOut != NULL)
  780. *((char far *) rgbValueOut) = (char) uchar;
  781. if (pcbValueOut != NULL)
  782. *pcbValueOut = 1;
  783. break;
  784. case SQL_C_UTINYINT:
  785. if (rgbValueOut != NULL)
  786. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  787. if (pcbValueOut != NULL)
  788. *pcbValueOut = 1;
  789. break;
  790. case SQL_C_DATE:
  791. return ERR_NOTCONVERTABLE;
  792. case SQL_C_TIME:
  793. return ERR_NOTCONVERTABLE;
  794. case SQL_C_TIMESTAMP:
  795. return ERR_NOTCONVERTABLE;
  796. case SQL_C_BINARY:
  797. if (rgbValueOut != NULL)
  798. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  799. if (pcbValueOut != NULL)
  800. *pcbValueOut = 1;
  801. break;
  802. default:
  803. return ERR_NOTCONVERTABLE;
  804. }
  805. break;
  806. case SQL_TINYINT:
  807. if (fUnsignedAttributeIn)
  808. uchar = *((unsigned char far *) rgbValueIn);
  809. else
  810. schar = *((char far *) rgbValueIn);
  811. switch (fCTypeOut) {
  812. case SQL_C_CHAR:
  813. if (fUnsignedAttributeIn)
  814. wsprintf((LPSTR)szBuffer, "%u", (unsigned short) uchar);
  815. else
  816. wsprintf((LPSTR)szBuffer, "%d", (short) schar);
  817. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  818. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  819. pcbValueOut);
  820. case SQL_C_SHORT:
  821. case SQL_C_SSHORT:
  822. if (rgbValueOut != NULL) {
  823. if (fUnsignedAttributeIn)
  824. *((short far *) rgbValueOut) = (short) uchar;
  825. else
  826. *((short far *) rgbValueOut) = (short) schar;
  827. }
  828. if (pcbValueOut != NULL)
  829. *pcbValueOut = 2;
  830. break;
  831. case SQL_C_USHORT:
  832. if (rgbValueOut != NULL) {
  833. if (fUnsignedAttributeIn)
  834. *((unsigned short far *) rgbValueOut) = (unsigned short) uchar;
  835. else {
  836. if (schar < USHORT_LOW_I)
  837. return ERR_OUTOFRANGE;
  838. *((unsigned short far *) rgbValueOut) = (unsigned short) schar;
  839. }
  840. }
  841. if (pcbValueOut != NULL)
  842. *pcbValueOut = 2;
  843. break;
  844. case SQL_C_LONG:
  845. case SQL_C_SLONG:
  846. if (rgbValueOut != NULL) {
  847. if (fUnsignedAttributeIn)
  848. *((long far *) rgbValueOut) = (long) uchar;
  849. else
  850. *((long far *) rgbValueOut) = (long) schar;
  851. }
  852. if (pcbValueOut != NULL)
  853. *pcbValueOut = 4;
  854. break;
  855. case SQL_C_ULONG:
  856. if (rgbValueOut != NULL) {
  857. if (fUnsignedAttributeIn)
  858. *((unsigned long far *) rgbValueOut) = (unsigned long) uchar;
  859. else {
  860. if (schar < ULONG_LOW_I)
  861. return ERR_OUTOFRANGE;
  862. *((unsigned long far *) rgbValueOut) = (unsigned long) schar;
  863. }
  864. }
  865. if (pcbValueOut != NULL)
  866. *pcbValueOut = 4;
  867. break;
  868. case SQL_C_FLOAT:
  869. if (rgbValueOut != NULL) {
  870. if (fUnsignedAttributeIn)
  871. *((float far *) rgbValueOut) = (float) uchar;
  872. else
  873. *((float far *) rgbValueOut) = (float) schar;
  874. }
  875. if (pcbValueOut != NULL)
  876. *pcbValueOut = 4;
  877. break;
  878. case SQL_C_DOUBLE:
  879. if (rgbValueOut != NULL) {
  880. if (fUnsignedAttributeIn)
  881. *((double far *) rgbValueOut) = (double) uchar;
  882. else
  883. *((double far *) rgbValueOut) = (double) schar;
  884. }
  885. if (pcbValueOut != NULL)
  886. *pcbValueOut = 8;
  887. break;
  888. case SQL_C_BIT:
  889. if (rgbValueOut != NULL) {
  890. if (fUnsignedAttributeIn) {
  891. if (uchar > BIT_HIGH_I)
  892. return ERR_OUTOFRANGE;
  893. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  894. }
  895. else {
  896. if ((schar < BIT_LOW_I) || (schar > BIT_HIGH_I))
  897. return ERR_OUTOFRANGE;
  898. *((unsigned char far *) rgbValueOut) = (unsigned char) schar;
  899. }
  900. }
  901. if (pcbValueOut != NULL)
  902. *pcbValueOut = 1;
  903. break;
  904. case SQL_C_TINYINT:
  905. case SQL_C_STINYINT:
  906. if (rgbValueOut != NULL) {
  907. if (fUnsignedAttributeIn) {
  908. if (uchar > STINY_HIGH_I)
  909. return ERR_OUTOFRANGE;
  910. *((char far *) rgbValueOut) = (char) uchar;
  911. }
  912. else
  913. *((char far *) rgbValueOut) = (char) schar;
  914. }
  915. if (pcbValueOut != NULL)
  916. *pcbValueOut = 1;
  917. break;
  918. case SQL_C_UTINYINT:
  919. if (rgbValueOut != NULL) {
  920. if (fUnsignedAttributeIn)
  921. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  922. else {
  923. if (schar < UTINY_LOW_I)
  924. return ERR_OUTOFRANGE;
  925. *((unsigned char far *) rgbValueOut) = (unsigned char) schar;
  926. }
  927. }
  928. if (pcbValueOut != NULL)
  929. *pcbValueOut = 1;
  930. break;
  931. case SQL_C_DEFAULT:
  932. if (rgbValueOut != NULL) {
  933. if (fUnsignedAttributeIn)
  934. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  935. else
  936. *((char far *) rgbValueOut) = (char) schar;
  937. }
  938. if (pcbValueOut != NULL)
  939. *pcbValueOut = 1;
  940. break;
  941. case SQL_C_DATE:
  942. return ERR_NOTCONVERTABLE;
  943. case SQL_C_TIME:
  944. return ERR_NOTCONVERTABLE;
  945. case SQL_C_TIMESTAMP:
  946. return ERR_NOTCONVERTABLE;
  947. case SQL_C_BINARY:
  948. if (rgbValueOut != NULL) {
  949. if (fUnsignedAttributeIn)
  950. *((unsigned char far *) rgbValueOut) = (unsigned char) uchar;
  951. else
  952. *((char far *) rgbValueOut) = (char) schar;
  953. }
  954. if (pcbValueOut != NULL)
  955. *pcbValueOut = 1;
  956. break;
  957. default:
  958. return ERR_NOTCONVERTABLE;
  959. }
  960. break;
  961. case SQL_SMALLINT:
  962. if (fUnsignedAttributeIn)
  963. ushort = *((unsigned short far *) rgbValueIn);
  964. else
  965. sshort = *((short far *) rgbValueIn);
  966. switch (fCTypeOut) {
  967. case SQL_C_CHAR:
  968. if (fUnsignedAttributeIn)
  969. wsprintf((LPSTR)szBuffer, "%u", (unsigned short) ushort);
  970. else
  971. wsprintf((LPSTR)szBuffer, "%d", (short) sshort);
  972. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  973. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  974. pcbValueOut);
  975. case SQL_C_SHORT:
  976. case SQL_C_SSHORT:
  977. if (rgbValueOut != NULL) {
  978. if (fUnsignedAttributeIn) {
  979. if (ushort > SSHORT_HIGH_I)
  980. return ERR_OUTOFRANGE;
  981. *((short far *) rgbValueOut) = (short) ushort;
  982. }
  983. else
  984. *((short far *) rgbValueOut) = (short) sshort;
  985. }
  986. if (pcbValueOut != NULL)
  987. *pcbValueOut = 2;
  988. break;
  989. case SQL_C_USHORT:
  990. if (rgbValueOut != NULL) {
  991. if (fUnsignedAttributeIn)
  992. *((unsigned short far *) rgbValueOut) = (unsigned short) ushort;
  993. else {
  994. if (sshort < USHORT_LOW_I)
  995. return ERR_OUTOFRANGE;
  996. *((unsigned short far *) rgbValueOut) = (unsigned short) sshort;
  997. }
  998. }
  999. if (pcbValueOut != NULL)
  1000. *pcbValueOut = 2;
  1001. break;
  1002. case SQL_C_LONG:
  1003. case SQL_C_SLONG:
  1004. if (rgbValueOut != NULL) {
  1005. if (fUnsignedAttributeIn)
  1006. *((long far *) rgbValueOut) = (long) ushort;
  1007. else
  1008. *((long far *) rgbValueOut) = (long) sshort;
  1009. }
  1010. if (pcbValueOut != NULL)
  1011. *pcbValueOut = 4;
  1012. break;
  1013. case SQL_C_ULONG:
  1014. if (rgbValueOut != NULL) {
  1015. if (fUnsignedAttributeIn)
  1016. *((unsigned long far *) rgbValueOut) = (unsigned long) ushort;
  1017. else {
  1018. if (sshort < ULONG_LOW_I)
  1019. return ERR_OUTOFRANGE;
  1020. *((unsigned long far *) rgbValueOut) = (unsigned long) sshort;
  1021. }
  1022. }
  1023. if (pcbValueOut != NULL)
  1024. *pcbValueOut = 4;
  1025. break;
  1026. case SQL_C_FLOAT:
  1027. if (rgbValueOut != NULL) {
  1028. if (fUnsignedAttributeIn)
  1029. *((float far *) rgbValueOut) = (float) ushort;
  1030. else
  1031. *((float far *) rgbValueOut) = (float) sshort;
  1032. }
  1033. if (pcbValueOut != NULL)
  1034. *pcbValueOut = 4;
  1035. break;
  1036. case SQL_C_DOUBLE:
  1037. if (rgbValueOut != NULL) {
  1038. if (fUnsignedAttributeIn)
  1039. *((double far *) rgbValueOut) = (double) ushort;
  1040. else
  1041. *((double far *) rgbValueOut) = (double) sshort;
  1042. }
  1043. if (pcbValueOut != NULL)
  1044. *pcbValueOut = 8;
  1045. break;
  1046. case SQL_C_BIT:
  1047. if (rgbValueOut != NULL) {
  1048. if (fUnsignedAttributeIn) {
  1049. if (ushort > BIT_HIGH_I)
  1050. return ERR_OUTOFRANGE;
  1051. *((unsigned char far *) rgbValueOut) = (unsigned char) ushort;
  1052. }
  1053. else {
  1054. if ((sshort < BIT_LOW_I) || (sshort > BIT_HIGH_I))
  1055. return ERR_OUTOFRANGE;
  1056. *((unsigned char far *) rgbValueOut) = (unsigned char) sshort;
  1057. }
  1058. }
  1059. if (pcbValueOut != NULL)
  1060. *pcbValueOut = 1;
  1061. break;
  1062. case SQL_C_TINYINT:
  1063. case SQL_C_STINYINT:
  1064. if (rgbValueOut != NULL) {
  1065. if (fUnsignedAttributeIn) {
  1066. if (ushort > STINY_HIGH_I)
  1067. return ERR_OUTOFRANGE;
  1068. *((char far *) rgbValueOut) = (char) ushort;
  1069. }
  1070. else {
  1071. if ((sshort < STINY_LOW_I) || (sshort > STINY_HIGH_I))
  1072. return ERR_OUTOFRANGE;
  1073. *((char far *) rgbValueOut) = (char) sshort;
  1074. }
  1075. }
  1076. if (pcbValueOut != NULL)
  1077. *pcbValueOut = 1;
  1078. break;
  1079. case SQL_C_UTINYINT:
  1080. if (rgbValueOut != NULL) {
  1081. if (fUnsignedAttributeIn) {
  1082. if (ushort > UTINY_HIGH_I)
  1083. return ERR_OUTOFRANGE;
  1084. *((unsigned char far *) rgbValueOut) = (unsigned char) ushort;
  1085. }
  1086. else {
  1087. if ((sshort < UTINY_LOW_I) || (sshort > UTINY_HIGH_I))
  1088. return ERR_OUTOFRANGE;
  1089. *((unsigned char far *) rgbValueOut) = (unsigned char) sshort;
  1090. }
  1091. }
  1092. if (pcbValueOut != NULL)
  1093. *pcbValueOut = 1;
  1094. break;
  1095. case SQL_C_DEFAULT:
  1096. if (rgbValueOut != NULL) {
  1097. if (fUnsignedAttributeIn)
  1098. *((unsigned short far *) rgbValueOut) = (unsigned short) ushort;
  1099. else
  1100. *((short far *) rgbValueOut) = (short) sshort;
  1101. }
  1102. if (pcbValueOut != NULL)
  1103. *pcbValueOut = 2;
  1104. break;
  1105. case SQL_C_DATE:
  1106. return ERR_NOTCONVERTABLE;
  1107. case SQL_C_TIME:
  1108. return ERR_NOTCONVERTABLE;
  1109. case SQL_C_TIMESTAMP:
  1110. return ERR_NOTCONVERTABLE;
  1111. case SQL_C_BINARY:
  1112. if (rgbValueOut != NULL) {
  1113. if (fUnsignedAttributeIn)
  1114. *((unsigned short far *) rgbValueOut) = (unsigned short) ushort;
  1115. else
  1116. *((short far *) rgbValueOut) = (short) sshort;
  1117. }
  1118. if (pcbValueOut != NULL)
  1119. *pcbValueOut = 2;
  1120. break;
  1121. default:
  1122. return ERR_NOTCONVERTABLE;
  1123. }
  1124. break;
  1125. case SQL_INTEGER:
  1126. if (fUnsignedAttributeIn)
  1127. ulong = *((unsigned long far *) rgbValueIn);
  1128. else
  1129. slong = *((long far *) rgbValueIn);
  1130. switch (fCTypeOut) {
  1131. case SQL_C_CHAR:
  1132. if (fUnsignedAttributeIn)
  1133. wsprintf((LPSTR)szBuffer, "%lu", (unsigned long) ulong);
  1134. else
  1135. wsprintf((LPSTR)szBuffer, "%ld", (long) slong);
  1136. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  1137. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  1138. pcbValueOut);
  1139. case SQL_C_SHORT:
  1140. case SQL_C_SSHORT:
  1141. if (rgbValueOut != NULL) {
  1142. if (fUnsignedAttributeIn) {
  1143. if (ulong > SSHORT_HIGH_I)
  1144. return ERR_OUTOFRANGE;
  1145. *((short far *) rgbValueOut) = (short) ulong;
  1146. }
  1147. else {
  1148. if ((slong < SSHORT_LOW_I) || (slong > SSHORT_HIGH_I))
  1149. return ERR_OUTOFRANGE;
  1150. *((short far *) rgbValueOut) = (short) slong;
  1151. }
  1152. }
  1153. if (pcbValueOut != NULL)
  1154. *pcbValueOut = 2;
  1155. break;
  1156. case SQL_C_USHORT:
  1157. if (rgbValueOut != NULL) {
  1158. if (fUnsignedAttributeIn) {
  1159. if (ulong > USHORT_HIGH_I)
  1160. return ERR_OUTOFRANGE;
  1161. *((unsigned short far *) rgbValueOut) = (unsigned short) ulong;
  1162. }
  1163. else {
  1164. if ((slong < USHORT_LOW_I) || (slong > USHORT_HIGH_I))
  1165. return ERR_OUTOFRANGE;
  1166. *((unsigned short far *) rgbValueOut) = (unsigned short) slong;
  1167. }
  1168. }
  1169. if (pcbValueOut != NULL)
  1170. *pcbValueOut = 2;
  1171. break;
  1172. case SQL_C_LONG:
  1173. case SQL_C_SLONG:
  1174. if (rgbValueOut != NULL) {
  1175. if (fUnsignedAttributeIn) {
  1176. if (ulong > SLONG_HIGH_I)
  1177. return ERR_OUTOFRANGE;
  1178. *((long far *) rgbValueOut) = (long) ulong;
  1179. }
  1180. else
  1181. *((long far *) rgbValueOut) = (long) slong;
  1182. }
  1183. if (pcbValueOut != NULL)
  1184. *pcbValueOut = 4;
  1185. break;
  1186. case SQL_C_ULONG:
  1187. if (rgbValueOut != NULL) {
  1188. if (fUnsignedAttributeIn)
  1189. *((unsigned long far *) rgbValueOut) = (unsigned long) ulong;
  1190. else {
  1191. if (slong < ULONG_LOW_I)
  1192. return ERR_OUTOFRANGE;
  1193. *((unsigned long far *) rgbValueOut) = (unsigned long) slong;
  1194. }
  1195. }
  1196. if (pcbValueOut != NULL)
  1197. *pcbValueOut = 4;
  1198. break;
  1199. case SQL_C_FLOAT:
  1200. if (rgbValueOut != NULL) {
  1201. if (fUnsignedAttributeIn)
  1202. *((float far *) rgbValueOut) = (float) ulong;
  1203. else
  1204. *((float far *) rgbValueOut) = (float) slong;
  1205. }
  1206. if (pcbValueOut != NULL)
  1207. *pcbValueOut = 4;
  1208. break;
  1209. case SQL_C_DOUBLE:
  1210. if (rgbValueOut != NULL) {
  1211. if (fUnsignedAttributeIn)
  1212. *((double far *) rgbValueOut) = (double) ulong;
  1213. else
  1214. *((double far *) rgbValueOut) = (double) slong;
  1215. }
  1216. if (pcbValueOut != NULL)
  1217. *pcbValueOut = 8;
  1218. break;
  1219. case SQL_C_BIT:
  1220. if (rgbValueOut != NULL) {
  1221. if (fUnsignedAttributeIn) {
  1222. if (ulong > BIT_HIGH_I)
  1223. return ERR_OUTOFRANGE;
  1224. *((unsigned char far *) rgbValueOut) = (unsigned char) ulong;
  1225. }
  1226. else {
  1227. if ((slong < BIT_LOW_I) || (slong > BIT_HIGH_I))
  1228. return ERR_OUTOFRANGE;
  1229. *((unsigned char far *) rgbValueOut) = (unsigned char) slong;
  1230. }
  1231. }
  1232. if (pcbValueOut != NULL)
  1233. *pcbValueOut = 1;
  1234. break;
  1235. case SQL_C_TINYINT:
  1236. case SQL_C_STINYINT:
  1237. if (rgbValueOut != NULL) {
  1238. if (fUnsignedAttributeIn) {
  1239. if (ulong > STINY_HIGH_I)
  1240. return ERR_OUTOFRANGE;
  1241. *((char far *) rgbValueOut) = (char) ulong;
  1242. }
  1243. else {
  1244. if ((slong < STINY_LOW_I) || (slong > STINY_HIGH_I))
  1245. return ERR_OUTOFRANGE;
  1246. *((char far *) rgbValueOut) = (char) slong;
  1247. }
  1248. }
  1249. if (pcbValueOut != NULL)
  1250. *pcbValueOut = 1;
  1251. break;
  1252. case SQL_C_UTINYINT:
  1253. if (rgbValueOut != NULL) {
  1254. if (fUnsignedAttributeIn) {
  1255. if (ulong > UTINY_HIGH_I)
  1256. return ERR_OUTOFRANGE;
  1257. *((unsigned char far *) rgbValueOut) = (unsigned char) ulong;
  1258. }
  1259. else {
  1260. if ((slong < UTINY_LOW_I) || (slong > UTINY_HIGH_I))
  1261. return ERR_OUTOFRANGE;
  1262. *((unsigned char far *) rgbValueOut) = (unsigned char) slong;
  1263. }
  1264. }
  1265. if (pcbValueOut != NULL)
  1266. *pcbValueOut = 1;
  1267. break;
  1268. case SQL_C_DEFAULT:
  1269. if (rgbValueOut != NULL) {
  1270. if (fUnsignedAttributeIn)
  1271. *((unsigned long far *) rgbValueOut) = (unsigned long) ulong;
  1272. else
  1273. *((long far *) rgbValueOut) = (long) slong;
  1274. }
  1275. if (pcbValueOut != NULL)
  1276. *pcbValueOut = 4;
  1277. break;
  1278. case SQL_C_DATE:
  1279. return ERR_NOTCONVERTABLE;
  1280. case SQL_C_TIME:
  1281. return ERR_NOTCONVERTABLE;
  1282. case SQL_C_TIMESTAMP:
  1283. return ERR_NOTCONVERTABLE;
  1284. case SQL_C_BINARY:
  1285. if (rgbValueOut != NULL) {
  1286. if (fUnsignedAttributeIn)
  1287. *((unsigned long far *) rgbValueOut) = (unsigned long) ulong;
  1288. else
  1289. *((long far *) rgbValueOut) = (long) slong;
  1290. }
  1291. if (pcbValueOut != NULL)
  1292. *pcbValueOut = 4;
  1293. break;
  1294. default:
  1295. return ERR_NOTCONVERTABLE;
  1296. }
  1297. break;
  1298. case SQL_REAL:
  1299. flt = (*((float far *) rgbValueIn));
  1300. switch (fCTypeOut) {
  1301. case SQL_C_CHAR:
  1302. if (rgbValueOut == NULL) {
  1303. rgbValueOut = szBuffer;
  1304. cbValueOutMax = sizeof(szBuffer);
  1305. }
  1306. fTruncated = DoubleToChar(flt, TRUE, (LPUSTR)rgbValueOut, cbValueOutMax);
  1307. if (fTruncated)
  1308. ((LPSTR)rgbValueOut)[cbValueOutMax-1] = '\0';
  1309. if (pcbValueOut != NULL) {
  1310. if (!fTruncated)
  1311. *pcbValueOut = s_lstrlen((char*)rgbValueOut);
  1312. else
  1313. *pcbValueOut = cbValueOutMax;
  1314. }
  1315. break;
  1316. case SQL_C_SHORT:
  1317. case SQL_C_SSHORT:
  1318. if (rgbValueOut != NULL) {
  1319. if ((flt < SSHORT_LOW_D) || (flt > SSHORT_HIGH_D))
  1320. return ERR_OUTOFRANGE;
  1321. *((short far *) rgbValueOut) = (short) flt;
  1322. if (((float) *((short far *) rgbValueOut)) != flt)
  1323. fTruncated = TRUE;
  1324. }
  1325. if (pcbValueOut != NULL)
  1326. *pcbValueOut = 2;
  1327. break;
  1328. case SQL_C_USHORT:
  1329. if (rgbValueOut != NULL) {
  1330. if ((flt < USHORT_LOW_D) || (flt > USHORT_HIGH_D))
  1331. return ERR_OUTOFRANGE;
  1332. *((unsigned short far *) rgbValueOut) = (unsigned short) flt;
  1333. if (((float) *((unsigned short far *) rgbValueOut)) != flt)
  1334. fTruncated = TRUE;
  1335. }
  1336. if (pcbValueOut != NULL)
  1337. *pcbValueOut = 2;
  1338. break;
  1339. case SQL_C_LONG:
  1340. case SQL_C_SLONG:
  1341. if (rgbValueOut != NULL) {
  1342. if ((flt < SLONG_LOW_D) || (flt > SLONG_HIGH_D))
  1343. return ERR_OUTOFRANGE;
  1344. *((long far *) rgbValueOut) = (long) flt;
  1345. if (((float) *((long far *) rgbValueOut)) != flt)
  1346. fTruncated = TRUE;
  1347. }
  1348. if (pcbValueOut != NULL)
  1349. *pcbValueOut = 4;
  1350. break;
  1351. case SQL_C_ULONG:
  1352. if (rgbValueOut != NULL) {
  1353. if ((flt < ULONG_LOW_D) || (flt > ULONG_HIGH_D))
  1354. return ERR_OUTOFRANGE;
  1355. *((unsigned long far *) rgbValueOut) = (unsigned long) flt;
  1356. if (((float) *((unsigned long far *) rgbValueOut)) != flt)
  1357. fTruncated = TRUE;
  1358. }
  1359. if (pcbValueOut != NULL)
  1360. *pcbValueOut = 4;
  1361. break;
  1362. case SQL_C_FLOAT:
  1363. case SQL_C_DEFAULT:
  1364. if (rgbValueOut != NULL)
  1365. *((float far *) rgbValueOut) = (float) flt;
  1366. if (pcbValueOut != NULL)
  1367. *pcbValueOut = 4;
  1368. break;
  1369. case SQL_C_DOUBLE:
  1370. if (rgbValueOut != NULL)
  1371. *((double far *) rgbValueOut) = (double) flt;
  1372. if (pcbValueOut != NULL)
  1373. *pcbValueOut = 8;
  1374. break;
  1375. case SQL_C_BIT:
  1376. if (rgbValueOut != NULL) {
  1377. if ((flt < BIT_LOW_D) || (flt > BIT_HIGH_D))
  1378. return ERR_OUTOFRANGE;
  1379. *((unsigned char far *) rgbValueOut) = (unsigned char) flt;
  1380. if (((float) *((unsigned char far *) rgbValueOut)) != flt)
  1381. fTruncated = TRUE;
  1382. }
  1383. if (pcbValueOut != NULL)
  1384. *pcbValueOut = 1;
  1385. break;
  1386. case SQL_C_TINYINT:
  1387. case SQL_C_STINYINT:
  1388. if (rgbValueOut != NULL) {
  1389. if ((flt < STINY_LOW_D) || (flt > STINY_HIGH_D))
  1390. return ERR_OUTOFRANGE;
  1391. *((char far *) rgbValueOut) = (char) flt;
  1392. if (((float) *((char far *) rgbValueOut)) != flt)
  1393. fTruncated = TRUE;
  1394. }
  1395. if (pcbValueOut != NULL)
  1396. *pcbValueOut = 1;
  1397. break;
  1398. case SQL_C_UTINYINT:
  1399. if (rgbValueOut != NULL) {
  1400. if ((flt < UTINY_LOW_D) || (flt > UTINY_HIGH_D))
  1401. return ERR_OUTOFRANGE;
  1402. *((unsigned char far *) rgbValueOut) = (unsigned char) flt;
  1403. if (((float) *((unsigned char far *) rgbValueOut)) != flt)
  1404. fTruncated = TRUE;
  1405. }
  1406. if (pcbValueOut != NULL)
  1407. *pcbValueOut = 1;
  1408. break;
  1409. case SQL_C_DATE:
  1410. return ERR_NOTCONVERTABLE;
  1411. case SQL_C_TIME:
  1412. return ERR_NOTCONVERTABLE;
  1413. case SQL_C_TIMESTAMP:
  1414. return ERR_NOTCONVERTABLE;
  1415. case SQL_C_BINARY:
  1416. if (rgbValueOut != NULL)
  1417. *((float far *) rgbValueOut) = (float) flt;
  1418. if (pcbValueOut != NULL)
  1419. *pcbValueOut = 4;
  1420. break;
  1421. default:
  1422. return ERR_NOTCONVERTABLE;
  1423. }
  1424. break;
  1425. case SQL_FLOAT:
  1426. case SQL_DOUBLE:
  1427. dbl = (*((double far *) rgbValueIn));
  1428. switch (fCTypeOut) {
  1429. case SQL_C_CHAR:
  1430. if (rgbValueOut == NULL) {
  1431. rgbValueOut = szBuffer;
  1432. cbValueOutMax = sizeof(szBuffer);
  1433. }
  1434. fTruncated = DoubleToChar(dbl, TRUE, (LPUSTR)rgbValueOut, cbValueOutMax);
  1435. if (fTruncated)
  1436. ((LPSTR)rgbValueOut)[cbValueOutMax-1] = '\0';
  1437. if (pcbValueOut != NULL) {
  1438. if (!fTruncated)
  1439. *pcbValueOut = s_lstrlen((char*)rgbValueOut);
  1440. else
  1441. *pcbValueOut = cbValueOutMax;
  1442. }
  1443. break;
  1444. case SQL_C_SHORT:
  1445. case SQL_C_SSHORT:
  1446. if (rgbValueOut != NULL) {
  1447. if ((dbl < SSHORT_LOW_D) || (dbl > SSHORT_HIGH_D))
  1448. return ERR_OUTOFRANGE;
  1449. *((short far *) rgbValueOut) = (short) dbl;
  1450. if (((double) *((short far *) rgbValueOut)) != dbl)
  1451. fTruncated = TRUE;
  1452. }
  1453. if (pcbValueOut != NULL)
  1454. *pcbValueOut = 2;
  1455. break;
  1456. case SQL_C_USHORT:
  1457. if (rgbValueOut != NULL) {
  1458. if ((dbl < USHORT_LOW_D) || (dbl > USHORT_HIGH_D))
  1459. return ERR_OUTOFRANGE;
  1460. *((unsigned short far *) rgbValueOut) = (unsigned short) dbl;
  1461. if (((double) *((unsigned short far *) rgbValueOut)) != dbl)
  1462. fTruncated = TRUE;
  1463. }
  1464. if (pcbValueOut != NULL)
  1465. *pcbValueOut = 2;
  1466. break;
  1467. case SQL_C_LONG:
  1468. case SQL_C_SLONG:
  1469. if (rgbValueOut != NULL) {
  1470. if ((dbl < SLONG_LOW_D) || (dbl > SLONG_HIGH_D))
  1471. return ERR_OUTOFRANGE;
  1472. *((long far *) rgbValueOut) = (long) dbl;
  1473. if (((double) *((long far *) rgbValueOut)) != dbl)
  1474. fTruncated = TRUE;
  1475. }
  1476. if (pcbValueOut != NULL)
  1477. *pcbValueOut = 4;
  1478. break;
  1479. case SQL_C_ULONG:
  1480. if (rgbValueOut != NULL) {
  1481. if ((dbl < ULONG_LOW_D) || (dbl > ULONG_HIGH_D))
  1482. return ERR_OUTOFRANGE;
  1483. *((unsigned long far *) rgbValueOut) = (unsigned long) dbl;
  1484. if (((double) *((unsigned long far *) rgbValueOut)) != dbl)
  1485. fTruncated = TRUE;
  1486. }
  1487. if (pcbValueOut != NULL)
  1488. *pcbValueOut = 4;
  1489. break;
  1490. case SQL_C_FLOAT:
  1491. if (rgbValueOut != NULL) {
  1492. if ((dbl < FLOAT_LOW_D) || (dbl > FLOAT_HIGH_D))
  1493. return ERR_OUTOFRANGE;
  1494. *((float far *) rgbValueOut) = (float) dbl;
  1495. }
  1496. if (pcbValueOut != NULL)
  1497. *pcbValueOut = 4;
  1498. break;
  1499. case SQL_C_DOUBLE:
  1500. case SQL_C_DEFAULT:
  1501. if (rgbValueOut != NULL)
  1502. *((double far *) rgbValueOut) = (double) dbl;
  1503. if (pcbValueOut != NULL)
  1504. *pcbValueOut = 8;
  1505. break;
  1506. case SQL_C_BIT:
  1507. if (rgbValueOut != NULL) {
  1508. if ((dbl < BIT_LOW_D) || (dbl > BIT_HIGH_D))
  1509. return ERR_OUTOFRANGE;
  1510. *((unsigned char far *) rgbValueOut) = (unsigned char) dbl;
  1511. if (((double) *((unsigned char far *) rgbValueOut)) != dbl)
  1512. fTruncated = TRUE;
  1513. }
  1514. if (pcbValueOut != NULL)
  1515. *pcbValueOut = 1;
  1516. break;
  1517. case SQL_C_TINYINT:
  1518. case SQL_C_STINYINT:
  1519. if (rgbValueOut != NULL) {
  1520. if ((dbl < STINY_LOW_D) || (dbl > STINY_HIGH_D))
  1521. return ERR_OUTOFRANGE;
  1522. *((char far *) rgbValueOut) = (char) dbl;
  1523. if (((double) *((char far *) rgbValueOut)) != dbl)
  1524. fTruncated = TRUE;
  1525. }
  1526. if (pcbValueOut != NULL)
  1527. *pcbValueOut = 1;
  1528. break;
  1529. case SQL_C_UTINYINT:
  1530. if (rgbValueOut != NULL) {
  1531. if ((dbl < UTINY_LOW_D) || (dbl > UTINY_HIGH_D))
  1532. return ERR_OUTOFRANGE;
  1533. *((unsigned char far *) rgbValueOut) = (unsigned char) dbl;
  1534. if (((double) *((unsigned char far *) rgbValueOut)) != dbl)
  1535. fTruncated = TRUE;
  1536. }
  1537. if (pcbValueOut != NULL)
  1538. *pcbValueOut = 1;
  1539. break;
  1540. case SQL_C_DATE:
  1541. return ERR_NOTCONVERTABLE;
  1542. case SQL_C_TIME:
  1543. return ERR_NOTCONVERTABLE;
  1544. case SQL_C_TIMESTAMP:
  1545. return ERR_NOTCONVERTABLE;
  1546. case SQL_C_BINARY:
  1547. if (rgbValueOut != NULL)
  1548. *((double far *) rgbValueOut) = (double) dbl;
  1549. if (pcbValueOut != NULL)
  1550. *pcbValueOut = 8;
  1551. break;
  1552. default:
  1553. return ERR_NOTCONVERTABLE;
  1554. }
  1555. break;
  1556. case SQL_BINARY:
  1557. case SQL_VARBINARY:
  1558. case SQL_LONGVARBINARY:
  1559. switch (fCTypeOut) {
  1560. case SQL_C_CHAR:
  1561. /* Get length of input */
  1562. if (cbValueIn < 0)
  1563. cbValueIn = 0;
  1564. /* Figure out how many nibbles (not bytes) to copy */
  1565. cbValue = (2 * cbValueIn) - *pcbOffset;
  1566. if (cbValue >= cbValueOutMax) {
  1567. cbValue = cbValueOutMax-1;
  1568. fTruncated = TRUE;
  1569. }
  1570. /* Copy the value */
  1571. lpFrom = (LPUSTR) rgbValueIn;
  1572. lpTo = (LPUSTR) rgbValueOut;
  1573. for (i = *pcbOffset; i < (*pcbOffset + cbValue); i++) {
  1574. /* Get the next nibble */
  1575. nibble = *lpFrom;
  1576. if (((i/2) * 2) == i)
  1577. nibble = nibble >> 4;
  1578. else
  1579. lpFrom++;
  1580. nibble = nibble & 0x0F;
  1581. /* Convert it to a character */
  1582. if (nibble <= 9)
  1583. *lpTo = nibble + '0';
  1584. else
  1585. *lpTo = (nibble-10) + 'A';
  1586. lpTo++;
  1587. }
  1588. *lpTo = '\0';
  1589. if (pcbValueOut != NULL)
  1590. *pcbValueOut = (2 * cbValueIn) - *pcbOffset;
  1591. /* Adjust offset */
  1592. *pcbOffset += (cbValue);
  1593. break;
  1594. case SQL_C_SHORT:
  1595. if (rgbValueOut != NULL) {
  1596. if (fUnsignedAttributeIn)
  1597. *((unsigned short far *) rgbValueOut) =
  1598. *((unsigned short far *) rgbValueIn);
  1599. else
  1600. *((short far *) rgbValueOut) =
  1601. *((short far *) rgbValueIn);
  1602. }
  1603. if (pcbValueOut != NULL)
  1604. *pcbValueOut = 2;
  1605. break;
  1606. case SQL_C_SSHORT:
  1607. if (rgbValueOut != NULL)
  1608. *((short far *) rgbValueOut) = *((short far *) rgbValueIn);
  1609. if (pcbValueOut != NULL)
  1610. *pcbValueOut = 2;
  1611. break;
  1612. case SQL_C_USHORT:
  1613. if (rgbValueOut != NULL)
  1614. *((unsigned short far *) rgbValueOut) =
  1615. *((unsigned short far *) rgbValueIn);
  1616. if (pcbValueOut != NULL)
  1617. *pcbValueOut = 2;
  1618. break;
  1619. case SQL_C_LONG:
  1620. if (rgbValueOut != NULL) {
  1621. if (fUnsignedAttributeIn)
  1622. *((unsigned long far *) rgbValueOut) =
  1623. *((unsigned long far *) rgbValueIn);
  1624. else
  1625. *((long far *) rgbValueOut) =
  1626. *((long far *) rgbValueIn);
  1627. }
  1628. if (pcbValueOut != NULL)
  1629. *pcbValueOut = 4;
  1630. break;
  1631. case SQL_C_SLONG:
  1632. if (rgbValueOut != NULL)
  1633. *((long far *) rgbValueOut) = *((long far *) rgbValueIn);
  1634. if (pcbValueOut != NULL)
  1635. *pcbValueOut = 4;
  1636. break;
  1637. case SQL_C_ULONG:
  1638. if (rgbValueOut != NULL)
  1639. *((unsigned long far *) rgbValueOut) =
  1640. *((unsigned long far *) rgbValueIn);
  1641. if (pcbValueOut != NULL)
  1642. *pcbValueOut = 4;
  1643. break;
  1644. case SQL_C_FLOAT:
  1645. if (rgbValueOut != NULL)
  1646. *((float far *) rgbValueOut) = *((float far *) rgbValueIn);
  1647. if (pcbValueOut != NULL)
  1648. *pcbValueOut = 4;
  1649. break;
  1650. case SQL_C_DOUBLE:
  1651. if (rgbValueOut != NULL)
  1652. *((double far *) rgbValueOut) = *((double far *) rgbValueIn);
  1653. if (pcbValueOut != NULL)
  1654. *pcbValueOut = 8;
  1655. break;
  1656. case SQL_C_BIT:
  1657. if (rgbValueOut != NULL)
  1658. *((unsigned char far *) rgbValueOut) =
  1659. *((unsigned char far *) rgbValueIn);
  1660. if (pcbValueOut != NULL)
  1661. *pcbValueOut = 1;
  1662. break;
  1663. case SQL_C_TINYINT:
  1664. if (rgbValueOut != NULL) {
  1665. if (fUnsignedAttributeIn)
  1666. *((unsigned char far *) rgbValueOut) =
  1667. *((unsigned char far *) rgbValueIn);
  1668. else
  1669. *((char far *) rgbValueOut) =
  1670. *((char far *) rgbValueIn);
  1671. }
  1672. if (pcbValueOut != NULL)
  1673. *pcbValueOut = 1;
  1674. break;
  1675. case SQL_C_STINYINT:
  1676. if (rgbValueOut != NULL)
  1677. *((char far *) rgbValueOut) = *((char far *) rgbValueIn);
  1678. if (pcbValueOut != NULL)
  1679. *pcbValueOut = 1;
  1680. break;
  1681. case SQL_C_UTINYINT:
  1682. if (rgbValueOut != NULL)
  1683. *((unsigned char far *) rgbValueOut) =
  1684. *((unsigned char far *) rgbValueIn);
  1685. if (pcbValueOut != NULL)
  1686. *pcbValueOut = 1;
  1687. break;
  1688. case SQL_C_DATE:
  1689. if (rgbValueOut != NULL)
  1690. *((DATE_STRUCT far *) rgbValueOut) =
  1691. *((DATE_STRUCT far *) rgbValueIn);
  1692. if (pcbValueOut != NULL)
  1693. *pcbValueOut = 6;
  1694. break;
  1695. case SQL_C_TIME:
  1696. if (rgbValueOut != NULL)
  1697. *((TIME_STRUCT far *) rgbValueOut) =
  1698. *((TIME_STRUCT far *) rgbValueIn);
  1699. if (pcbValueOut != NULL)
  1700. *pcbValueOut = 6;
  1701. break;
  1702. case SQL_C_TIMESTAMP:
  1703. if (rgbValueOut != NULL)
  1704. *((TIMESTAMP_STRUCT far *) rgbValueOut) =
  1705. *((TIMESTAMP_STRUCT far *) rgbValueIn);
  1706. if (pcbValueOut != NULL)
  1707. *pcbValueOut = 16;
  1708. break;
  1709. case SQL_C_BINARY:
  1710. case SQL_C_DEFAULT:
  1711. /* Get length of input string */
  1712. if (cbValueIn < 0)
  1713. cbValueIn = 0;
  1714. /* Figure out how many bytes to copy */
  1715. cbValue = cbValueIn - *pcbOffset;
  1716. if (cbValue > cbValueOutMax) {
  1717. cbValue = cbValueOutMax;
  1718. fTruncated = TRUE;
  1719. }
  1720. /* Copy the string */
  1721. if (rgbValueOut != NULL) {
  1722. _fmemcpy(rgbValueOut, ((LPSTR) rgbValueIn) + *pcbOffset,
  1723. (SWORD) cbValue);
  1724. }
  1725. if (pcbValueOut != NULL)
  1726. *pcbValueOut = cbValueIn - *pcbOffset;
  1727. /* Adjust offset */
  1728. *pcbOffset += (cbValue);
  1729. break;
  1730. default:
  1731. return ERR_NOTCONVERTABLE;
  1732. }
  1733. break;
  1734. case SQL_DATE:
  1735. switch (fCTypeOut) {
  1736. case SQL_C_CHAR:
  1737. DateToChar((DATE_STRUCT far *) rgbValueIn, (LPUSTR)szBuffer);
  1738. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  1739. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  1740. pcbValueOut);
  1741. case SQL_C_SHORT:
  1742. case SQL_C_SSHORT:
  1743. case SQL_C_USHORT:
  1744. case SQL_C_LONG:
  1745. case SQL_C_SLONG:
  1746. case SQL_C_ULONG:
  1747. case SQL_C_FLOAT:
  1748. case SQL_C_DOUBLE:
  1749. case SQL_C_BIT:
  1750. case SQL_C_TINYINT:
  1751. case SQL_C_STINYINT:
  1752. case SQL_C_UTINYINT:
  1753. return ERR_NOTCONVERTABLE;
  1754. case SQL_C_DEFAULT:
  1755. case SQL_C_DATE:
  1756. if (rgbValueOut != NULL)
  1757. *((DATE_STRUCT far *) rgbValueOut) =
  1758. *((DATE_STRUCT far *) rgbValueIn);
  1759. if (pcbValueOut != NULL)
  1760. *pcbValueOut = 6;
  1761. break;
  1762. case SQL_C_TIME:
  1763. return ERR_NOTCONVERTABLE;
  1764. case SQL_C_TIMESTAMP:
  1765. if (rgbValueOut != NULL) {
  1766. lpTimestamp = (TIMESTAMP_STRUCT far *) rgbValueOut;
  1767. lpDate = (DATE_STRUCT far *) rgbValueIn;
  1768. lpTimestamp->year = lpDate->year;
  1769. lpTimestamp->month = lpDate->month;
  1770. lpTimestamp->day = lpDate->day;
  1771. lpTimestamp->hour = 0;
  1772. lpTimestamp->minute = 0;
  1773. lpTimestamp->second = 0;
  1774. lpTimestamp->fraction = 0;
  1775. }
  1776. if (pcbValueOut != NULL)
  1777. *pcbValueOut = 16;
  1778. break;
  1779. case SQL_C_BINARY:
  1780. if (rgbValueOut != NULL)
  1781. *((DATE_STRUCT far *) rgbValueOut) =
  1782. *((DATE_STRUCT far *) rgbValueIn);
  1783. if (pcbValueOut != NULL)
  1784. *pcbValueOut = 6;
  1785. break;
  1786. default:
  1787. return ERR_NOTCONVERTABLE;
  1788. }
  1789. break;
  1790. case SQL_TIME:
  1791. switch (fCTypeOut) {
  1792. case SQL_C_CHAR:
  1793. TimeToChar((TIME_STRUCT far *) rgbValueIn, (LPUSTR)szBuffer);
  1794. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  1795. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  1796. pcbValueOut);
  1797. case SQL_C_SHORT:
  1798. case SQL_C_SSHORT:
  1799. case SQL_C_USHORT:
  1800. case SQL_C_LONG:
  1801. case SQL_C_SLONG:
  1802. case SQL_C_ULONG:
  1803. case SQL_C_FLOAT:
  1804. case SQL_C_DOUBLE:
  1805. case SQL_C_BIT:
  1806. case SQL_C_TINYINT:
  1807. case SQL_C_STINYINT:
  1808. case SQL_C_UTINYINT:
  1809. return ERR_NOTCONVERTABLE;
  1810. case SQL_C_DATE:
  1811. return ERR_NOTCONVERTABLE;
  1812. case SQL_C_DEFAULT:
  1813. case SQL_C_TIME:
  1814. if (rgbValueOut != NULL)
  1815. *((TIME_STRUCT far *) rgbValueOut) =
  1816. *((TIME_STRUCT far *) rgbValueIn);
  1817. if (pcbValueOut != NULL)
  1818. *pcbValueOut = 6;
  1819. break;
  1820. case SQL_C_TIMESTAMP:
  1821. if (rgbValueOut != NULL) {
  1822. lpTimestamp = (TIMESTAMP_STRUCT far *) rgbValueOut;
  1823. lpTime = (TIME_STRUCT far *) rgbValueIn;
  1824. time(&t);
  1825. ts = localtime(&t);
  1826. lpTimestamp->year = ts->tm_year + 1900;
  1827. lpTimestamp->month = ts->tm_mon + 1;
  1828. lpTimestamp->day = (UWORD) ts->tm_mday;
  1829. lpTimestamp->hour = lpTime->hour;
  1830. lpTimestamp->minute = lpTime->minute;
  1831. lpTimestamp->second = lpTime->second;
  1832. lpTimestamp->fraction = 0;
  1833. }
  1834. if (pcbValueOut != NULL)
  1835. *pcbValueOut = 16;
  1836. break;
  1837. case SQL_C_BINARY:
  1838. if (rgbValueOut != NULL)
  1839. *((TIME_STRUCT far *) rgbValueOut) =
  1840. *((TIME_STRUCT far *) rgbValueIn);
  1841. if (pcbValueOut != NULL)
  1842. *pcbValueOut = 6;
  1843. break;
  1844. default:
  1845. return ERR_NOTCONVERTABLE;
  1846. }
  1847. break;
  1848. case SQL_TIMESTAMP:
  1849. switch (fCTypeOut) {
  1850. case SQL_C_CHAR:
  1851. TimestampToChar((TIMESTAMP_STRUCT far *) rgbValueIn, (LPUSTR)szBuffer);
  1852. return ConvertSqlToC(SQL_VARCHAR, FALSE, szBuffer, SQL_NTS,
  1853. pcbOffset, fCTypeOut, rgbValueOut, cbValueOutMax,
  1854. pcbValueOut);
  1855. case SQL_C_SHORT:
  1856. case SQL_C_SSHORT:
  1857. case SQL_C_USHORT:
  1858. case SQL_C_LONG:
  1859. case SQL_C_SLONG:
  1860. case SQL_C_ULONG:
  1861. case SQL_C_FLOAT:
  1862. case SQL_C_DOUBLE:
  1863. case SQL_C_BIT:
  1864. case SQL_C_TINYINT:
  1865. case SQL_C_STINYINT:
  1866. case SQL_C_UTINYINT:
  1867. return ERR_NOTCONVERTABLE;
  1868. case SQL_C_DATE:
  1869. if (rgbValueOut != NULL) {
  1870. lpDate = (DATE_STRUCT far *) rgbValueOut;
  1871. lpTimestamp = (TIMESTAMP_STRUCT far *) rgbValueIn;
  1872. lpDate->year = lpTimestamp->year;
  1873. lpDate->month = lpTimestamp->month;
  1874. lpDate->day = lpTimestamp->day;
  1875. }
  1876. if (pcbValueOut != NULL)
  1877. *pcbValueOut = 6;
  1878. break;
  1879. case SQL_C_TIME:
  1880. if (rgbValueOut != NULL) {
  1881. lpTime = (TIME_STRUCT far *) rgbValueOut;
  1882. lpTimestamp = (TIMESTAMP_STRUCT far *) rgbValueIn;
  1883. lpTime->hour = lpTimestamp->hour;
  1884. lpTime->minute = lpTimestamp->minute;
  1885. lpTime->second = lpTimestamp->second;
  1886. }
  1887. if (pcbValueOut != NULL)
  1888. *pcbValueOut = 6;
  1889. break;
  1890. case SQL_C_DEFAULT:
  1891. case SQL_C_TIMESTAMP:
  1892. if (rgbValueOut != NULL)
  1893. *((TIMESTAMP_STRUCT far *) rgbValueOut) =
  1894. *((TIMESTAMP_STRUCT far *) rgbValueIn);
  1895. if (pcbValueOut != NULL)
  1896. *pcbValueOut = 16;
  1897. break;
  1898. case SQL_C_BINARY:
  1899. if (rgbValueOut != NULL)
  1900. *((TIMESTAMP_STRUCT far *) rgbValueOut) =
  1901. *((TIMESTAMP_STRUCT far *) rgbValueIn);
  1902. if (pcbValueOut != NULL)
  1903. *pcbValueOut = 16;
  1904. break;
  1905. default:
  1906. return ERR_NOTCONVERTABLE;
  1907. }
  1908. break;
  1909. default:
  1910. return ERR_NOTCAPABLE;
  1911. }
  1912. if (fTruncated)
  1913. return ERR_DATATRUNCATED;
  1914. return ERR_SUCCESS;
  1915. }
  1916. /***************************************************************************/
  1917. BOOL INTFUNC PatternMatch(
  1918. BOOL fEscape,
  1919. LPUSTR lpCandidate,
  1920. SDWORD cbCandidate,
  1921. LPUSTR lpPattern,
  1922. SDWORD cbPattern,
  1923. BOOL fCaseSensitive)
  1924. {
  1925. /* Take care of "special" lengths */
  1926. if ((cbCandidate < 0) || (cbPattern < 0)) {
  1927. /* Handle case where candidate is null-terminated */
  1928. if (cbCandidate == SQL_NTS)
  1929. return PatternMatch(fEscape, lpCandidate, s_lstrlen(lpCandidate),
  1930. lpPattern, cbPattern, fCaseSensitive);
  1931. /* Handle case where pattern is null-terminated */
  1932. else if (cbPattern == SQL_NTS)
  1933. return PatternMatch(fEscape, lpCandidate, cbCandidate,
  1934. lpPattern, s_lstrlen(lpPattern),
  1935. fCaseSensitive);
  1936. /* Handle case where candidate is null */
  1937. else if (cbCandidate == SQL_NULL_DATA)
  1938. return PatternMatch(fEscape, lpCandidate, 0,
  1939. lpPattern, cbPattern,
  1940. fCaseSensitive);
  1941. /* Handle case where pattern is null */
  1942. else if (cbPattern == SQL_NULL_DATA)
  1943. return PatternMatch(fEscape, lpCandidate, cbCandidate,
  1944. lpPattern, 0,
  1945. fCaseSensitive);
  1946. else
  1947. return FALSE;
  1948. }
  1949. /* Remove trailing blanks */
  1950. while ( (cbPattern > 0) && (lpPattern[cbPattern-1] == ' ') )
  1951. cbPattern--;
  1952. while ( (cbCandidate > 0) && (lpCandidate[cbCandidate-1] == ' ') )
  1953. cbCandidate--;
  1954. /* End of pattern? */
  1955. if (cbPattern == 0) {
  1956. /* Yes. End of candidate? */
  1957. if (cbCandidate == 0)
  1958. /* Yes. They match */
  1959. return TRUE;
  1960. else
  1961. /* No. They don't match */
  1962. return FALSE;
  1963. }
  1964. else {
  1965. /* No. What is next pattern character? */
  1966. switch (*lpPattern) {
  1967. /* Match any single character. */
  1968. case '_':
  1969. /* End of candidate? */
  1970. if (cbCandidate == 0)
  1971. /* Yes. No match */
  1972. return FALSE;
  1973. else
  1974. /* No. Comapre rest of both strings */
  1975. return PatternMatch(fEscape, lpCandidate + 1, cbCandidate - 1,
  1976. lpPattern + 1, cbPattern - 1,
  1977. fCaseSensitive);
  1978. /* Match zero-or more characters */
  1979. case '%':
  1980. /* End of candidate? */
  1981. if (cbCandidate == 0)
  1982. /* Yes. Make sure rest of pattern matches too. */
  1983. return PatternMatch(fEscape, lpCandidate, cbCandidate,
  1984. lpPattern + 1, cbPattern - 1,
  1985. fCaseSensitive);
  1986. /* If you skip the first character of the candidate, does the */
  1987. /* rest of the candidate match the pattern (test to see if */
  1988. /* the '%' corresponds to one or more characters (the 'or more' */
  1989. /* is done at the next recursive level)? */
  1990. else if (PatternMatch(fEscape, lpCandidate + 1,
  1991. cbCandidate - 1, lpPattern, cbPattern,
  1992. fCaseSensitive))
  1993. /* Yes. We have a match */
  1994. return TRUE;
  1995. /* Does the rest of the pattern match the candidate (test to */
  1996. /* see if the '%' corresponds to no characters)? */
  1997. else if (PatternMatch(fEscape, lpCandidate, cbCandidate,
  1998. lpPattern + 1, cbPattern - 1,
  1999. fCaseSensitive))
  2000. /* Yes. We have a match */
  2001. return TRUE;
  2002. else
  2003. /* No match. */
  2004. return FALSE;
  2005. /* Single character match */
  2006. default:
  2007. /* Is it the escape character? */
  2008. if (fEscape && (cbPattern > 1) && (*lpPattern == '\\')) {
  2009. /* Yes. Go to next character */
  2010. cbPattern--;
  2011. lpPattern++;
  2012. }
  2013. /* If the candidate is empty, no match */
  2014. if (cbCandidate == 0)
  2015. return FALSE;
  2016. /* If the characters match, test the rest of the strings */
  2017. else if (*lpCandidate == *lpPattern)
  2018. return PatternMatch(fEscape, lpCandidate + 1, cbCandidate - 1,
  2019. lpPattern + 1, cbPattern - 1,
  2020. fCaseSensitive);
  2021. /* Try a case insensitve match if allowed */
  2022. else if (!fCaseSensitive) {
  2023. if ((*lpCandidate >= 'a') && (*lpCandidate <= 'z')) {
  2024. if (((*lpCandidate - 'a') + 'A') == *lpPattern)
  2025. return PatternMatch(fEscape, lpCandidate + 1,
  2026. cbCandidate - 1, lpPattern + 1,
  2027. cbPattern - 1, fCaseSensitive);
  2028. else
  2029. return FALSE;
  2030. }
  2031. else if ((*lpPattern >= 'a') && (*lpPattern <= 'z')) {
  2032. if (*lpCandidate == ((*lpPattern - 'a') + 'A'))
  2033. return PatternMatch(fEscape, lpCandidate + 1,
  2034. cbCandidate - 1, lpPattern + 1,
  2035. cbPattern - 1, fCaseSensitive);
  2036. else
  2037. return FALSE;
  2038. }
  2039. else
  2040. return FALSE;
  2041. }
  2042. else
  2043. return FALSE;
  2044. }
  2045. }
  2046. }
  2047. /***************************************************************************/
  2048. SDWORD INTFUNC TrueSize(LPUSTR lpStr, SDWORD cbStr, SDWORD cbMax)
  2049. {
  2050. /* If no string, return 0 */
  2051. if (lpStr == NULL)
  2052. return 0;
  2053. /* If zero terminated string, get length */
  2054. if (cbStr == SQL_NTS)
  2055. cbStr = s_lstrlen(lpStr);
  2056. /* If bigger than mat, return the max */
  2057. if (cbStr > cbMax)
  2058. cbStr = cbMax;
  2059. /* If a "special" length, return 0 */
  2060. else if (cbStr < 0)
  2061. cbStr = 0;
  2062. /* Otherwise just return length of the string */
  2063. return cbStr;
  2064. }
  2065. /***************************************************************************/
  2066. void INTFUNC DateToChar (
  2067. DATE_STRUCT FAR *lpDate,
  2068. LPUSTR lpChar)
  2069. {
  2070. wsprintf((LPSTR)lpChar, "%04d-%02u-%02u", lpDate->year, lpDate->month,
  2071. lpDate->day);
  2072. }
  2073. /***************************************************************************/
  2074. void INTFUNC TimeToChar (
  2075. TIME_STRUCT FAR *lpTime,
  2076. LPUSTR lpChar)
  2077. {
  2078. wsprintf((LPSTR)lpChar, "%02u:%02u:%02u", lpTime->hour, lpTime->minute,
  2079. lpTime->second);
  2080. }
  2081. /***************************************************************************/
  2082. void INTFUNC TimestampToChar (
  2083. TIMESTAMP_STRUCT FAR *lpTimestamp,
  2084. LPUSTR lpChar)
  2085. {
  2086. UCHAR szTemplate[36];
  2087. UDWORD fraction;
  2088. int i;
  2089. if (TIMESTAMP_SCALE > 0) {
  2090. s_lstrcpy((LPSTR)szTemplate, "%04d-%02u-%02u %02u:%02u:%02u.%0");
  2091. wsprintf((LPSTR)szTemplate + lstrlen((char*)szTemplate), "%1u", (UWORD) TIMESTAMP_SCALE);
  2092. s_lstrcat((LPSTR)szTemplate, "lu");
  2093. fraction = lpTimestamp->fraction;
  2094. for (i = 9 - TIMESTAMP_SCALE; i != 0; i--)
  2095. fraction = fraction/10;
  2096. wsprintf((LPSTR)lpChar, (LPSTR)szTemplate,
  2097. lpTimestamp->year, lpTimestamp->month, lpTimestamp->day,
  2098. lpTimestamp->hour, lpTimestamp->minute, lpTimestamp->second,
  2099. fraction);
  2100. }
  2101. else {
  2102. wsprintf((LPSTR)lpChar, "%04d-%02u-%02u %02u:%02u:%02u",
  2103. lpTimestamp->year, lpTimestamp->month, lpTimestamp->day,
  2104. lpTimestamp->hour, lpTimestamp->minute, lpTimestamp->second);
  2105. }
  2106. }
  2107. /***************************************************************************/
  2108. #define UPPER(c) ((((c) < 'a') || ((c) > 'z')) ? (c) : (((c) - 'a') + 'A'))
  2109. #define CHARCHECK(c) \
  2110. if (cbChar == 0) \
  2111. return ERR_NOTCONVERTABLE; \
  2112. if (UPPER (*ptr) != UPPER(c)) \
  2113. return ERR_NOTCONVERTABLE; \
  2114. ptr++; \
  2115. cbChar--;
  2116. #define GETDIGIT(val) \
  2117. if (cbChar == 0) \
  2118. return ERR_NOTCONVERTABLE; \
  2119. if ((*ptr < '0') || (*ptr > '9')) \
  2120. return ERR_NOTCONVERTABLE; \
  2121. val = (val * 10) + (*ptr - '0'); \
  2122. ptr++; \
  2123. cbChar--;
  2124. #define CLEARBLANKS \
  2125. while ((cbChar > 0) && (*ptr == ' ')) { \
  2126. ptr++; \
  2127. cbChar--; \
  2128. }
  2129. /***************************************************************************/
  2130. RETCODE INTFUNC CharToDate (
  2131. LPUSTR lpChar,
  2132. SDWORD cbChar,
  2133. DATE_STRUCT FAR *lpDate)
  2134. {
  2135. LPUSTR ptr;
  2136. BOOL fEscape;
  2137. BOOL fShorthand;
  2138. /* Point to string */
  2139. ptr = lpChar;
  2140. if (cbChar == SQL_NTS)
  2141. cbChar = s_lstrlen(lpChar);
  2142. if (cbChar < 0)
  2143. cbChar = 0;
  2144. /* Clear leading blanks */
  2145. CLEARBLANKS
  2146. if (cbChar == 0)
  2147. return ERR_NOTCONVERTABLE;
  2148. /* Start of escape clause? */
  2149. if (*ptr == '-') {
  2150. /* Yes. Set flags */
  2151. fEscape = TRUE;
  2152. fShorthand = FALSE;
  2153. /* Point at the next character */
  2154. ptr++;
  2155. cbChar--;
  2156. /* Make sure the rest of the escape clause is correct */
  2157. CHARCHECK('-')
  2158. CHARCHECK('(')
  2159. CHARCHECK('*')
  2160. CLEARBLANKS
  2161. CHARCHECK('V')
  2162. CHARCHECK('E')
  2163. CHARCHECK('N')
  2164. CHARCHECK('D')
  2165. CHARCHECK('O')
  2166. CHARCHECK('R')
  2167. CLEARBLANKS
  2168. CHARCHECK('(')
  2169. CLEARBLANKS
  2170. CHARCHECK('M')
  2171. CHARCHECK('i')
  2172. CHARCHECK('c')
  2173. CHARCHECK('r')
  2174. CHARCHECK('o')
  2175. CHARCHECK('s')
  2176. CHARCHECK('o')
  2177. CHARCHECK('f')
  2178. CHARCHECK('t')
  2179. CLEARBLANKS
  2180. CHARCHECK(')')
  2181. CLEARBLANKS
  2182. CHARCHECK(',')
  2183. CLEARBLANKS
  2184. CHARCHECK('P')
  2185. CHARCHECK('R')
  2186. CHARCHECK('O')
  2187. CHARCHECK('D')
  2188. CHARCHECK('U')
  2189. CHARCHECK('C')
  2190. CHARCHECK('T')
  2191. CLEARBLANKS
  2192. CHARCHECK('(')
  2193. CLEARBLANKS
  2194. CHARCHECK('O')
  2195. CHARCHECK('D')
  2196. CHARCHECK('B')
  2197. CHARCHECK('C')
  2198. CLEARBLANKS
  2199. CHARCHECK(')')
  2200. CLEARBLANKS
  2201. CHARCHECK('d')
  2202. CLEARBLANKS
  2203. CHARCHECK('\'')
  2204. }
  2205. /* Start of shorthand? */
  2206. else if (*ptr == '{') {
  2207. /* Yes. Set flags */
  2208. fEscape = FALSE;
  2209. fShorthand = TRUE;
  2210. /* Point at the next character */
  2211. ptr++;
  2212. cbChar--;
  2213. /* Make sure the rest of the escape clause is correct */
  2214. CLEARBLANKS
  2215. CHARCHECK('d')
  2216. CLEARBLANKS
  2217. CHARCHECK('\'')
  2218. }
  2219. /* Plain value? */
  2220. else {
  2221. /* Yes. Set flags */
  2222. fEscape = FALSE;
  2223. fShorthand = FALSE;
  2224. }
  2225. /* Get year */
  2226. lpDate->year = 0;
  2227. GETDIGIT(lpDate->year)
  2228. GETDIGIT(lpDate->year)
  2229. GETDIGIT(lpDate->year)
  2230. GETDIGIT(lpDate->year)
  2231. /* Get separator */
  2232. CHARCHECK('-')
  2233. /* Get month */
  2234. lpDate->month = 0;
  2235. GETDIGIT(lpDate->month)
  2236. GETDIGIT(lpDate->month)
  2237. /* Get separator */
  2238. CHARCHECK('-')
  2239. /* Get day */
  2240. lpDate->day = 0;
  2241. GETDIGIT(lpDate->day)
  2242. GETDIGIT(lpDate->day)
  2243. /* Escape clause? */
  2244. if (fEscape) {
  2245. /* Make sure it is properly terminated */
  2246. CHARCHECK('\'')
  2247. CLEARBLANKS
  2248. CHARCHECK('*')
  2249. CHARCHECK(')')
  2250. CHARCHECK('-')
  2251. CHARCHECK('-')
  2252. }
  2253. /* Shorthand? */
  2254. if (fShorthand) {
  2255. /* Make sure it is properly terminated */
  2256. CHARCHECK('\'')
  2257. CLEARBLANKS
  2258. CHARCHECK('}')
  2259. }
  2260. /* Make sure only trailing blanks */
  2261. CLEARBLANKS
  2262. if (cbChar != 0)
  2263. return ERR_NOTCONVERTABLE;
  2264. /* Make sure date is legal */
  2265. if ((lpDate->year != 0) || (lpDate->month != 0) || (lpDate->day != 0)) {
  2266. switch (lpDate->month) {
  2267. case 1: /* January */
  2268. case 3: /* March */
  2269. case 5: /* May */
  2270. case 7: /* July */
  2271. case 8: /* August */
  2272. case 10: /* October */
  2273. case 12: /* December */
  2274. if ((lpDate->day < 1) || (lpDate->day > 31))
  2275. return ERR_NOTCONVERTABLE;
  2276. break;
  2277. case 4: /* April */
  2278. case 6: /* June */
  2279. case 9: /* September */
  2280. case 11: /* November */
  2281. if ((lpDate->day < 1) || (lpDate->day > 30))
  2282. return ERR_NOTCONVERTABLE;
  2283. break;
  2284. case 2: /* February */
  2285. if (((lpDate->year / 400) * 400) == lpDate->year) {
  2286. if ((lpDate->day < 1) || (lpDate->day > 29))
  2287. return ERR_NOTCONVERTABLE;
  2288. }
  2289. else if (((lpDate->year / 100) * 100) == lpDate->year) {
  2290. if ((lpDate->day < 1) || (lpDate->day > 28))
  2291. return ERR_NOTCONVERTABLE;
  2292. }
  2293. else if (((lpDate->year / 4) * 4) == lpDate->year) {
  2294. if ((lpDate->day < 1) || (lpDate->day > 29))
  2295. return ERR_NOTCONVERTABLE;
  2296. }
  2297. else {
  2298. if ((lpDate->day < 1) || (lpDate->day > 28))
  2299. return ERR_NOTCONVERTABLE;
  2300. }
  2301. break;
  2302. default:
  2303. return ERR_NOTCONVERTABLE;
  2304. }
  2305. }
  2306. return 0;
  2307. }
  2308. /***************************************************************************/
  2309. RETCODE INTFUNC CharToTime (
  2310. LPUSTR lpChar,
  2311. SDWORD cbChar,
  2312. TIME_STRUCT FAR *lpTime)
  2313. {
  2314. LPUSTR ptr;
  2315. BOOL fEscape;
  2316. BOOL fShorthand;
  2317. /* Point to string */
  2318. ptr = lpChar;
  2319. if (cbChar == SQL_NTS)
  2320. cbChar = s_lstrlen(lpChar);
  2321. if (cbChar < 0)
  2322. cbChar = 0;
  2323. /* Clear leading blanks */
  2324. CLEARBLANKS
  2325. if (cbChar == 0)
  2326. return ERR_NOTCONVERTABLE;
  2327. /* Start of escape clause? */
  2328. if (*ptr == '-') {
  2329. /* Yes. Set flags */
  2330. fEscape = TRUE;
  2331. fShorthand = FALSE;
  2332. /* Point at the next character */
  2333. ptr++;
  2334. cbChar--;
  2335. /* Make sure the rest of the escape clause is correct */
  2336. CHARCHECK('-')
  2337. CHARCHECK('(')
  2338. CHARCHECK('*')
  2339. CLEARBLANKS
  2340. CHARCHECK('V')
  2341. CHARCHECK('E')
  2342. CHARCHECK('N')
  2343. CHARCHECK('D')
  2344. CHARCHECK('O')
  2345. CHARCHECK('R')
  2346. CLEARBLANKS
  2347. CHARCHECK('(')
  2348. CLEARBLANKS
  2349. CHARCHECK('M')
  2350. CHARCHECK('i')
  2351. CHARCHECK('c')
  2352. CHARCHECK('r')
  2353. CHARCHECK('o')
  2354. CHARCHECK('s')
  2355. CHARCHECK('o')
  2356. CHARCHECK('f')
  2357. CHARCHECK('t')
  2358. CLEARBLANKS
  2359. CHARCHECK(')')
  2360. CLEARBLANKS
  2361. CHARCHECK(',')
  2362. CLEARBLANKS
  2363. CHARCHECK('P')
  2364. CHARCHECK('R')
  2365. CHARCHECK('O')
  2366. CHARCHECK('D')
  2367. CHARCHECK('U')
  2368. CHARCHECK('C')
  2369. CHARCHECK('T')
  2370. CLEARBLANKS
  2371. CHARCHECK('(')
  2372. CLEARBLANKS
  2373. CHARCHECK('O')
  2374. CHARCHECK('D')
  2375. CHARCHECK('B')
  2376. CHARCHECK('C')
  2377. CLEARBLANKS
  2378. CHARCHECK(')')
  2379. CLEARBLANKS
  2380. CHARCHECK('t')
  2381. CLEARBLANKS
  2382. CHARCHECK('\'')
  2383. }
  2384. /* Start of shorthand? */
  2385. else if (*ptr == '{') {
  2386. /* Yes. Set flags */
  2387. fEscape = FALSE;
  2388. fShorthand = TRUE;
  2389. /* Point at the next character */
  2390. ptr++;
  2391. cbChar--;
  2392. /* Make sure the rest of the escape clause is correct */
  2393. CLEARBLANKS
  2394. CHARCHECK('t')
  2395. CLEARBLANKS
  2396. CHARCHECK('\'')
  2397. }
  2398. /* Plain value? */
  2399. else {
  2400. /* Yes. Set flags */
  2401. fEscape = FALSE;
  2402. fShorthand = FALSE;
  2403. }
  2404. /* Get hour */
  2405. lpTime->hour = 0;
  2406. GETDIGIT(lpTime->hour)
  2407. GETDIGIT(lpTime->hour)
  2408. /* Get separator */
  2409. CHARCHECK(':')
  2410. /* Get minute */
  2411. lpTime->minute = 0;
  2412. GETDIGIT(lpTime->minute)
  2413. GETDIGIT(lpTime->minute)
  2414. /* Are seconds specified (or required)? */
  2415. lpTime->second = 0;
  2416. if (fEscape || fShorthand || ((cbChar != 0) && (*ptr == ':'))) {
  2417. /* Yes. Get separator */
  2418. CHARCHECK(':')
  2419. /* Get second */
  2420. GETDIGIT(lpTime->second)
  2421. GETDIGIT(lpTime->second)
  2422. }
  2423. /* Escape clause? */
  2424. if (fEscape) {
  2425. /* Make sure it is properly terminated */
  2426. CHARCHECK('\'')
  2427. CLEARBLANKS
  2428. CHARCHECK('*')
  2429. CHARCHECK(')')
  2430. CHARCHECK('-')
  2431. CHARCHECK('-')
  2432. }
  2433. /* Shorthand? */
  2434. if (fShorthand) {
  2435. /* Make sure it is properly terminated */
  2436. CHARCHECK('\'')
  2437. CLEARBLANKS
  2438. CHARCHECK('}')
  2439. }
  2440. /* AM or PM specified? */
  2441. CLEARBLANKS
  2442. if (!fEscape && !fShorthand) {
  2443. if (cbChar != 0) {
  2444. switch (*ptr) {
  2445. case 'p':
  2446. case 'P':
  2447. lpTime->hour += (12);
  2448. /* **** DROP DOWN TO NEXT CASE **** */
  2449. case 'a':
  2450. case 'A':
  2451. /* **** CONTROL MAY COME HERE FROM PREVIOUS CASE **** */
  2452. ptr++;
  2453. cbChar--;
  2454. if (cbChar != 0) {
  2455. switch (*ptr) {
  2456. case 'm':
  2457. case 'M':
  2458. case ' ':
  2459. break;
  2460. default:
  2461. return ERR_NOTCONVERTABLE;
  2462. }
  2463. ptr++;
  2464. cbChar--;
  2465. }
  2466. break;
  2467. default:
  2468. return ERR_NOTCONVERTABLE;
  2469. }
  2470. }
  2471. CLEARBLANKS
  2472. }
  2473. /* Make sure only trailing blanks */
  2474. if (cbChar != 0)
  2475. return ERR_NOTCONVERTABLE;
  2476. /* Make sure time is legal */
  2477. if (lpTime->hour > 23)
  2478. return ERR_NOTCONVERTABLE;
  2479. if (lpTime->minute > 59)
  2480. return ERR_NOTCONVERTABLE;
  2481. if (lpTime->second > 59)
  2482. return ERR_NOTCONVERTABLE;
  2483. return 0;
  2484. }
  2485. /***************************************************************************/
  2486. RETCODE INTFUNC CharToTimestamp (
  2487. LPUSTR lpChar,
  2488. SDWORD cbChar,
  2489. TIMESTAMP_STRUCT FAR *lpTimestamp)
  2490. {
  2491. LPUSTR ptr;
  2492. BOOL fEscape;
  2493. BOOL fShorthand;
  2494. UWORD i;
  2495. /* Point to string */
  2496. ptr = lpChar;
  2497. if (cbChar == SQL_NTS)
  2498. cbChar = s_lstrlen(lpChar);
  2499. if (cbChar < 0)
  2500. cbChar = 0;
  2501. /* Clear leading blanks */
  2502. CLEARBLANKS
  2503. if (cbChar == 0)
  2504. return ERR_NOTCONVERTABLE;
  2505. /* Start of escape clause? */
  2506. if (*ptr == '-') {
  2507. /* Yes. Set flags */
  2508. fEscape = TRUE;
  2509. fShorthand = FALSE;
  2510. /* Point at the next character */
  2511. ptr++;
  2512. cbChar--;
  2513. /* Make sure the rest of the escape clause is correct */
  2514. CHARCHECK('-')
  2515. CHARCHECK('(')
  2516. CHARCHECK('*')
  2517. CLEARBLANKS
  2518. CHARCHECK('V')
  2519. CHARCHECK('E')
  2520. CHARCHECK('N')
  2521. CHARCHECK('D')
  2522. CHARCHECK('O')
  2523. CHARCHECK('R')
  2524. CLEARBLANKS
  2525. CHARCHECK('(')
  2526. CLEARBLANKS
  2527. CHARCHECK('M')
  2528. CHARCHECK('i')
  2529. CHARCHECK('c')
  2530. CHARCHECK('r')
  2531. CHARCHECK('o')
  2532. CHARCHECK('s')
  2533. CHARCHECK('o')
  2534. CHARCHECK('f')
  2535. CHARCHECK('t')
  2536. CLEARBLANKS
  2537. CHARCHECK(')')
  2538. CLEARBLANKS
  2539. CHARCHECK(',')
  2540. CLEARBLANKS
  2541. CHARCHECK('P')
  2542. CHARCHECK('R')
  2543. CHARCHECK('O')
  2544. CHARCHECK('D')
  2545. CHARCHECK('U')
  2546. CHARCHECK('C')
  2547. CHARCHECK('T')
  2548. CLEARBLANKS
  2549. CHARCHECK('(')
  2550. CLEARBLANKS
  2551. CHARCHECK('O')
  2552. CHARCHECK('D')
  2553. CHARCHECK('B')
  2554. CHARCHECK('C')
  2555. CLEARBLANKS
  2556. CHARCHECK(')')
  2557. CLEARBLANKS
  2558. CHARCHECK('t')
  2559. CHARCHECK('s')
  2560. CLEARBLANKS
  2561. CHARCHECK('\'')
  2562. }
  2563. /* Start of shorthand? */
  2564. else if (*ptr == '{') {
  2565. /* Yes. Set flags */
  2566. fEscape = FALSE;
  2567. fShorthand = TRUE;
  2568. /* Point at the next character */
  2569. ptr++;
  2570. cbChar--;
  2571. /* Make sure the rest of the escape clause is correct */
  2572. CLEARBLANKS
  2573. CHARCHECK('t')
  2574. CHARCHECK('s')
  2575. CLEARBLANKS
  2576. CHARCHECK('\'')
  2577. }
  2578. /* Plain value? */
  2579. else {
  2580. /* Yes. Set flags */
  2581. fEscape = FALSE;
  2582. fShorthand = FALSE;
  2583. }
  2584. /* Get year */
  2585. lpTimestamp->year = 0;
  2586. GETDIGIT(lpTimestamp->year)
  2587. GETDIGIT(lpTimestamp->year)
  2588. GETDIGIT(lpTimestamp->year)
  2589. GETDIGIT(lpTimestamp->year)
  2590. /* Get separator */
  2591. CHARCHECK('-')
  2592. /* Get month */
  2593. lpTimestamp->month = 0;
  2594. GETDIGIT(lpTimestamp->month)
  2595. GETDIGIT(lpTimestamp->month)
  2596. /* Get separator */
  2597. CHARCHECK('-')
  2598. /* Get day */
  2599. lpTimestamp->day = 0;
  2600. GETDIGIT(lpTimestamp->day)
  2601. GETDIGIT(lpTimestamp->day)
  2602. /* Get separator */
  2603. CHARCHECK(' ')
  2604. /* Get hour */
  2605. lpTimestamp->hour = 0;
  2606. GETDIGIT(lpTimestamp->hour)
  2607. GETDIGIT(lpTimestamp->hour)
  2608. /* Get separator */
  2609. CHARCHECK(':')
  2610. /* Get minute */
  2611. lpTimestamp->minute = 0;
  2612. GETDIGIT(lpTimestamp->minute)
  2613. GETDIGIT(lpTimestamp->minute)
  2614. /* Get separator */
  2615. CHARCHECK(':')
  2616. /* Get second */
  2617. lpTimestamp->second = 0;
  2618. GETDIGIT(lpTimestamp->second)
  2619. GETDIGIT(lpTimestamp->second)
  2620. /* Is a fraction specified? */
  2621. lpTimestamp->fraction = 0;
  2622. if ((cbChar != 0) && (*ptr == '.')) {
  2623. /* Yes. Get separator */
  2624. CHARCHECK('.')
  2625. /* Get fraction */
  2626. for (i=0; i < 9; i++) {
  2627. if ((*ptr < '0') || (*ptr > '9'))
  2628. break;
  2629. GETDIGIT(lpTimestamp->fraction)
  2630. }
  2631. for (; i < 9; i++)
  2632. lpTimestamp->fraction = lpTimestamp->fraction * 10;
  2633. }
  2634. /* Escape clause? */
  2635. if (fEscape) {
  2636. /* Make sure it is properly terminated */
  2637. CHARCHECK('\'')
  2638. CLEARBLANKS
  2639. CHARCHECK('*')
  2640. CHARCHECK(')')
  2641. CHARCHECK('-')
  2642. CHARCHECK('-')
  2643. }
  2644. /* Shorthand? */
  2645. if (fShorthand) {
  2646. /* Make sure it is properly terminated */
  2647. CHARCHECK('\'')
  2648. CLEARBLANKS
  2649. CHARCHECK('}')
  2650. }
  2651. /* Make sure only trailing blanks */
  2652. CLEARBLANKS
  2653. if (cbChar != 0)
  2654. return ERR_NOTCONVERTABLE;
  2655. /* Make sure timestamp is legal */
  2656. if ((lpTimestamp->year != 0) || (lpTimestamp->month != 0) ||
  2657. (lpTimestamp->day != 0) || (lpTimestamp->hour != 0) ||
  2658. (lpTimestamp->minute != 0) || (lpTimestamp->second != 0) ||
  2659. (lpTimestamp->fraction != 0)) {
  2660. switch (lpTimestamp->month) {
  2661. case 1: /* January */
  2662. case 3: /* March */
  2663. case 5: /* May */
  2664. case 7: /* July */
  2665. case 8: /* August */
  2666. case 10: /* October */
  2667. case 12: /* December */
  2668. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 31))
  2669. return ERR_NOTCONVERTABLE;
  2670. break;
  2671. case 4: /* April */
  2672. case 6: /* June */
  2673. case 9: /* September */
  2674. case 11: /* November */
  2675. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 30))
  2676. return ERR_NOTCONVERTABLE;
  2677. break;
  2678. case 2: /* February */
  2679. if (((lpTimestamp->year / 400) * 400) == lpTimestamp->year) {
  2680. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 29))
  2681. return ERR_NOTCONVERTABLE;
  2682. }
  2683. else if (((lpTimestamp->year / 100) * 100) == lpTimestamp->year) {
  2684. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 28))
  2685. return ERR_NOTCONVERTABLE;
  2686. }
  2687. else if (((lpTimestamp->year / 4) * 4) == lpTimestamp->year) {
  2688. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 29))
  2689. return ERR_NOTCONVERTABLE;
  2690. }
  2691. else {
  2692. if ((lpTimestamp->day < 1) || (lpTimestamp->day > 28))
  2693. return ERR_NOTCONVERTABLE;
  2694. }
  2695. break;
  2696. default:
  2697. return ERR_NOTCONVERTABLE;
  2698. }
  2699. }
  2700. if (lpTimestamp->hour > 23)
  2701. return ERR_NOTCONVERTABLE;
  2702. if (lpTimestamp->minute > 59)
  2703. return ERR_NOTCONVERTABLE;
  2704. if (lpTimestamp->second > 59)
  2705. return ERR_NOTCONVERTABLE;
  2706. return 0;
  2707. }
  2708. /***************************************************************************/
  2709. #ifndef WIN32
  2710. BOOL INTFUNC DeleteFile (
  2711. LPCSTR lpszFilename)
  2712. {
  2713. static UCHAR szFilename[MAX_PATHNAME_SIZE+1];
  2714. szFilename[0] = 0;
  2715. lstrcpy(szFilename, lpszFilename);
  2716. remove(szFilename);
  2717. return TRUE;
  2718. }
  2719. #endif
  2720. /***************************************************************************/