/* ======================================= 文本模式去除多余换行符 ======================================= */ CR_API uint_t qst_txt_mode ( __CR_IO__ ansi_t* text, __CR_IN__ uint_t size ) { ansi_t *ptr; uint_t ii, jj; if (size < 2) return (size); size -= 1; ptr = text; for (jj = ii = 0; ii < size; ii++) { ptr[jj++] = text[ii]; if (text[ii] == CR_AC('\r') && text[ii + 1] == CR_AC('\n')) ii++; } if (ii == size) ptr[jj++] = text[ii]; return (jj); }
/* ======================================= TGL IPAC 文件读取 ======================================= */ CR_API sFMT_PRT* load_tgl_ipac ( __CR_IO__ iDATIN* datin, __CR_IN__ const sLOADER* param ) { int16u idx; int16u cnt; int32u offs; int32u size; sFMT_PRT* rett; sIPAC_HDR head; iPAK_IPAC* port; sPAK_FILE* list; ansi_t str[17]; /* 必须使用自己私有的读取接口 */ datin = create_file_inX(param); if (datin == NULL) return (NULL); /* 读取 & 检查头部 */ if (!(CR_VCALL(datin)->geType(datin, &head, sIPAC_HDR))) goto _failure1; if (head.magic != mk_tag4("IPAC")) goto _failure1; /* 分配子文件属性表 */ cnt = WORD_LE(head.count); if (cnt != 0) { list = mem_talloc(cnt, sPAK_FILE); if (list == NULL) goto _failure1; str[16] = CR_AC(NIL); mem_tzero(list, cnt, sPAK_FILE); } else { list = NULL; /* 支持空的包文件 */ } /* 加载文件信息表 */ for (idx = 0; idx < cnt; idx++) { /* 读取文件名不保证\0结尾 */ if (CR_VCALL(datin)->read(datin, str, 16) != 16) goto _failure2; /* 文件的包内偏移和大小 */ if (!CR_VCALL(datin)->getd_le(datin, &offs)) goto _failure2; if (!CR_VCALL(datin)->getd_le(datin, &size)) goto _failure2; /* 文件名统一使用 UTF-8 编码 */ list[idx].name = local_to_utf8(param->page, str); if (list[idx].name == NULL) goto _failure2; /* 设置公用文件属性 */ list[idx].skip = sizeof(sPAK_FILE); list[idx].attr = 0; list[idx].offs = offs; list[idx].pack = size; list[idx].size = size; list[idx].memo = "Store"; } /* 生成读包接口对象 */ port = struct_new(iPAK_IPAC); if (port == NULL) goto _failure2; port->m_cnt = cnt; port->m_file = datin; port->pack.__filelst__ = list; port->pack.__vptr__ = &s_pack_vtbl; if (!pack_init_list((iPACKAGE*)port, TRUE)) { mem_free(port); goto _failure2; } /* 返回读取的文件数据 */ rett = struct_new(sFMT_PRT); if (rett == NULL) { iPAK_IPAC_release((iPACKAGE*)port); return (NULL); } rett->type = CR_FMTZ_PRT; rett->port = (iPORT*)port; rett->more = "iPACKAGE"; rett->infor = "TGL IPAC Archive (IPAC)"; return (rett); _failure2: if (list != NULL) { for (cnt = 0; cnt < idx; cnt++) { TRY_FREE(list[cnt].find); mem_free(list[cnt].name); } mem_free(list); } _failure1: CR_VCALL(datin)->release(datin); return (NULL); }