Exemplo n.º 1
0
// internalRead returns the size of the LOB variable for internal comsumption.
func (lv *ExternalLobVar) internalRead(p []byte, off int64) (length int64, err error) {
	var charsetID C.ub2
	j := lv.pos * lv.lobVar.typ.size

	if lv.isFile {
		// Py_BEGIN_ALLOW_THREADS
		if err = lv.lobVar.environment.CheckStatus(
			C.OCILobFileOpen(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				(*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j])),
				C.OCI_FILE_READONLY),
			"LobFileOpen"); err != nil {
			return
		}
	}
	// Py_END_ALLOW_THREADS

	// Py_BEGIN_ALLOW_THREADS
	if lv.lobVar.typ == NClobVarType {
		// charsetID = C.OCI_UTF16ID
		charsetID = CsIDAl32UTF8
	} else {
		charsetID = 0
	}
	length = int64(len(p))
	olength := C.ub4(length + 1)
	if err = lv.lobVar.environment.CheckStatus(
		C.OCILobRead(lv.lobVar.connection.handle,
			lv.lobVar.environment.errorHandle,
			(*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j])),
			&olength, C.ub4(off+1), unsafe.Pointer(&p[0]),
			C.ub4(len(p)), nil, nil, charsetID, lv.lobVar.typ.charsetForm),
		"LobRead"); err != nil {
		// Py_END_ALLOW_THREADS
		C.OCILobFileClose(lv.lobVar.connection.handle,
			lv.lobVar.environment.errorHandle,
			(*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j])))
		return
	}

	if lv.isFile {
		// Py_BEGIN_ALLOW_THREADS
		if err = lv.lobVar.environment.CheckStatus(
			C.OCILobFileClose(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				(*C.OCILobLocator)(unsafe.Pointer(&lv.lobVar.dataBytes[j]))),
			"LobFileClose"); err != nil {
			return
		}
	}

	return
}
Exemplo n.º 2
0
// internalRead returns the size of the LOB variable for internal comsumption.
func (lv *ExternalLobVar) internalRead(p []byte, off int64) (length int64, err error) {
	var charsetID C.ub2

	if lv.isFile {
		// Py_BEGIN_ALLOW_THREADS
		if CTrace {
			ctrace("OCILobFileOpen(conn=%p, lob=%x, OCI_FILE_READONLY)",
				lv.lobVar.connection.handle, lv.getHandleBytes())
		}
		if err = lv.lobVar.environment.CheckStatus(
			C.OCILobFileOpen(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				lv.getHandle(), C.OCI_FILE_READONLY),
			"LobFileOpen"); err != nil {
			return
		}
	}
	// Py_END_ALLOW_THREADS

	// Py_BEGIN_ALLOW_THREADS
	if lv.lobVar.typ == NClobVarType {
		// charsetID = C.OCI_UTF16ID
		charsetID = CsIDAl32UTF8
	} else {
		charsetID = 0
	}
	var (
		byteLen2 = C.oraub8(len(p))
		charLen2 = C.oraub8(0)
		byteLen  = C.ub4(len(p))
		status   C.sword
		pos      = int(0)
	)
	for {
		if useLobRead2 {
			if CTrace {
				ctrace("OCILobRead2(conn=%p, lob=%x, byteLen=%d, charLen=%d, off=%d, &p=%p "+
					"len(p)=%d, piece=%d, csID=%d, csF=%d",
					lv.lobVar.connection.handle,
					lv.getHandleBytes(), byteLen2, charLen2, off+1,
					&p[pos], len(p)-pos, C.OCI_ONE_PIECE,
					charsetID, lv.lobVar.typ.charsetForm)
			}
			status = C.OCILobRead2(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				lv.getHandle(), &byteLen2, &charLen2, C.oraub8(off+1),
				unsafe.Pointer(&p[pos]), C.oraub8(len(p)-pos), C.OCI_ONE_PIECE,
				nil, nil, charsetID, lv.lobVar.typ.charsetForm)
		} else {
			if CTrace {
				//log.Printf("p=%q len(p)=%d pos=%d byteLen=%d", p, len(p), pos, byteLen)
				ctrace("OCILobRead(conn=%p, lob=%x, byteLen=%d, off=%d, &p=%p "+
					"len(p)=%d, csID=%d, csF=%d",
					lv.lobVar.connection.handle,
					lv.getHandleBytes(), byteLen, off+1,
					&p[pos], len(p)-pos,
					charsetID, lv.lobVar.typ.charsetForm)
			}
			status = C.OCILobRead(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				lv.getHandle(), &byteLen, C.ub4(off+1),
				unsafe.Pointer(&p[pos]), C.ub4(len(p)-pos),
				nil, nil,
				charsetID, lv.lobVar.typ.charsetForm)
		}
		if !(status == C.OCI_SUCCESS || status == C.OCI_NEED_DATA) {
			err = lv.lobVar.environment.CheckStatus(status, "LobRead")
			if CTrace {
				ctrace("OCILobFileClose(conn=%p, lob=%p)",
					lv.lobVar.connection.handle, lv.getHandleBytes())
			}
			C.OCILobFileClose(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				lv.getHandle())
			return
		}

		if useLobRead2 {
			byteLen = C.ub4(byteLen2)
		}
		off += int64(byteLen)
		length += int64(byteLen)
		if CTrace {
			if useLobRead2 {
				ctrace("(byteLen2=%d charLen2=%d) => length=%d off=%d",
					byteLen2, charLen2, length, off)
			} else {
				ctrace("byteLen=%d => length=%d off=%d", byteLen, length, off)
			}
		}
		if status == C.OCI_SUCCESS {
			break
		}
		pos += int(byteLen)
		if useLobRead2 {
			byteLen2 = C.oraub8(len(p) - pos)
		} else {
			byteLen = C.ub4(len(p) - pos)
		}
	}

	if lv.isFile {
		// Py_BEGIN_ALLOW_THREADS
		if CTrace {
			ctrace("OCILobFileClose(conn=%p, lob=%x)",
				lv.lobVar.connection.handle, lv.getHandleBytes())
		}
		if err = lv.lobVar.environment.CheckStatus(
			C.OCILobFileClose(lv.lobVar.connection.handle,
				lv.lobVar.environment.errorHandle,
				lv.getHandle()),
			"LobFileClose"); err != nil {
			return
		}
	}

	if 0 == length && err == nil {
		err = io.EOF
	}
	if CTrace {
		ctrace("internalRead returns %d, %s", length, err)
	}
	return
}