// 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());
        }
Exemple #2
0
        // 将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格式错误
        }