// File: /workspace/github_c_makefile_star2_O3/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 %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x27bf0d
movq %rsi, %rax
movq %rdi, %r15
movq 0x20(%rdi), %r14
movl $0x1, %ebx
movl %ecx, %esi
orl %edx, %esi
js 0x27beea
movl %ecx, %esi
movl %edx, %edi
addq %rsi, %rdi
movslq (%r15), %rsi
cmpq %rsi, %rdi
jg 0x27beea
movq 0x18(%r15), %r12
movl $0x4, %ebx
testq %r12, %r12
je 0x27beea
movq 0x10(%r15), %rdi
movq 0x8(%rdi), %rsi
movq (%rsi), %r9
movq 0x8(%rsi), %rsi
movq %r9, 0x8(%rsi)
addl 0x4(%r15), %ecx
movl %ecx, %esi
movq %rax, %rcx
callq *%r8
cmpl $0x4, %eax
jne 0x27bf55
movq %r12, %rdi
callq 0x277f75
movq $0x0, 0x18(%r15)
movl %ebx, 0x50(%r14)
movq %r14, %rdi
movl %ebx, %esi
callq 0x284b1f
cmpl $0xc0a, %ebx            # imm = 0xC0A
je 0x27bf3a
cmpb $0x0, 0x61(%r14)
jne 0x27bf3a
andl 0x54(%r14), %ebx
jmp 0x27bf47
leaq 0x159cb7(%rip), %rsi    # 0x3d5bcb
leaq 0x15e52c(%rip), %rdx    # 0x3da447
leaq 0x159b0f(%rip), %r8     # 0x3d5a31
movl $0x15, %ebx
movl $0x15, %edi
movl $0x16e3e, %ecx          # imm = 0x16E3E
xorl %eax, %eax
callq 0x274d08
jmp 0x27bf47
movq %r14, %rdi
callq 0x28fd56
movl $0x7, %ebx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movl %eax, 0x38(%r12)
movl %eax, 0x50(%r14)
movl %eax, %ebx
testl %eax, %eax
jne 0x27beee
xorl %ebx, %ebx
cmpq $0x0, 0x160(%r14)
jne 0x27beee
jmp 0x27bef8