// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: blobReadWrite
static int blobReadWrite(
  sqlite3_blob *pBlob,
  void *z,
  int n,
  int iOffset,
  int (*xCall)(BtCursor*, u32, u32, void*)
){
  int rc;
  Incrblob *p = (Incrblob *)pBlob;
  Vdbe *v;
  sqlite3 *db;

  if( p==0 ) return SQLITE_MISUSE_BKPT;
  db = p->db;
  sqlite3_mutex_enter(db->mutex);
  v = (Vdbe*)p->pStmt;

  if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
    /* Request is out of range. Return a transient error. */
    rc = SQLITE_ERROR;
  }else if( v==0 ){
    /* If there is no statement handle, then the blob-handle has
    ** already been invalidated. Return SQLITE_ABORT in this case.
    */
    rc = SQLITE_ABORT;
  }else{
    /* Call either BtreeData() or BtreePutData(). If SQLITE_ABORT is
    ** returned, clean-up the statement handle.
    */
    assert( db == v->db );
    sqlite3BtreeEnterCursor(p->pCsr);

#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
    if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){
      /* If a pre-update hook is registered and this is a write cursor,
      ** invoke it here.
      **
      ** TODO: The preupdate-hook is passed SQLITE_DELETE, even though this
      ** operation should really be an SQLITE_UPDATE. This is probably
      ** incorrect, but is convenient because at this point the new.* values
      ** are not easily obtainable. And for the sessions module, an
      ** SQLITE_UPDATE where the PK columns do not change is handled in the
      ** same way as an SQLITE_DELETE (the SQLITE_DELETE code is actually
      ** slightly more efficient). Since you cannot write to a PK column
      ** using the incremental-blob API, this works. For the sessions module
      ** anyhow.
      */
      sqlite3_int64 iKey;
      iKey = sqlite3BtreeIntegerKey(p->pCsr);
      sqlite3VdbePreUpdateHook(
          v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1
      );
    }
#endif

    rc = xCall(p->pCsr, iOffset+p->iOffset, n, z);
    sqlite3BtreeLeaveCursor(p->pCsr);
    if( rc==SQLITE_ABORT ){
      sqlite3VdbeFinalize(v);
      p->pStmt = 0;
    }else{
      v->rc = rc;
    }
  }
  sqlite3Error(db, rc);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x3cc56b
movl $0x16e3e, %edi          # imm = 0x16E3E
callq 0x3bf6a0
movl %eax, -0x4(%rbp)
jmp 0x3cc63a
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x1c(%rbp)
jl 0x3cc5a6
cmpl $0x0, -0x20(%rbp)
jl 0x3cc5a6
movslq -0x20(%rbp), %rax
movslq -0x1c(%rbp), %rcx
addq %rcx, %rax
movq -0x38(%rbp), %rcx
movslq (%rcx), %rcx
cmpq %rcx, %rax
jle 0x3cc5af
movl $0x1, -0x2c(%rbp)
jmp 0x3cc619
cmpq $0x0, -0x40(%rbp)
jne 0x3cc5bf
movl $0x4, -0x2c(%rbp)
jmp 0x3cc617
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x410920
movq -0x28(%rbp), %rax
movq -0x38(%rbp), %rcx
movq 0x10(%rcx), %rdi
movl -0x20(%rbp), %esi
movq -0x38(%rbp), %rcx
addl 0x4(%rcx), %esi
movl -0x1c(%rbp), %edx
movq -0x18(%rbp), %rcx
callq *%rax
movl %eax, -0x2c(%rbp)
cmpl $0x4, -0x2c(%rbp)
jne 0x3cc60b
movq -0x40(%rbp), %rdi
callq 0x3c7330
movq -0x38(%rbp), %rax
movq $0x0, 0x18(%rax)
jmp 0x3cc615
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rax
movl %ecx, 0x38(%rax)
jmp 0x3cc617
jmp 0x3cc619
movq -0x48(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x3c5210
movq -0x48(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0x3c7380
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)