package xugu import "errors" // LobDataItem 结构体定义 type LobDataItem struct { ChunkNo int ItemData []byte // 使用 interface{} 表示任意类型的数据 Next *LobDataItem } // LOB_PICE 常量定义 const LOB_PICE = 1024 * 1024 // 1 MB // XuguLob 结构体定义 type XuguLob struct { Type HANDLE_TYPE ChunkNum int State int // 0 inited 1 inputing 2 inputed ok DataOff int64 RPos int64 // 增加于 2017-09-08 CurItem *LobDataItem HeadItem *LobDataItem RdIfValue interface{} Desc string // 增加于 2017-09-12 ErrStr string } func CreateLob() XuguLob { return XuguLob{ Type: HT_LOB, ChunkNum: 0, State: 0, DataOff: 0, RPos: 0, CurItem: nil, HeadItem: nil, RdIfValue: nil, Desc: "", ErrStr: "", } } /* 大对象 数据填入 * Lob_ptr 大对象指针 由XGC_Create_Lob生成, * data 数据缓冲区,其内容长度 由 len决定 * len 数据缓冲区填入数据的长度, 数据存放入大对象 内部是分片存放的,非一块整的大对象,因此较为灵活 * 注意 当 len 填入长度是 -1 表示整个大对象写入最终完成,此时data区域不起作用,仅标识大对象录入最终完成。 * 如果最终没有 len 填入长度是 -1 那么无法标识 大对象的录入已经完成,数据录入会失败 * 返回值 0 */ func (pLob *XuguLob) putLobData(data []byte, len int) (int, error) { if len == -1 { pLob.State = 2 return 0, errors.New("LOB data input len == -1") } if len == 0 || data == nil { return 0, errors.New("LOB data input len == 0 or data == nil") } reLen := len sDataOff := 0 if pLob.ChunkNum == 0 { pLob.HeadItem = new(LobDataItem) pLob.CurItem = pLob.HeadItem pLob.CurItem.ItemData = make([]byte, LOB_PICE) pLob.CurItem.ChunkNo = 0 // begin from 0 pLob.ChunkNum = 1 cpLen := minInt(reLen, LOB_PICE) //memcpy(pLob->p_cur_item->p_item_data, data, cp_len); copy(pLob.CurItem.ItemData, data) sDataOff += cpLen pLob.DataOff = int64(cpLen) reLen -= cpLen } for reLen != 0 { //=================满了 填入前半段//// itemOff := pLob.DataOff % LOB_PICE if itemOff == 0 { pLob.CurItem.Next = new(LobDataItem) pLob.CurItem.Next.ChunkNo = pLob.ChunkNum pLob.ChunkNum++ pLob.CurItem = pLob.CurItem.Next //copy data cpLen := minInt(reLen, LOB_PICE) //memcpy(pLob->p_cur_item->p_item_data, data, cp_len); copy(pLob.CurItem.ItemData, data[sDataOff:]) sDataOff += cpLen pLob.DataOff += int64(cpLen) reLen -= cpLen } else { cpLen := minInt(reLen, int(LOB_PICE-itemOff)) //memcpy(pLob->p_cur_item->p_item_data, data, cp_len); copy(pLob.CurItem.ItemData[cpLen:], data[sDataOff:]) sDataOff += cpLen pLob.DataOff += int64(cpLen) reLen -= cpLen } } pLob.State = 1 return 0, nil } func minInt(a, b int) int { if a < b { return a } return b }