// 2015/5/10 优化 public byte[] GetBytes() { MyByteList list = new MyByteList(24); list.AddRange(reclen); // 5 list.AddRange(status); // 1 list.AddRange(type); // 1 list.AddRange(level); // 1 list.AddRange(control); // 1 list.AddRange(reserve); // 1 list.AddRange(indicount); // 1 list.AddRange(subfldcodecount); // 1 list.AddRange(baseaddr); // 5 list.AddRange(res1); // 3 list.AddRange(lenoffld); // 1 list.AddRange(startposoffld); // 1 list.AddRange(impdef); // 1 list.AddRange(res2); // 1 Debug.Assert(list.Count == 24, "头标区内容必须为24字符"); if (list.Count != 24) { throw (new Exception("MarcHeader.GetBytes() error")); } // 2014/5/9 // 防范头标区出现 0 字符 for (int i = 0; i < list.Count; i++) { if (list[i] == 0) { list[i] = (byte)'*'; } } return(list.GetByteArray()); }
// 将ISO2709格式记录转换为字段数组 // aResult的每个元素为byte[]型,内容是一个字段。第一个元素是头标区,一定是24bytes // return: // -1 一般性错误 // -2 MARC格式错误 public static int Cvt2709ToFieldArray( Encoding encoding, // 2007/7/11 byte[] s, out List <byte[]> aResult, // out out string strErrorInfo) { strErrorInfo = ""; aResult = new List <byte[]>(); // const char *sopp; int maxbytes = 2000000; // 约2000K,防止攻击 // const byte RECEND = 29; // const byte FLDEND = 30; // const byte SUBFLD = 31; if (encoding.Equals(Encoding.Unicode) == true) { throw new Exception("UCS2编码方式应当使用 ForceCvt2709ToFieldArray(),而不是 Cvt2709ToFieldArray()"); } MarcHeaderStruct header = new MarcHeaderStruct(encoding, s); { // 输出头标区 byte[] tarray = null; tarray = new byte[24]; Array.Copy(s, 0, tarray, 0, 24); // 2014/5/9 // 防范头标区出现 0 字符 for (int j = 0; j < tarray.Length; j++) { if (tarray[j] == 0) { tarray[j] = (byte)'*'; } } aResult.Add(tarray); } int somaxlen; int reclen, baseaddr, lenoffld, startposoffld; int len, startpos; // char *dirp; int offs = 0; int t = 0; int i; // char temp[30]; somaxlen = s.Length; try { reclen = header.RecLength; } catch (FormatException ex) { strErrorInfo = "头标区开始5字符 '" + header.RecLengthString + "' 不是纯数字 :" + ex.Message; // throw(new MarcException(strErrorInfo)); goto ERROR2; } if (reclen > somaxlen) { strErrorInfo = "头标区头5字符表示的记录长度" + Convert.ToString(reclen) + "大于源缓冲区整个内容的长度" + Convert.ToString(somaxlen); goto ERROR2; } if (reclen < 24) { strErrorInfo = "头标区头5字符表示的记录长度" + Convert.ToString(reclen) + "小于24"; goto ERROR2; } if (s[reclen - 1] != RECEND) { strErrorInfo = "头标区声称的结束位置不是MARC记录结束符"; goto ERROR2; // 结束符不正确 } for (i = 0; i < reclen - 1; i++) { if (s[i] == RECEND) { strErrorInfo = "记录内容中不能有记录结束符"; goto ERROR2; } } try { baseaddr = header.BaseAddress; } catch (FormatException ex) { strErrorInfo = "头标区数据基地址5字符 '" + header.BaseAddressString + " '不是纯数字 :" + ex.Message; //throw(new MarcException(strErrorInfo)); goto ERROR2; } if (baseaddr > somaxlen) { strErrorInfo = "数据基地址值 " + Convert.ToString(baseaddr) + " 已经超出源缓冲区整个内容的长度 " + Convert.ToString(somaxlen); goto ERROR2; } if (baseaddr <= 24) { strErrorInfo = "数据基地址值 " + Convert.ToString(baseaddr) + " 小于24"; goto ERROR2; // 数据基地址太小 } if (s[baseaddr - 1] != FLDEND) { strErrorInfo = "没有在目次区尾部位置" + Convert.ToString(baseaddr) + "找到FLDEND符号"; goto ERROR2; // } try { lenoffld = header.WidthOfFieldLength; } catch (FormatException ex) { strErrorInfo = "头标区目次区字段长度1字符 '" + header.WidthOfFieldLengthString + " '不是纯数字 :" + ex.Message; //throw(new MarcException(strErrorInfo)); goto ERROR2; } try { startposoffld = header.WidthOfStartPositionOfField; } catch (FormatException ex) { strErrorInfo = "头标区目次区字段起始位置1字符 '" + header.WidthOfStartPositionOfFieldString + " '不是纯数字 :" + ex.Message; // throw(new MarcException(strErrorInfo)); goto ERROR2; } if (lenoffld <= 0 || lenoffld > 30) { strErrorInfo = "目次区中字段长度值占用字符数 " + Convert.ToString(lenoffld) + " 不正确,应在1和29之间..."; goto ERROR2; } if (lenoffld != 4) { // 2001/5/15 strErrorInfo = "目次区中字段长度值占用字符数 " + Convert.ToString(lenoffld) + " 不正确,应为4..."; goto ERROR2; } lenoffld = 4; if (startposoffld <= 0 || startposoffld > 30) { strErrorInfo = "目次区中字段起始位置值占用字符数 " + Convert.ToString(startposoffld) + " 不正确,应在1到29之间..."; goto ERROR2; } startposoffld = 5; // 开始处理目次区 // dirp = (char *)sopp; t = 24; offs = 24; MyByteList baField = null; for (i = 0; ; i++) { if (s[offs] == FLDEND) { break; // 目次区结束 } // 将字段名装入目标 if (offs + 3 >= baseaddr) { break; } if (t + 3 >= maxbytes) { break; } /* * baTarget.SetSize(t+3, CHUNK_SIZE); * memcpy((char *)baTarget.GetData()+t, * dirp+offs, * 3); * t+=3; */ baField = new MyByteList(); baField.AddRange(s, offs, 3); t += 3; // 得到字段长度 offs += 3; if (offs + lenoffld >= baseaddr) { break; } len = MarcHeaderStruct.IntValue(s, offs, lenoffld); // 得到字段内容开始地址 offs += lenoffld; if (offs + startposoffld >= baseaddr) { break; } startpos = MarcHeaderStruct.IntValue(s, offs, startposoffld); offs += startposoffld; if (offs >= baseaddr) { break; } // 将字段内容装入目标 if (t + len >= maxbytes) { break; } if (s[baseaddr + startpos - 1] != FLDEND) { // errnoiso2709 = ERROR_BADFLDCONTENT; strErrorInfo = "缺乏字段结束符"; goto ERROR2; } if (s[baseaddr + startpos + len - 1] != FLDEND) { //errnoiso2709 = ERROR_BADFLDCONTENT; strErrorInfo = "缺乏字段结束符"; goto ERROR2; } /* * baTarget.SetSize(t+len, CHUNK_SIZE); * memcpy((char *)baTarget.GetData()+t, * sopp+baseaddr+startpos, * len); * t += len; */ baField.AddRange(s, baseaddr + startpos, len == 0 ? len : len - 1); t += len; aResult.Add(baField.GetByteArray()); baField = null; } if (t + 1 >= maxbytes) { // errnoiso2709 = ERROR_TARGETBUFFEROVERFLOW; strErrorInfo = "记录太大"; goto ERROR2; // 目标空间不够 } /* * baField.Add((char)RECEND); * t ++; */ /* * baTarget.SetSize(t+1, CHUNK_SIZE); *((char *)baTarget.GetData() + t++) = RECEND; * if (t+1>=maxbytes) * { * errnoiso2709 = ERROR_TARGETBUFFEROVERFLOW; * goto ERROR1; // 目标空间不够 * } */ Debug.Assert(t != -2, ""); return(t); //ERROR1: // return -1; // 一般性错误 ERROR2: // 调试用 Debug.Assert(false, ""); return(-2); // MARC格式错误 }