sdk/Transform/SelectObjectMetaRequestDeserializer.cs (132 lines of code) (raw):

/* * Copyright (C) Alibaba Cloud Computing * All rights reserved. * */ using System; using Aliyun.OSS.Common; using Aliyun.OSS.Common.Communication; using Aliyun.OSS.Util; namespace Aliyun.OSS.Transform { internal class SelectObjectMetaRequestDeserializer : ResponseDeserializer<CreateSelectObjectMetaResult, CreateSelectObjectMetaResult> { private bool _gotEndofStream; public SelectObjectMetaRequestDeserializer() : base(null) { } public override CreateSelectObjectMetaResult Deserialize(ServiceResponse xmlStream) { var result = new CreateSelectObjectMetaResult(); var buff = new byte[128]; uint payloadCrc32 = 0; int readCnt = 0; bool gotEndFrame = false; _gotEndofStream = false; CRC32.Init(); while (!gotEndFrame) { //Version | Frame - Type | Payload Length | Header Checksum | Payload | Payload Checksum //<1 bytes> <--3 bytes--> <-- 4 bytes --> <------4 bytes--> <variable><----4bytes------> //Payload //<offset | data> //<8 bytes><variable> //read Header 12 bytes readCnt = TryRead(xmlStream.Content, buff, 0, 12); if (_gotEndofStream) break; ensureReadSize(12, readCnt); //version //Frame - Type int frameType = OssUtils.ConvertBytesToInt(buff, 1, 3); //Payload Length int payloadLength = OssUtils.ConvertBytesToInt(buff, 4, 4); //Header Checksum int headerCheckSum = OssUtils.ConvertBytesToInt(buff, 8, 4); //read Playload switch (frameType) { case 0x800006: //Meta End Frame(Csv) case 0x800007: //Meta End Frame(Json) payloadLength -= 32; // 32 bytes readCnt = TryRead(xmlStream.Content, buff, 0, 32); ensureReadSize(32, readCnt); payloadCrc32 = CRC32.GetCRC32Byte(buff, 32, payloadCrc32); // offset 8 bytes result.Offset = OssUtils.ConvertBytesToLong(buff, 0, 8); // total scaned 8bytes result.TotalScannedBytes = OssUtils.ConvertBytesToLong(buff, 8, 8); // status 4 bytes result.Status = OssUtils.ConvertBytesToInt(buff, 16, 4); // splitsCount 4 bytes result.SplitsCount = OssUtils.ConvertBytesToLong(buff, 20, 4); // rowsCount 8 bytes result.RowsCount = OssUtils.ConvertBytesToLong(buff, 24, 8); // 32 bytes if (frameType == 0x800006) { payloadLength -= 4; // colsCount 4 bytes readCnt = TryRead(xmlStream.Content, buff, 0, 4); ensureReadSize(4, readCnt); result.ColumnsCount = OssUtils.ConvertBytesToLong(buff, 0, 4); payloadCrc32 = CRC32.GetCRC32Byte(buff, 4, payloadCrc32); } while (payloadLength > 0) { int len = Math.Min(buff.Length, payloadLength); readCnt = TryRead(xmlStream.Content, buff, 0, len); ensureReadSize(len, readCnt); if (string.IsNullOrEmpty(result.ErrorMessage)) { result.ErrorMessage = System.Text.Encoding.Default.GetString(buff, 0, readCnt); } payloadCrc32 = CRC32.GetCRC32Byte(buff, readCnt, payloadCrc32); payloadLength -= readCnt; } //Payload Checksum readCnt = TryRead(xmlStream.Content, buff, 0, 4); ensureReadSize(4, readCnt); uint serverCrc32 = OssUtils.ConvertBytesToUint(buff, 0, 4); //Payload Crc32 check if (serverCrc32 != 0 && serverCrc32 != payloadCrc32) { throw new ClientException(string.Format("Payload checksum check fail server CRC {0}, client CRC {1}", serverCrc32, payloadCrc32)); } gotEndFrame = true; break; default: //skip playload readCnt = TrySkip(xmlStream.Content, payloadLength); ensureReadSize(payloadLength, readCnt); //skip payload Checksum readCnt = TryRead(xmlStream.Content, buff, 0, 4); ensureReadSize(4, readCnt); break; } } if (!gotEndFrame) { throw new ClientException("No end frame exists."); } DeserializeGeneric(xmlStream, result); return result; } private int TryRead(System.IO.Stream stream, byte[] buffer, int offset, int count) { int remain = count; while (remain > 0 && stream.CanRead) { int read = stream.Read(buffer, offset, remain); remain -= read; offset += read; if (read == 0) { _gotEndofStream = true; break; } } return count - remain; } private int TrySkip(System.IO.Stream stream, int count) { byte[] buffer = new byte[256]; int remain = count; while (remain > 0) { int len = Math.Min(buffer.Length, remain); int read = stream.Read(buffer, 0, len); remain -= read; if (read == 0) { _gotEndofStream = true; break; } } return count - remain; } private void ensureReadSize(int expect, int got) { if (expect != got) { throw new ClientException(string.Format("Extract frame fail. expect {0}, but got {1}", expect, got)); } } } }