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.

1638 lines
43 KiB

  1. /***************************************************************************/
  2. /* DBASE.C - This is the module containing the code to read and write */
  3. /* dBASE files. */
  4. /* */
  5. /* (C) Copyright 1993-96 - SYWARE, Inc. - All rights reserved */
  6. /***************************************************************************/
  7. #include "precomp.h"
  8. #include "wbemidl.h"
  9. #include "dbase.h"
  10. #include <stdio.h>
  11. #include <time.h>
  12. #define s_lstrcpy(a, b) lstrcpy((LPSTR) a, (LPCSTR) b)
  13. #define s_lstrcat(a, b) lstrcat((LPSTR) a, (LPCSTR) b)
  14. #define s_lstrlen(a) lstrlen((LPCSTR) a)
  15. #define s_lstrcmp(a, b) lstrcmp((LPCSTR) a, (LPCSTR) b)
  16. /***************************************************************************/
  17. #define FIRST_RECORD 0xFFFFFFFF
  18. #define LAST_RECORD 0xFFFFFFFE
  19. /***************************************************************************/
  20. SWORD FAR PASCAL dBaseExtendedOpen(LPUSTR name, BOOL fReadOnly,
  21. UWORD extraColumns, LPDBASEFILE FAR *lpf)
  22. {
  23. /*
  24. HFILE hf;
  25. UWORD columnCount;
  26. UWORD recordLen;
  27. HGLOBAL h;
  28. LPDBASEFILE f;
  29. UWORD i;
  30. UCHAR FAR * ptr;
  31. UCHAR fullname[DBASE_MAX_PATHNAME_SIZE+1];
  32. // Get the filename
  33. s_lstrcpy((char*)fullname, name);
  34. ptr = fullname + s_lstrlen((char*)fullname);
  35. while ((ptr != fullname) && (*ptr != PATH_SEPARATOR_CHAR) && (*ptr != ':') &&
  36. (*ptr != '.'))
  37. ptr--;
  38. if (*ptr != '.')
  39. s_lstrcat((char*)fullname, ".dbf");
  40. // Open the file
  41. if (fReadOnly)
  42. hf = _lopen((LPCSTR)fullname, OF_READ);
  43. else
  44. hf = _lopen((LPCSTR)fullname, OF_READWRITE);
  45. if (hf == HFILE_ERROR)
  46. return DBASE_ERR_TABLEACCESSERROR;
  47. //Figure out how many columns there are
  48. if (HFILE_ERROR == _llseek(hf, DBASE_HEADER_SIZE_OFFSET, 0)) {
  49. _lclose(hf);
  50. return DBASE_ERR_CORRUPTFILE;
  51. }
  52. if (sizeof(UWORD) != _lread(hf, &columnCount, sizeof(UWORD))) {
  53. _lclose(hf);
  54. return DBASE_ERR_CORRUPTFILE;
  55. }
  56. columnCount = (columnCount - DBASE_HEADER_LENGTH - 1)/
  57. DBASE_COLUMN_DESCR_LENGTH;
  58. // Get record size
  59. if (HFILE_ERROR == _llseek(hf, DBASE_RECORD_LENGTH_OFFSET, 0)) {
  60. _lclose(hf);
  61. return DBASE_ERR_CORRUPTFILE;
  62. }
  63. if (sizeof(UWORD) != _lread(hf, &recordLen, sizeof(UWORD))) {
  64. _lclose(hf);
  65. return DBASE_ERR_CORRUPTFILE;
  66. }
  67. // Allocate space for handle
  68. h = GlobalAlloc (GMEM_MOVEABLE, (sizeof(DBASEFILE) - sizeof(DBASECOL)) +
  69. (sizeof(DBASECOL) * (columnCount + extraColumns)) + recordLen);
  70. if (h == NULL || (f = (LPDBASEFILE)GlobalLock (h)) == NULL)
  71. {
  72. _lclose(hf);
  73. return DBASE_ERR_MEMALLOCFAIL;
  74. }
  75. // Read in the header
  76. if (HFILE_ERROR == _llseek(hf, 0, 0)) {
  77. GlobalUnlock(h);
  78. GlobalFree(h);
  79. _lclose(hf);
  80. return DBASE_ERR_CORRUPTFILE;
  81. }
  82. if (DBASE_HEADER_LENGTH != _lread(hf, f, DBASE_HEADER_LENGTH)) {
  83. GlobalUnlock(h);
  84. GlobalFree(h);
  85. _lclose(hf);
  86. return DBASE_ERR_CORRUPTFILE;
  87. }
  88. if (f->encrypted != DBASE_NOT_ENCRYPTED) {
  89. GlobalUnlock(h);
  90. GlobalFree(h);
  91. _lclose(hf);
  92. return DBASE_ERR_CORRUPTFILE;
  93. }
  94. f->hf = hf;
  95. f->columnCount = columnCount;
  96. f->sortArray = NULL;
  97. f->currentRecord = 0;
  98. f->record = ((UCHAR FAR *) (&(f->column))) +
  99. ((columnCount+extraColumns) * sizeof(DBASECOL));
  100. f->headerDirty = FALSE;
  101. f->recordDirty = FALSE;
  102. f->newRecord = FALSE;
  103. // Read in column definition
  104. ptr = f->record + 1;
  105. for (i = 0; (i < columnCount); i++) {
  106. if (DBASE_COLUMN_DESCR_LENGTH !=
  107. _lread(hf, &(f->column[i]), DBASE_COLUMN_DESCR_LENGTH)) {
  108. GlobalUnlock(h);
  109. GlobalFree(h);
  110. _lclose(hf);
  111. return DBASE_ERR_CORRUPTFILE;
  112. }
  113. OemToAnsiBuff((LPCSTR) f->column[i].name, f->column[i].name,
  114. DBASE_COLUMN_NAME_SIZE);
  115. f->column[i].value = ptr;
  116. ptr += f->column[i].length;
  117. }
  118. *lpf = f;
  119. */
  120. return DBASE_ERR_SUCCESS;
  121. }
  122. /***************************************************************************/
  123. SWORD FAR PASCAL dBaseFlushDirtyRecord(LPDBASEFILE f)
  124. {
  125. /*
  126. LONG offset;
  127. UCHAR c;
  128. UDWORD currentRecord;
  129. // Is there a dirty record?
  130. if (f->recordDirty) {
  131. // Yes. Write it back
  132. f->recordDirty = FALSE;
  133. if (f->sortArray == NULL)
  134. currentRecord = f->currentRecord-1;
  135. else
  136. currentRecord = f->sortArray[f->currentRecord-1];
  137. offset = f->headerSize + (currentRecord * f->recordSize);
  138. if (HFILE_ERROR == _llseek(f->hf, offset, 0)) {
  139. f->newRecord = FALSE;
  140. f->currentRecord = 0;
  141. return DBASE_ERR_CORRUPTFILE;
  142. }
  143. AnsiToOemBuff((LPCSTR) f->record, f->record, f->recordSize);
  144. if (f->recordSize != _lwrite(f->hf, (LPCSTR) f->record, f->recordSize)) {
  145. f->newRecord = FALSE;
  146. f->currentRecord = 0;
  147. return DBASE_ERR_WRITEERROR;
  148. }
  149. // Was this a new record?
  150. if (f->newRecord) {
  151. // Yes. Write the end-of-data mark
  152. f->newRecord = FALSE;
  153. c = DBASE_FILE_END;
  154. if (1 != _lwrite(f->hf, (LPCSTR) &c, 1)) {
  155. f->currentRecord = 0;
  156. return DBASE_ERR_WRITEERROR;
  157. }
  158. }
  159. // Write back the header
  160. f->headerDirty = TRUE;
  161. }
  162. */
  163. return DBASE_ERR_SUCCESS;
  164. }
  165. /***************************************************************************/
  166. SWORD FAR PASCAL dBaseQuickSortKeyCompare(LPDBASEFILE f, UWORD icol,
  167. BOOL descending, UDWORD left,
  168. UDWORD right, BOOL FAR *result)
  169. /* Is the key of the left greater than or equal the key of the right? */
  170. {
  171. /*
  172. SWORD err;
  173. UWORD size;
  174. UCHAR szLeft[255];
  175. UCHAR szRight[255];
  176. SDOUBLE dblLeft;
  177. SDOUBLE dblRight;
  178. BOOL nullLeft;
  179. BOOL nullRight;
  180. // Handle boundry conditions
  181. if (left == LAST_RECORD) {
  182. *result = TRUE;
  183. return DBASE_ERR_SUCCESS;
  184. }
  185. if (right == FIRST_RECORD) {
  186. *result = TRUE;
  187. return DBASE_ERR_SUCCESS;
  188. }
  189. if (left == FIRST_RECORD) {
  190. *result = FALSE;
  191. return DBASE_ERR_SUCCESS;
  192. }
  193. if (right == LAST_RECORD) {
  194. *result = FALSE;
  195. return DBASE_ERR_SUCCESS;
  196. }
  197. // Position to the right record
  198. if (HFILE_ERROR == _llseek(f->hf, f->headerSize + (right * f->recordSize),
  199. 0))
  200. return DBASE_ERR_CORRUPTFILE;
  201. // Read the right record
  202. size = _lread(f->hf, f->record, f->recordSize);
  203. if (size != f->recordSize)
  204. return DBASE_ERR_CORRUPTFILE;
  205. OemToAnsiBuff((LPCSTR) f->record, (LPSTR) f->record, f->recordSize);
  206. *(f->record) = DBASE_RECORD_NOT_DELETED;
  207. // Get the right key
  208. switch (f->column[icol-1].type) {
  209. case DBASE_CHAR:
  210. case DBASE_LOGICAL:
  211. case DBASE_DATE:
  212. case DBASE_MEMO:
  213. err = dBaseColumnCharVal(f, icol, 0, 255, szRight, &nullRight);
  214. break;
  215. case DBASE_NUMERIC:
  216. case DBASE_FLOAT:
  217. err = dBaseColumnNumVal(f, icol, &dblRight, &nullRight);
  218. break;
  219. }
  220. if (err != DBASE_ERR_SUCCESS)
  221. return err;
  222. // If right is null, return TRUE
  223. if (nullRight) {
  224. *result = TRUE;
  225. return DBASE_ERR_SUCCESS;
  226. }
  227. // Position to the left record
  228. if (HFILE_ERROR == _llseek(f->hf, f->headerSize + (left * f->recordSize),
  229. 0))
  230. return DBASE_ERR_CORRUPTFILE;
  231. // Read the left record
  232. size = _lread(f->hf, f->record, f->recordSize);
  233. if (size != f->recordSize)
  234. return DBASE_ERR_CORRUPTFILE;
  235. OemToAnsiBuff((LPCSTR) f->record, (LPSTR) f->record, f->recordSize);
  236. *(f->record) = DBASE_RECORD_NOT_DELETED;
  237. // Get the left key
  238. switch (f->column[icol-1].type) {
  239. case DBASE_CHAR:
  240. case DBASE_LOGICAL:
  241. case DBASE_DATE:
  242. case DBASE_MEMO:
  243. err = dBaseColumnCharVal(f, icol, 0, 255, szLeft, &nullLeft);
  244. break;
  245. case DBASE_NUMERIC:
  246. case DBASE_FLOAT:
  247. err = dBaseColumnNumVal(f, icol, &dblLeft, &nullLeft);
  248. break;
  249. }
  250. if (err != DBASE_ERR_SUCCESS)
  251. return err;
  252. // If left is null, return FALSE
  253. if (nullRight) {
  254. *result = FALSE;
  255. return DBASE_ERR_SUCCESS;
  256. }
  257. // Compare the keys
  258. switch (f->column[icol-1].type) {
  259. case DBASE_CHAR:
  260. case DBASE_LOGICAL:
  261. case DBASE_DATE:
  262. case DBASE_MEMO:
  263. if (!descending) {
  264. if (s_lstrcmp(szLeft, szRight) >= 0)
  265. *result = TRUE;
  266. else
  267. *result = FALSE;
  268. }
  269. else {
  270. if (s_lstrcmp(szLeft, szRight) <= 0)
  271. *result = TRUE;
  272. else
  273. *result = FALSE;
  274. }
  275. break;
  276. case DBASE_NUMERIC:
  277. case DBASE_FLOAT:
  278. if (!descending) {
  279. if (dblLeft >= dblRight)
  280. *result = TRUE;
  281. else
  282. *result = FALSE;
  283. }
  284. else {
  285. if (dblLeft <= dblRight)
  286. *result = TRUE;
  287. else
  288. *result = FALSE;
  289. }
  290. break;
  291. }
  292. */
  293. return DBASE_ERR_SUCCESS;
  294. }
  295. /***************************************************************************/
  296. SWORD FAR PASCAL dBaseQuickSort(LPDBASEFILE f, UWORD icol, BOOL descending,
  297. UDWORD FAR *sortArray, UDWORD left,
  298. UDWORD right)
  299. {
  300. /*
  301. UDWORD i;
  302. UDWORD j;
  303. UDWORD temp;
  304. SWORD err;
  305. BOOL result;
  306. // Q1:
  307. if (right <= left)
  308. return DBASE_ERR_SUCCESS;
  309. // Q2:
  310. i = left;
  311. j = right+1;
  312. while (TRUE) {
  313. // Q3:
  314. while (TRUE) {
  315. i++;
  316. err = dBaseQuickSortKeyCompare(f, icol, descending,
  317. sortArray[i], sortArray[left], &result);
  318. if (err != DBASE_ERR_SUCCESS)
  319. return err;
  320. if (result)
  321. break;
  322. }
  323. // Q4:
  324. while (TRUE) {
  325. j--;
  326. err = dBaseQuickSortKeyCompare(f, icol, descending,
  327. sortArray[left], sortArray[j], &result);
  328. if (err != DBASE_ERR_SUCCESS)
  329. return err;
  330. if (result)
  331. break;
  332. }
  333. // Q5:
  334. if (j <= i)
  335. break;
  336. // Q6:
  337. temp = sortArray[j];
  338. sortArray[j] = sortArray[i];
  339. sortArray[i] = temp;
  340. }
  341. // Q5:
  342. temp = sortArray[left];
  343. sortArray[left] = sortArray[j];
  344. sortArray[j] = temp;
  345. // Q7:
  346. err = dBaseQuickSort(f, icol, descending, sortArray, left, j-1);
  347. if (err != DBASE_ERR_SUCCESS)
  348. return err;
  349. // Q8:
  350. err = dBaseQuickSort(f, icol, descending, sortArray, j+1, right);
  351. if (err != DBASE_ERR_SUCCESS)
  352. return err;
  353. */
  354. return DBASE_ERR_SUCCESS;
  355. }
  356. /***************************************************************************/
  357. /***************************************************************************/
  358. SWORD FAR PASCAL dBaseCreate(LPUSTR name)
  359. {
  360. /*
  361. UCHAR FAR * ptr;
  362. DBASEFILE header;
  363. HFILE hf;
  364. int i;
  365. HANDLE h;
  366. UCHAR NEAR *fullname;
  367. UCHAR c;
  368. HANDLE ht;
  369. time_t *t;
  370. struct tm *ts;
  371. // Get the filename
  372. h = LocalAlloc(LMEM_MOVEABLE, DBASE_MAX_PATHNAME_SIZE+1);
  373. fullname = (UCHAR NEAR *) LocalLock(h);
  374. lstrcpy(fullname, name);
  375. ptr = fullname + lstrlen(fullname);
  376. while ((ptr != fullname) && (*ptr != '\\') && (*ptr != ':') &&
  377. (*ptr != '.'))
  378. ptr--;
  379. if (*ptr != '.')
  380. lstrcat(fullname, ".dbf");
  381. // Open the file
  382. hf = _lcreat(fullname, 0);
  383. if (hf == HFILE_ERROR) {
  384. LocalUnlock(h);
  385. LocalFree(h);
  386. return DBASE_ERR_CREATEERROR;
  387. }
  388. // Set up the header
  389. header.flag = DBASE_3_FILE;
  390. ht = LocalAlloc(LMEM_MOVEABLE, sizeof(time_t));
  391. t = (time_t NEAR *) LocalLock(ht);
  392. time(t);
  393. ts = localtime(t);
  394. LocalUnlock(ht);
  395. LocalFree(ht);
  396. header.year = ts->tm_year;
  397. header.month = ts->tm_mon + 1;
  398. header.day = ts->tm_mday;
  399. header.recordCount = 0;
  400. header.headerSize = DBASE_HEADER_LENGTH + 1;
  401. header.recordSize = 1;
  402. for (i=0; (i < 2); i++)
  403. header.reserved1[i] = 0;
  404. header.transaction = 0;
  405. header.encrypted = DBASE_NOT_ENCRYPTED;
  406. for (i=0; (i < 12); i++)
  407. header.reserved2[i] = 0;
  408. header.mdx = DBASE_MDX_FLAG_OFF;
  409. for (i=0; (i < 3); i++)
  410. header.reserved3[i] = 0;
  411. // Write the header
  412. if (DBASE_HEADER_LENGTH != _lwrite(hf, (LPSTR) &header,
  413. DBASE_HEADER_LENGTH)) {
  414. _lclose(hf);
  415. AnsiToOem(fullname, fullname);
  416. #ifdef WIN32
  417. DeleteFile(fullname);
  418. #else
  419. remove(fullname);
  420. #endif
  421. LocalUnlock(h);
  422. LocalFree(h);
  423. return DBASE_ERR_WRITEERROR;
  424. }
  425. // Write the end-of-columns mark
  426. c = DBASE_END_OF_COLUMNS;
  427. if (1 != _lwrite(hf, &c, 1)) {
  428. _lclose(hf);
  429. AnsiToOem(fullname, fullname);
  430. #ifdef WIN32
  431. DeleteFile(fullname);
  432. #else
  433. remove(fullname);
  434. #endif
  435. LocalUnlock(h);
  436. LocalFree(h);
  437. return DBASE_ERR_WRITEERROR;
  438. }
  439. // Write the end-of-data mark
  440. c = DBASE_FILE_END;
  441. if (1 != _lwrite(hf, &c, 1)) {
  442. _lclose(hf);
  443. AnsiToOem(fullname, fullname);
  444. #ifdef WIN32
  445. DeleteFile(fullname);
  446. #else
  447. remove(fullname);
  448. #endif
  449. LocalUnlock(h);
  450. LocalFree(h);
  451. return DBASE_ERR_WRITEERROR;
  452. }
  453. // Close the file
  454. if (HFILE_ERROR == _lclose(hf)) {
  455. AnsiToOem(fullname, fullname);
  456. #ifdef WIN32
  457. DeleteFile(fullname);
  458. #else
  459. remove(fullname);
  460. #endif
  461. LocalUnlock(h);
  462. LocalFree(h);
  463. return DBASE_ERR_CLOSEERROR;
  464. }
  465. LocalUnlock(h);
  466. LocalFree(h);
  467. */
  468. return DBASE_ERR_SUCCESS;
  469. }
  470. /***************************************************************************/
  471. SWORD FAR PASCAL dBaseAddColumn(LPUSTR name, LPUSTR colName, UCHAR type,
  472. UCHAR length, UCHAR scale)
  473. {
  474. /*
  475. LPDBASEFILE f;
  476. LPSTR from;
  477. int i;
  478. LONG offset;
  479. UCHAR c;
  480. SWORD err;
  481. // Check the column name
  482. if (lstrlen(colName) > DBASE_COLUMN_NAME_SIZE)
  483. return DBASE_ERR_NOTSUPPORTED;
  484. // Check the length and scale
  485. switch (type) {
  486. case DBASE_CHAR:
  487. if ((length == 0) || (length > 254))
  488. return DBASE_ERR_NOTSUPPORTED;
  489. scale = 0;
  490. break;
  491. case DBASE_NUMERIC:
  492. case DBASE_FLOAT:
  493. if ((length == 0) || (length > 19))
  494. return DBASE_ERR_NOTSUPPORTED;
  495. if (length == 1) {
  496. if (scale != 0)
  497. return DBASE_ERR_NOTSUPPORTED;
  498. }
  499. else if (((UCHAR) (scale+2)) > length)
  500. return DBASE_ERR_NOTSUPPORTED;
  501. break;
  502. case DBASE_LOGICAL:
  503. length = 1;
  504. scale = 0;
  505. break;
  506. case DBASE_DATE:
  507. length = 8;
  508. scale = 0;
  509. break;
  510. case DBASE_MEMO:
  511. return DBASE_ERR_NOTSUPPORTED;
  512. default:
  513. return DBASE_ERR_NOTSUPPORTED;
  514. }
  515. // Open the file
  516. err = dBaseExtendedOpen(name, FALSE, 1, &f) ;
  517. if (err != DBASE_ERR_SUCCESS)
  518. return err;
  519. if (f->recordCount != 0) {
  520. dBaseClose(f);
  521. return DBASE_ERR_NOTSUPPORTED;
  522. }
  523. // Fill in the new entry
  524. from = colName;
  525. for (i=0; (i < DBASE_COLUMN_NAME_SIZE); i++) {
  526. f->column[f->columnCount].name[i] = *from;
  527. if (*from != 0)
  528. from++;
  529. }
  530. f->column[f->columnCount].type = type;
  531. for (i=0; (i < 4); i++)
  532. f->column[f->columnCount].reserved1[i] = 0;
  533. f->column[f->columnCount].length = length;
  534. f->column[f->columnCount].scale = scale;
  535. for (i=0; (i < 2); i++)
  536. f->column[f->columnCount].reserved2[i] = 0;
  537. f->column[f->columnCount].workarea = 0;
  538. for (i=0; (i < 10); i++)
  539. f->column[f->columnCount].reserved3[i] = 0;
  540. f->column[f->columnCount].mdx = DBASE_MDX_FLAG_OFF;
  541. f->column[f->columnCount].value = NULL;
  542. // Write the new column information
  543. offset = DBASE_HEADER_LENGTH + (f->columnCount*DBASE_COLUMN_DESCR_LENGTH);
  544. if (HFILE_ERROR == _llseek(f->hf, offset, 0)) {
  545. dBaseClose(f);
  546. return DBASE_ERR_CORRUPTFILE;
  547. }
  548. AnsiToOemBuff(f->column[f->columnCount].name,
  549. f->column[f->columnCount].name, DBASE_COLUMN_NAME_SIZE);
  550. if (DBASE_COLUMN_DESCR_LENGTH != _lwrite(f->hf, (LPSTR)
  551. &(f->column[f->columnCount]), DBASE_COLUMN_DESCR_LENGTH)) {
  552. dBaseClose(f);
  553. return DBASE_ERR_WRITEERROR;
  554. }
  555. // Adust header information
  556. (f->columnCount)++;
  557. f->headerSize += DBASE_COLUMN_DESCR_LENGTH;
  558. f->recordSize += length;
  559. if (type == DBASE_FLOAT)
  560. f->flag = DBASE_4_FILE;
  561. // Put in end-of-columns mark
  562. c = DBASE_END_OF_COLUMNS;
  563. if (1 != _lwrite(f->hf, &c, 1)) {
  564. dBaseClose(f);
  565. return DBASE_ERR_WRITEERROR;
  566. }
  567. // Put in end-of-data mark
  568. c = DBASE_FILE_END;
  569. if (1 != _lwrite(f->hf, &c, 1)) {
  570. dBaseClose(f);
  571. return DBASE_ERR_WRITEERROR;
  572. }
  573. // Close the file
  574. f->headerDirty = TRUE;
  575. err = dBaseClose(f);
  576. if (err != DBASE_ERR_SUCCESS)
  577. return err;
  578. */
  579. return DBASE_ERR_SUCCESS;
  580. }
  581. /***************************************************************************/
  582. SWORD FAR PASCAL dBaseOpen(LPUSTR name, BOOL fReadOnly, LPDBASEFILE FAR *lpf)
  583. {
  584. return dBaseExtendedOpen(name, fReadOnly, 0, lpf);
  585. }
  586. /***************************************************************************/
  587. SWORD FAR PASCAL dBaseColumnCount(LPDBASEFILE f, UWORD FAR *count)
  588. {
  589. // *count = f->columnCount;
  590. return DBASE_ERR_SUCCESS;
  591. }
  592. /***************************************************************************/
  593. SWORD FAR PASCAL dBaseColumnName(LPDBASEFILE f, UWORD icol, LPUSTR name)
  594. {
  595. /*
  596. int i;
  597. if ((icol > f->columnCount) || (icol <= 0))
  598. return DBASE_ERR_NOSUCHCOLUMN;
  599. for (i = 0; i < DBASE_COLUMN_NAME_SIZE; i++)
  600. name[i] = f->column[icol-1].name[i];
  601. name[DBASE_COLUMN_NAME_SIZE] = '\0';
  602. */
  603. return DBASE_ERR_SUCCESS;
  604. }
  605. /***************************************************************************/
  606. SWORD FAR PASCAL dBaseColumnType(LPDBASEFILE f, UWORD icol, UCHAR FAR *type)
  607. {
  608. /*
  609. if ((icol > f->columnCount) || (icol <= 0))
  610. return DBASE_ERR_NOSUCHCOLUMN;
  611. *type = f->column[icol-1].type;
  612. */
  613. return DBASE_ERR_SUCCESS;
  614. }
  615. /***************************************************************************/
  616. SWORD FAR PASCAL dBaseColumnLength(LPDBASEFILE f, UWORD icol, UCHAR FAR *len)
  617. {
  618. /*
  619. if ((icol > f->columnCount) || (icol <= 0))
  620. return DBASE_ERR_NOSUCHCOLUMN;
  621. *len = f->column[icol-1].length;
  622. */
  623. return DBASE_ERR_SUCCESS;
  624. }
  625. /***************************************************************************/
  626. SWORD FAR PASCAL dBaseColumnScale(LPDBASEFILE f, UWORD icol, UCHAR FAR *scale)
  627. {
  628. /*
  629. if ((icol > f->columnCount) || (icol <= 0))
  630. return DBASE_ERR_NOSUCHCOLUMN;
  631. *scale = f->column[icol-1].scale;
  632. */
  633. return DBASE_ERR_SUCCESS;
  634. }
  635. /***************************************************************************/
  636. SWORD FAR PASCAL dBaseSort(LPDBASEFILE f, UWORD icol, BOOL descending)
  637. {
  638. /*
  639. SWORD err;
  640. HANDLE h;
  641. UDWORD FAR *sortArray;
  642. UDWORD idx;
  643. // Make sure column is really there
  644. if ((icol > f->columnCount) || (icol < 0))
  645. return DBASE_ERR_NOSUCHCOLUMN;
  646. // Write back any pending writes
  647. err = dBaseFlushDirtyRecord(f);
  648. if (err != DBASE_ERR_SUCCESS)
  649. return err;
  650. // Remove sort order (if any)
  651. if (f->sortArray != NULL) {
  652. GlobalUnlock(GlobalPtrHandle (f->sortArray));
  653. GlobalFree(GlobalPtrHandle(f->sortArray));
  654. f->sortArray = NULL;
  655. }
  656. // Is there a new sort?
  657. if (icol != 0) {
  658. // Yes. Allocate space for new sort
  659. h = GlobalAlloc (GMEM_MOVEABLE, (sizeof(UDWORD) * (f->recordCount + 2)));
  660. if (h == NULL || (sortArray = (UDWORD FAR *)GlobalLock (h)) == NULL)
  661. return DBASE_ERR_MEMALLOCFAIL;
  662. // Fill in the sort array
  663. sortArray[0] = FIRST_RECORD;
  664. for (idx = 1; idx < f->recordCount+1; idx++)
  665. sortArray[idx] = idx-1;
  666. sortArray[f->recordCount+1] = LAST_RECORD;
  667. // Sort the records
  668. f->currentRecord = 1;
  669. err = dBaseQuickSort(f, icol, descending, sortArray, 1, f->recordCount);
  670. if (err != DBASE_ERR_SUCCESS) {
  671. f->currentRecord = 0;
  672. GlobalUnlock(h);
  673. GlobalFree(h);
  674. return err;
  675. }
  676. f->currentRecord = 0;
  677. // Move the items into place
  678. for (idx = 0; idx < f->recordCount; idx++)
  679. sortArray[idx] = sortArray[idx+1];
  680. sortArray[f->recordCount] = f->recordCount;
  681. f->sortArray = sortArray;
  682. }
  683. // Position before record
  684. f->currentRecord = 0;
  685. */
  686. return DBASE_ERR_SUCCESS;
  687. }
  688. /***************************************************************************/
  689. SWORD FAR PASCAL dBaseReadFirst(LPDBASEFILE f)
  690. {
  691. /*
  692. LONG offset;
  693. SWORD err;
  694. UWORD size;
  695. UDWORD currentRecord;
  696. // Write back any pending writes
  697. err = dBaseFlushDirtyRecord(f);
  698. if (err != DBASE_ERR_SUCCESS)
  699. return err;
  700. // Position to the first record
  701. if (f->sortArray == NULL)
  702. currentRecord = 0;
  703. else
  704. currentRecord = f->sortArray[0];
  705. offset = f->headerSize + (currentRecord * f->recordSize);
  706. if (HFILE_ERROR == _llseek(f->hf, offset, 0))
  707. return DBASE_ERR_CORRUPTFILE;
  708. // Read the record
  709. size = _lread(f->hf, f->record, f->recordSize);
  710. if (size == 1) {
  711. if (*(f->record) == DBASE_FILE_END)
  712. return DBASE_ERR_NODATAFOUND;
  713. else
  714. return DBASE_ERR_CORRUPTFILE;
  715. }
  716. if (size != f->recordSize)
  717. return DBASE_ERR_CORRUPTFILE;
  718. f->currentRecord = 1;
  719. // If this record is deleted, return next record
  720. if (*(f->record) == DBASE_RECORD_DELETED)
  721. return dBaseReadNext(f);
  722. // Return record
  723. OemToAnsiBuff(f->record, f->record, f->recordSize);
  724. */
  725. return DBASE_ERR_SUCCESS;
  726. }
  727. /***************************************************************************/
  728. SWORD FAR PASCAL dBaseReadNext(LPDBASEFILE f)
  729. {
  730. /*
  731. LONG offset;
  732. SWORD err;
  733. UWORD size;
  734. UDWORD currentRecord;
  735. // Write back any pending writes
  736. err = dBaseFlushDirtyRecord(f);
  737. if (err != DBASE_ERR_SUCCESS)
  738. return err;
  739. // Position to the next record
  740. if (f->sortArray == NULL)
  741. currentRecord = f->currentRecord;
  742. else
  743. currentRecord = f->sortArray[f->currentRecord];
  744. offset = f->headerSize + (currentRecord * f->recordSize);
  745. if (HFILE_ERROR == _llseek(f->hf, offset, 0))
  746. return DBASE_ERR_CORRUPTFILE;
  747. // Read the record
  748. size = _lread(f->hf, f->record, f->recordSize);
  749. if (size == 1) {
  750. if (*(f->record) == DBASE_FILE_END)
  751. return DBASE_ERR_NODATAFOUND;
  752. else
  753. return DBASE_ERR_CORRUPTFILE;
  754. }
  755. if (size != f->recordSize)
  756. return DBASE_ERR_CORRUPTFILE;
  757. f->currentRecord++;
  758. // If this record is deleted, return next record
  759. if (*(f->record) == DBASE_RECORD_DELETED)
  760. return dBaseReadNext(f);
  761. // Return record
  762. OemToAnsiBuff(f->record, f->record, f->recordSize);
  763. */
  764. return DBASE_ERR_SUCCESS;
  765. }
  766. /***************************************************************************/
  767. SWORD FAR PASCAL dBaseColumnCharVal(LPDBASEFILE f, UWORD icol, UDWORD offset,
  768. SDWORD bufsize, UCHAR FAR *val,
  769. BOOL FAR *isNull)
  770. {
  771. /*
  772. LPDBASECOL lpCol;
  773. UCHAR FAR *fromPtr;
  774. UCHAR FAR *toPtr;
  775. UCHAR i;
  776. UWORD year;
  777. UWORD month;
  778. UWORD day;
  779. */
  780. SWORD err;
  781. /*
  782. // Make sure data is really there
  783. if ((icol > f->columnCount) || (icol <= 0))
  784. return DBASE_ERR_NOSUCHCOLUMN;
  785. if (f->currentRecord == 0)
  786. return DBASE_ERR_NODATAFOUND;
  787. if (*(f->record) == DBASE_RECORD_DELETED)
  788. return DBASE_ERR_NODATAFOUND;
  789. // Get the data
  790. lpCol = &(f->column[icol-1]);
  791. fromPtr = lpCol->value;
  792. */
  793. err = DBASE_ERR_SUCCESS;
  794. /*
  795. switch (lpCol->type) {
  796. case DBASE_CHAR:
  797. toPtr = val;
  798. *isNull = TRUE;
  799. if (bufsize <= ((SDWORD) lpCol->length)) {
  800. err = DBASE_ERR_TRUNCATION;
  801. }
  802. else {
  803. bufsize = lpCol->length;
  804. }
  805. for (i=0; i < (UCHAR) bufsize; i++) {
  806. if (*fromPtr != ' ')
  807. *isNull = FALSE;
  808. if (toPtr != NULL) {
  809. *toPtr = *fromPtr;
  810. toPtr++;
  811. }
  812. fromPtr++;
  813. }
  814. if (toPtr != NULL)
  815. *toPtr = '\0';
  816. break;
  817. case DBASE_FLOAT:
  818. case DBASE_NUMERIC:
  819. i = lpCol->length;
  820. while ((*fromPtr == ' ') && (i > 0)) {
  821. fromPtr++;
  822. i--;
  823. }
  824. toPtr = val;
  825. *isNull = TRUE;
  826. for (;i > 0; i--) {
  827. if (toPtr != NULL) {
  828. *toPtr = *fromPtr;
  829. toPtr++;
  830. }
  831. fromPtr++;
  832. *isNull = FALSE;
  833. }
  834. if (toPtr != NULL)
  835. *toPtr = '\0';
  836. break;
  837. case DBASE_DATE:
  838. if (*fromPtr == ' ')
  839. *isNull = TRUE;
  840. else {
  841. *isNull = FALSE;
  842. year = ((fromPtr[0] & 0x0F) * 1000) +
  843. ((fromPtr[1] & 0x0F) * 100) +
  844. ((fromPtr[2] & 0x0F) * 10) +
  845. (fromPtr[3] & 0x0F);
  846. month = ((fromPtr[4] & 0x0F) * 10) + (fromPtr[5] & 0x0F);
  847. day = ((fromPtr[6] & 0x0F) * 10) + (fromPtr[7] & 0x0F);
  848. if (val != NULL)
  849. wsprintf(val, "%04d-%02d-%02d", year, month, day);
  850. }
  851. break;
  852. case DBASE_LOGICAL:
  853. switch (*fromPtr) {
  854. case 'Y':
  855. case 'y':
  856. case 'T':
  857. case 't':
  858. case '1':
  859. if (val != NULL)
  860. lstrcpy(val, "1");
  861. *isNull = FALSE;
  862. break;
  863. case 'N':
  864. case 'n':
  865. case 'F':
  866. case 'f':
  867. case '0':
  868. if (val != NULL)
  869. lstrcpy(val, "0");
  870. *isNull = FALSE;
  871. break;
  872. case '?':
  873. case ' ':
  874. *isNull = TRUE;
  875. break;
  876. }
  877. break;
  878. case DBASE_MEMO:
  879. *isNull = TRUE;
  880. break;
  881. }
  882. if ((*isNull) && (val != NULL))
  883. lstrcpy(val, "");
  884. */
  885. return err;
  886. }
  887. /***************************************************************************/
  888. SWORD FAR PASCAL dBaseColumnNumVal(LPDBASEFILE f, UWORD icol,
  889. SDOUBLE FAR *val, BOOL FAR *isNull)
  890. {
  891. /*
  892. LPDBASECOL lpCol;
  893. UCHAR i;
  894. double d;
  895. BOOL neg;
  896. UCHAR FAR *fromPtr;
  897. BOOL foundDecimalPoint;
  898. short scale;
  899. BOOL negexp;
  900. short exp;
  901. // Make sure data is really there
  902. if ((icol > f->columnCount) || (icol <= 0))
  903. return DBASE_ERR_NOSUCHCOLUMN;
  904. if (f->currentRecord == 0)
  905. return DBASE_ERR_NODATAFOUND;
  906. if (*(f->record) == DBASE_RECORD_DELETED)
  907. return DBASE_ERR_NODATAFOUND;
  908. // Get the data
  909. lpCol = &(f->column[icol-1]);
  910. fromPtr = lpCol->value;
  911. switch (lpCol->type) {
  912. case DBASE_CHAR:
  913. case DBASE_FLOAT:
  914. case DBASE_NUMERIC:
  915. *isNull = TRUE;
  916. for (i=0; i < lpCol->length; i++) {
  917. if (*fromPtr != ' ')
  918. break;
  919. fromPtr++;
  920. }
  921. neg = FALSE;
  922. if (i < lpCol->length) {
  923. if (*fromPtr == '-') {
  924. neg = TRUE;
  925. fromPtr++;
  926. i++;
  927. }
  928. }
  929. d = 0.0;
  930. scale = 0;
  931. foundDecimalPoint = FALSE;
  932. for (;i < lpCol->length; i++) {
  933. if (!foundDecimalPoint && (*fromPtr == '.'))
  934. foundDecimalPoint = TRUE;
  935. else {
  936. if ((*fromPtr == 'E') || (*fromPtr == 'e')) {
  937. fromPtr++;
  938. i++;
  939. if (i < lpCol->length) {
  940. if (*fromPtr == '-') {
  941. negexp = TRUE;
  942. fromPtr++;
  943. i++;
  944. }
  945. else if (*fromPtr == '+') {
  946. negexp = FALSE;
  947. fromPtr++;
  948. i++;
  949. }
  950. else
  951. negexp = FALSE;
  952. }
  953. else
  954. negexp = FALSE;
  955. exp = 0;
  956. for (;i < lpCol->length; i++) {
  957. if ((*fromPtr < '0') || (*fromPtr > '9'))
  958. return DBASE_ERR_CONVERSIONERROR;
  959. exp = (exp * 10) + (*fromPtr - '0');
  960. fromPtr++;
  961. }
  962. if (negexp)
  963. scale = scale + exp;
  964. else
  965. scale = scale - exp;
  966. break;
  967. }
  968. if ((*fromPtr < '0') || (*fromPtr > '9'))
  969. return DBASE_ERR_CONVERSIONERROR;
  970. d = (d * 10) + (*fromPtr - '0');
  971. *isNull = FALSE;
  972. if (foundDecimalPoint)
  973. scale++;
  974. }
  975. fromPtr++;
  976. }
  977. for (; (0 < scale); scale--)
  978. d /= 10;
  979. for (; (0 > scale); scale++)
  980. d *= 10;
  981. if (val != NULL) {
  982. if (neg)
  983. *val = -d;
  984. else
  985. *val = d;
  986. }
  987. break;
  988. case DBASE_DATE:
  989. return DBASE_ERR_CONVERSIONERROR;
  990. case DBASE_LOGICAL:
  991. switch (*fromPtr) {
  992. case 'Y':
  993. case 'y':
  994. case 'T':
  995. case 't':
  996. case '1':
  997. if (val != NULL)
  998. *val = 1.0;
  999. *isNull = FALSE;
  1000. break;
  1001. case 'N':
  1002. case 'n':
  1003. case 'F':
  1004. case 'f':
  1005. case '0':
  1006. if (val != NULL)
  1007. *val = 0.0;
  1008. *isNull = FALSE;
  1009. break;
  1010. case '?':
  1011. case ' ':
  1012. *isNull = TRUE;
  1013. break;
  1014. }
  1015. break;
  1016. case DBASE_MEMO:
  1017. *isNull = TRUE;
  1018. break;
  1019. }
  1020. if ((val != NULL) && (*isNull))
  1021. *val = 0.0;
  1022. */
  1023. return DBASE_ERR_SUCCESS;
  1024. }
  1025. /***************************************************************************/
  1026. SWORD FAR PASCAL dBaseAddRecord(LPDBASEFILE f)
  1027. {
  1028. /*
  1029. UWORD i;
  1030. UCHAR FAR * ptr;
  1031. SWORD err;
  1032. // Write dirty record
  1033. err = dBaseFlushDirtyRecord(f);
  1034. if (err != DBASE_ERR_SUCCESS)
  1035. return err;
  1036. // Remove sort order (if any)
  1037. if (f->sortArray != NULL) {
  1038. GlobalUnlock(GlobalPtrHandle(f->sortArray));
  1039. GlobalFree(GlobalPtrHandle(f->sortArray));
  1040. f->sortArray = NULL;
  1041. }
  1042. // Create null record
  1043. ptr = f->record;
  1044. for (i=0; i < f->recordSize; i++) {
  1045. *ptr = ' ';
  1046. ptr++;
  1047. }
  1048. f->recordDirty = TRUE;
  1049. f->newRecord = TRUE;
  1050. // Increment record count
  1051. f->recordCount++;
  1052. f->headerDirty = TRUE;
  1053. // Reset current record
  1054. f->currentRecord = f->recordCount;
  1055. */
  1056. return DBASE_ERR_SUCCESS;
  1057. }
  1058. /***************************************************************************/
  1059. SWORD FAR PASCAL dBaseSetColumnCharVal(LPDBASEFILE f, UWORD icol,
  1060. UCHAR FAR *val, SDWORD size)
  1061. {
  1062. /*
  1063. LPDBASECOL lpCol;
  1064. UCHAR FAR *fromPtr;
  1065. UCHAR FAR *toPtr;
  1066. UCHAR FAR *decimalLocation;
  1067. UCHAR FAR *valStart;
  1068. UCHAR FAR *valEnd;
  1069. UCHAR FAR *ptr;
  1070. UCHAR length;
  1071. UCHAR i;
  1072. SWORD extraZeros;
  1073. BOOL negNeeded;
  1074. BOOL foundExp;
  1075. SWORD err;
  1076. // Make sure data is really there
  1077. if ((icol > f->columnCount) || (icol <= 0))
  1078. return DBASE_ERR_NOSUCHCOLUMN;
  1079. if (f->currentRecord == 0)
  1080. return DBASE_ERR_NODATAFOUND;
  1081. if (*(f->record) == DBASE_RECORD_DELETED)
  1082. return DBASE_ERR_NODATAFOUND;
  1083. // Set value
  1084. lpCol = &(f->column[icol-1]);
  1085. toPtr = lpCol->value;
  1086. err = DBASE_ERR_SUCCESS;
  1087. switch (lpCol->type) {
  1088. case DBASE_CHAR:
  1089. fromPtr = val;
  1090. for (i=0; i < lpCol->length; i++) {
  1091. if (((SDWORD) i) == size)
  1092. break;
  1093. *toPtr = *fromPtr;
  1094. toPtr++;
  1095. fromPtr++;
  1096. }
  1097. for (; i < lpCol->length; i++) {
  1098. *toPtr = ' ';
  1099. toPtr++;
  1100. }
  1101. if (((SDWORD) lpCol->length) < size)
  1102. err = DBASE_ERR_TRUNCATION;
  1103. break;
  1104. case DBASE_FLOAT:
  1105. case DBASE_NUMERIC:
  1106. // If a zero length string is specifed, point to a zero
  1107. if ((lpCol->scale == 0) && (size == 0)) {
  1108. val = "0";
  1109. size = 1;
  1110. }
  1111. // Point at start of value
  1112. length = lpCol->length - 1;
  1113. valStart = val;
  1114. if (*valStart == '-') {
  1115. valStart++;
  1116. }
  1117. // Make sure all characters are legal and find decimal point
  1118. foundExp = FALSE;
  1119. decimalLocation = NULL;
  1120. fromPtr = valStart;
  1121. i = 0;
  1122. while (((SDWORD) i) < size) {
  1123. if (*fromPtr == '\0')
  1124. break;
  1125. else if (*fromPtr == '.') {
  1126. if ((decimalLocation != NULL) || (foundExp))
  1127. return DBASE_ERR_CONVERSIONERROR;
  1128. decimalLocation = fromPtr;
  1129. }
  1130. else if ((*fromPtr == 'E') || (*fromPtr == 'e')) {
  1131. if (foundExp)
  1132. return DBASE_ERR_CONVERSIONERROR;
  1133. foundExp = TRUE;
  1134. if ((*fromPtr == '-') || (*fromPtr == '+')) {
  1135. fromPtr++;
  1136. i++;
  1137. }
  1138. }
  1139. else if (!(IsCharAlphaNumeric(*fromPtr)) || IsCharAlpha(*fromPtr))
  1140. return DBASE_ERR_CONVERSIONERROR;
  1141. fromPtr++;
  1142. i++;
  1143. }
  1144. // Scientific notation?
  1145. if (foundExp) {
  1146. // Yes. Error if not enough room for value
  1147. if (size > (SDWORD) lpCol->length)
  1148. return DBASE_ERR_CONVERSIONERROR;
  1149. // Copy the value
  1150. for (i=0; (SWORD) i < (SWORD) lpCol->length - lstrlen(val); i++) {
  1151. *toPtr = ' ';
  1152. toPtr++;
  1153. }
  1154. fromPtr = val;
  1155. while (*fromPtr) {
  1156. *toPtr = *fromPtr;
  1157. toPtr++;
  1158. fromPtr++;
  1159. }
  1160. break;
  1161. }
  1162. // Find end of value
  1163. valEnd = fromPtr-1;
  1164. if (decimalLocation == valEnd) {
  1165. valEnd--;
  1166. decimalLocation = NULL;
  1167. }
  1168. // Truncate extra characters at end
  1169. if (decimalLocation != NULL) {
  1170. if (lpCol->scale == 0) {
  1171. valEnd = decimalLocation-1;
  1172. decimalLocation = NULL;
  1173. }
  1174. else {
  1175. if ((SWORD) lpCol->scale < (valEnd - decimalLocation)) {
  1176. valEnd = decimalLocation + lpCol->scale;
  1177. }
  1178. }
  1179. }
  1180. // Figure out how many extra zeros need to be added at end
  1181. if (lpCol->scale == 0)
  1182. extraZeros = 0;
  1183. else if (decimalLocation == NULL)
  1184. extraZeros = lpCol->scale + 1;
  1185. else
  1186. extraZeros = lpCol->scale - (valEnd - decimalLocation);
  1187. // Shave off extra characters in front
  1188. while ((SWORD) length < (valEnd - valStart) + 1 + extraZeros)
  1189. valStart++;
  1190. // Put in leading spaces
  1191. for (i=0;
  1192. (SWORD) i < (length - (valEnd - valStart + 1) - extraZeros);
  1193. i++) {
  1194. *toPtr = ' ';
  1195. toPtr++;
  1196. }
  1197. // Put in sign if needed
  1198. negNeeded = FALSE;
  1199. if (*val == '-') {
  1200. for (ptr = valStart; ptr <= valEnd; ptr++) {
  1201. if ((*ptr != '0') && (*ptr != '.')) {
  1202. negNeeded = TRUE;
  1203. break;
  1204. }
  1205. }
  1206. }
  1207. if (negNeeded)
  1208. *toPtr = '-';
  1209. else
  1210. *toPtr = ' ';
  1211. toPtr++;
  1212. // Put in value
  1213. while (valStart <= valEnd) {
  1214. *toPtr = *valStart;
  1215. toPtr++;
  1216. valStart++;
  1217. }
  1218. // Put in required trailing zeros
  1219. if (extraZeros == lpCol->scale + 1) {
  1220. *toPtr = '.';
  1221. toPtr++;
  1222. extraZeros--;
  1223. }
  1224. while (extraZeros > 0) {
  1225. *toPtr = '0';
  1226. toPtr++;
  1227. extraZeros--;
  1228. }
  1229. break;
  1230. case DBASE_DATE:
  1231. // Make sure value is legal
  1232. if (size != 10)
  1233. return DBASE_ERR_CONVERSIONERROR;
  1234. for (i=0; i < 10; i++) {
  1235. switch (i) {
  1236. case 0:
  1237. case 1:
  1238. case 2:
  1239. case 3:
  1240. case 6:
  1241. case 9:
  1242. if (!(IsCharAlphaNumeric(val[i])) || IsCharAlpha(val[i]))
  1243. return DBASE_ERR_CONVERSIONERROR;
  1244. break;
  1245. case 4:
  1246. case 7:
  1247. if (val[i] != '-')
  1248. return DBASE_ERR_CONVERSIONERROR;
  1249. break;
  1250. case 5:
  1251. if ((val[i] < '0') || (val[i] > '1'))
  1252. return DBASE_ERR_CONVERSIONERROR;
  1253. break;
  1254. case 8:
  1255. if ((val[i] < '0') && (val[i] > '3'))
  1256. return DBASE_ERR_CONVERSIONERROR;
  1257. if ((val[i] == '3') && (val[i+1] > '1'))
  1258. return DBASE_ERR_CONVERSIONERROR;
  1259. break;
  1260. }
  1261. }
  1262. // Copy the value
  1263. for (i=0; i < 4; i++) {
  1264. *toPtr = val[i];
  1265. toPtr++;
  1266. }
  1267. for (i=5; i < 7; i++) {
  1268. *toPtr = val[i];
  1269. toPtr++;
  1270. }
  1271. for (i=8; i < 10; i++) {
  1272. *toPtr = val[i];
  1273. toPtr++;
  1274. }
  1275. break;
  1276. case DBASE_LOGICAL:
  1277. if (size != 1)
  1278. return DBASE_ERR_CONVERSIONERROR;
  1279. switch (*val) {
  1280. case 'Y':
  1281. case 'y':
  1282. case 'T':
  1283. case 't':
  1284. case '1':
  1285. *toPtr = 'Y';
  1286. break;
  1287. case 'N':
  1288. case 'n':
  1289. case 'F':
  1290. case 'f':
  1291. case '0':
  1292. *toPtr = 'N';
  1293. break;
  1294. case '?':
  1295. case ' ':
  1296. *toPtr = '?';
  1297. break;
  1298. default:
  1299. return DBASE_ERR_CONVERSIONERROR;
  1300. }
  1301. break;
  1302. case DBASE_MEMO:
  1303. break;
  1304. }
  1305. f->recordDirty = TRUE;
  1306. */
  1307. return DBASE_ERR_SUCCESS;
  1308. }
  1309. /***************************************************************************/
  1310. SWORD FAR PASCAL dBaseSetColumnNull(LPDBASEFILE f, UWORD icol)
  1311. {
  1312. /*
  1313. UCHAR i;
  1314. LPDBASECOL lpCol;
  1315. // Make sure data is really there
  1316. if ((icol > f->columnCount) || (icol <= 0))
  1317. return DBASE_ERR_NOSUCHCOLUMN;
  1318. if (f->currentRecord == 0)
  1319. return DBASE_ERR_NODATAFOUND;
  1320. if (*(f->record) == DBASE_RECORD_DELETED)
  1321. return DBASE_ERR_NODATAFOUND;
  1322. // Set value
  1323. lpCol = &(f->column[icol-1]);
  1324. if (lpCol->type == DBASE_MEMO)
  1325. return DBASE_ERR_NOTSUPPORTED;
  1326. for (i=0; (i < f->column[icol-1].length); i++)
  1327. f->column[icol-1].value[i] = ' ';
  1328. f->recordDirty = TRUE;
  1329. */
  1330. return DBASE_ERR_SUCCESS;
  1331. }
  1332. /***************************************************************************/
  1333. SWORD FAR PASCAL dBaseDeleteRecord(LPDBASEFILE f)
  1334. {
  1335. /*
  1336. if (f->currentRecord == 0)
  1337. return DBASE_ERR_NODATAFOUND;
  1338. if (*(f->record) == DBASE_RECORD_DELETED)
  1339. return DBASE_ERR_NODATAFOUND;
  1340. if (f->newRecord) {
  1341. f->recordDirty = FALSE;
  1342. f->newRecord = FALSE;
  1343. f->recordCount--;
  1344. f->headerDirty = TRUE;
  1345. f->currentRecord = 0;
  1346. }
  1347. else {
  1348. *(f->record) = DBASE_RECORD_DELETED;
  1349. f->recordDirty = TRUE;
  1350. }
  1351. */
  1352. return DBASE_ERR_SUCCESS;
  1353. }
  1354. /***************************************************************************/
  1355. SWORD FAR PASCAL dBaseGetBookmark(LPDBASEFILE f, UDWORD far *b)
  1356. {
  1357. /*
  1358. // Make sure data is really there
  1359. if (f->currentRecord == 0)
  1360. return DBASE_ERR_NODATAFOUND;
  1361. if (*(f->record) == DBASE_RECORD_DELETED)
  1362. return DBASE_ERR_NODATAFOUND;
  1363. if (f->sortArray == NULL)
  1364. *b = f->currentRecord-1;
  1365. else
  1366. *b = f->sortArray[f->currentRecord-1];
  1367. */
  1368. return DBASE_ERR_SUCCESS;
  1369. }
  1370. /***************************************************************************/
  1371. SWORD FAR PASCAL dBasePosition(LPDBASEFILE f, UDWORD b)
  1372. {
  1373. /*
  1374. LONG offset;
  1375. SWORD err;
  1376. UWORD size;
  1377. // Write back any pending writes
  1378. err = dBaseFlushDirtyRecord(f);
  1379. if (err != DBASE_ERR_SUCCESS)
  1380. return err;
  1381. // Position to the specified record
  1382. offset = f->headerSize + (b * f->recordSize);
  1383. if (HFILE_ERROR == _llseek(f->hf, offset, 0))
  1384. return DBASE_ERR_CORRUPTFILE;
  1385. // Read the record
  1386. size = _lread(f->hf, f->record, f->recordSize);
  1387. if (size == 1) {
  1388. if (*(f->record) == DBASE_FILE_END)
  1389. return DBASE_ERR_NODATAFOUND;
  1390. else
  1391. return DBASE_ERR_CORRUPTFILE;
  1392. }
  1393. if (size != f->recordSize)
  1394. return DBASE_ERR_CORRUPTFILE;
  1395. f->currentRecord = b+1;
  1396. // If this record is deleted, return error
  1397. if (*(f->record) == DBASE_RECORD_DELETED)
  1398. return DBASE_ERR_NODATAFOUND;
  1399. // Return record
  1400. OemToAnsiBuff(f->record, f->record, f->recordSize);
  1401. */
  1402. return DBASE_ERR_SUCCESS;
  1403. }
  1404. /***************************************************************************/
  1405. SWORD FAR PASCAL dBaseClose(LPDBASEFILE f)
  1406. {
  1407. /*
  1408. SWORD err;
  1409. HANDLE ht;
  1410. time_t *t;
  1411. struct tm *ts;
  1412. if (f->headerDirty) {
  1413. ht = LocalAlloc(LMEM_MOVEABLE, sizeof(time_t));
  1414. t = (time_t NEAR *) LocalLock(ht);
  1415. time(t);
  1416. ts = localtime(t);
  1417. LocalUnlock(ht);
  1418. LocalFree(ht);
  1419. f->year = ts->tm_year;
  1420. f->month = ts->tm_mon + 1;
  1421. f->day = ts->tm_mday;
  1422. if (HFILE_ERROR == _llseek(f->hf, 0, 0))
  1423. return DBASE_ERR_CORRUPTFILE;
  1424. if (DBASE_HEADER_LENGTH != _lwrite(f->hf, (LPSTR) f, DBASE_HEADER_LENGTH))
  1425. return DBASE_ERR_WRITEERROR;
  1426. }
  1427. err = dBaseFlushDirtyRecord(f);
  1428. if (err != DBASE_ERR_SUCCESS)
  1429. return err;
  1430. if (HFILE_ERROR == _lclose(f->hf))
  1431. return DBASE_ERR_CLOSEERROR;
  1432. if (f->sortArray != NULL) {
  1433. GlobalUnlock(GlobalPtrHandle(f->sortArray));
  1434. GlobalFree(GlobalPtrHandle(f->sortArray));
  1435. }
  1436. GlobalUnlock(GlobalPtrHandle(f));
  1437. GlobalFree(GlobalPtrHandle(f));
  1438. */
  1439. return DBASE_ERR_SUCCESS;
  1440. }
  1441. /***************************************************************************/
  1442. SWORD FAR PASCAL dBaseDestroy(LPUSTR name)
  1443. {
  1444. /*
  1445. UCHAR FAR * ptr;
  1446. HANDLE h;
  1447. UCHAR NEAR *fullname;
  1448. // Get the filename
  1449. h = LocalAlloc(LMEM_MOVEABLE, DBASE_MAX_PATHNAME_SIZE+1);
  1450. fullname = (UCHAR NEAR *) LocalLock(h);
  1451. lstrcpy(fullname, name);
  1452. ptr = fullname + lstrlen(fullname);
  1453. while ((ptr != fullname) && (*ptr != '\\') && (*ptr != ':') &&
  1454. (*ptr != '.'))
  1455. ptr--;
  1456. if (*ptr != '.')
  1457. lstrcat(fullname, ".dbf");
  1458. AnsiToOem(fullname, fullname);
  1459. #ifdef WIN32
  1460. DeleteFile(fullname);
  1461. #else
  1462. remove(fullname);
  1463. #endif
  1464. LocalUnlock(h);
  1465. LocalFree(h);
  1466. */
  1467. return DBASE_ERR_SUCCESS;
  1468. }
  1469. /***************************************************************************/