db_ret.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*-
  2.  * See the file LICENSE for redistribution information.
  3.  *
  4.  * Copyright (c) 1996, 1997, 1998, 1999, 2000
  5.  * Sleepycat Software.  All rights reserved.
  6.  */
  7. #include "db_config.h"
  8. #ifndef lint
  9. static const char revid[] = "$Id: db_ret.c,v 11.12 2000/11/30 00:58:33 ubell Exp $";
  10. #endif /* not lint */
  11. #ifndef NO_SYSTEM_INCLUDES
  12. #include <sys/types.h>
  13. #include <string.h>
  14. #endif
  15. #include "db_int.h"
  16. #include "db_page.h"
  17. #include "btree.h"
  18. #include "db_am.h"
  19. /*
  20.  * __db_ret --
  21.  * Build return DBT.
  22.  *
  23.  * PUBLIC: int __db_ret __P((DB *,
  24.  * PUBLIC:    PAGE *, u_int32_t, DBT *, void **, u_int32_t *));
  25.  */
  26. int
  27. __db_ret(dbp, h, indx, dbt, memp, memsize)
  28. DB *dbp;
  29. PAGE *h;
  30. u_int32_t indx;
  31. DBT *dbt;
  32. void **memp;
  33. u_int32_t *memsize;
  34. {
  35. BKEYDATA *bk;
  36. HOFFPAGE ho;
  37. BOVERFLOW *bo;
  38. u_int32_t len;
  39. u_int8_t *hk;
  40. void *data;
  41. switch (TYPE(h)) {
  42. case P_HASH:
  43. hk = P_ENTRY(h, indx);
  44. if (HPAGE_PTYPE(hk) == H_OFFPAGE) {
  45. memcpy(&ho, hk, sizeof(HOFFPAGE));
  46. return (__db_goff(dbp, dbt,
  47.     ho.tlen, ho.pgno, memp, memsize));
  48. }
  49. len = LEN_HKEYDATA(h, dbp->pgsize, indx);
  50. data = HKEYDATA_DATA(hk);
  51. break;
  52. case P_LBTREE:
  53. case P_LDUP:
  54. case P_LRECNO:
  55. bk = GET_BKEYDATA(h, indx);
  56. if (B_TYPE(bk->type) == B_OVERFLOW) {
  57. bo = (BOVERFLOW *)bk;
  58. return (__db_goff(dbp, dbt,
  59.     bo->tlen, bo->pgno, memp, memsize));
  60. }
  61. len = bk->len;
  62. data = bk->data;
  63. break;
  64. default:
  65. return (__db_pgfmt(dbp, h->pgno));
  66. }
  67. return (__db_retcopy(dbp, dbt, data, len, memp, memsize));
  68. }
  69. /*
  70.  * __db_retcopy --
  71.  * Copy the returned data into the user's DBT, handling special flags.
  72.  *
  73.  * PUBLIC: int __db_retcopy __P((DB *, DBT *,
  74.  * PUBLIC:    void *, u_int32_t, void **, u_int32_t *));
  75.  */
  76. int
  77. __db_retcopy(dbp, dbt, data, len, memp, memsize)
  78. DB *dbp;
  79. DBT *dbt;
  80. void *data;
  81. u_int32_t len;
  82. void **memp;
  83. u_int32_t *memsize;
  84. {
  85. DB_ENV *dbenv;
  86. int ret;
  87. dbenv = dbp == NULL ? NULL : dbp->dbenv;
  88. /* If returning a partial record, reset the length. */
  89. if (F_ISSET(dbt, DB_DBT_PARTIAL)) {
  90. data = (u_int8_t *)data + dbt->doff;
  91. if (len > dbt->doff) {
  92. len -= dbt->doff;
  93. if (len > dbt->dlen)
  94. len = dbt->dlen;
  95. } else
  96. len = 0;
  97. }
  98. /*
  99.  * Return the length of the returned record in the DBT size field.
  100.  * This satisfies the requirement that if we're using user memory
  101.  * and insufficient memory was provided, return the amount necessary
  102.  * in the size field.
  103.  */
  104. dbt->size = len;
  105. /*
  106.  * Allocate memory to be owned by the application: DB_DBT_MALLOC,
  107.  * DB_DBT_REALLOC.
  108.  *
  109.  * !!!
  110.  * We always allocate memory, even if we're copying out 0 bytes. This
  111.  * guarantees consistency, i.e., the application can always free memory
  112.  * without concern as to how many bytes of the record were requested.
  113.  *
  114.  * Use the memory specified by the application: DB_DBT_USERMEM.
  115.  *
  116.  * !!!
  117.  * If the length we're going to copy is 0, the application-supplied
  118.  * memory pointer is allowed to be NULL.
  119.  */
  120. if (F_ISSET(dbt, DB_DBT_MALLOC)) {
  121. if ((ret = __os_malloc(dbenv, len,
  122.     dbp == NULL ? NULL : dbp->db_malloc, &dbt->data)) != 0)
  123. return (ret);
  124. } else if (F_ISSET(dbt, DB_DBT_REALLOC)) {
  125. if ((ret = __os_realloc(dbenv, len,
  126.     dbp == NULL ? NULL : dbp->db_realloc, &dbt->data)) != 0)
  127. return (ret);
  128. } else if (F_ISSET(dbt, DB_DBT_USERMEM)) {
  129. if (len != 0 && (dbt->data == NULL || dbt->ulen < len))
  130. return (ENOMEM);
  131. } else if (memp == NULL || memsize == NULL) {
  132. return (EINVAL);
  133. } else {
  134. if (len != 0 && (*memsize == 0 || *memsize < len)) {
  135. if ((ret = __os_realloc(dbenv, len, NULL, memp)) != 0) {
  136. *memsize = 0;
  137. return (ret);
  138. }
  139. *memsize = len;
  140. }
  141. dbt->data = *memp;
  142. }
  143. if (len != 0)
  144. memcpy(dbt->data, data, len);
  145. return (0);
  146. }