private void ParseBody(int penMaxForce) { mDots.Clear(); long penDownTime = 0, penUpTime = 0, prevTimestamp = 0; int dotTotalCount = 0, dotCount = 0; byte lineCheckSum = 0; int dotStartIndex = 0, dotSize = 0; byte[] lineColorBytes = new byte[4]; int lineColor = 0x000000; // 현재 라인의 도트 offlineDots = new List <Dot>(); int i = 0; while (i < mBody.Length && mBody.Length > 0) { if (ByteConverter.SingleByteToInt(mBody[i]) == LINE_MARK_1 && ByteConverter.SingleByteToInt(mBody[i + 1]) == LINE_MARK_2) { offlineDots = new List <Dot>(); penDownTime = ByteConverter.ByteToLong(CopyOfRange(mBody, i + 2, 8)); penUpTime = ByteConverter.ByteToLong(CopyOfRange(mBody, i + 10, 8)); dotTotalCount = ByteConverter.ByteToInt(CopyOfRange(mBody, i + 18, 4)); lineColorBytes = CopyOfRange(mBody, i + 23, 4); lineColor = ByteConverter.ByteToInt(new byte[] { lineColorBytes[2], lineColorBytes[1], lineColorBytes[0], (byte)0 }); //System.Console.WriteLine( "[OfflineDataParser] penDownTime : {0}, penUpTime : {1}, dotTotalCount : {2}, lineColor : {3}", penDownTime, penUpTime, dotTotalCount, lineColor ); lineCheckSum = mBody[i + 27]; i += BYTE_LINE_SIZE; dotStartIndex = i; dotSize = 0; dotCount = 0; } else { dotCount++; // 스트로크 헤더에 정의된 도트갯수보다 넘어가면 LN이 나올때까지 한바이트씩 포인터를 이동한다. if (dotCount > dotTotalCount) { i++; continue; } long timeGap = ByteConverter.SingleByteToInt(mBody[i]); short x = ByteConverter.ByteToShort(CopyOfRange(mBody, i + 1, 2)); short y = ByteConverter.ByteToShort(CopyOfRange(mBody, i + 3, 2)); int fx = ByteConverter.SingleByteToInt(mBody[i + 5]); int fy = ByteConverter.SingleByteToInt(mBody[i + 6]); int force = ByteConverter.SingleByteToInt(mBody[i + 7]); int color = lineColor; bool isPenUp = false; long timestamp = -1L; DotTypes dotType; if (dotSize == 0) { dotType = DotTypes.PEN_DOWN; timestamp = penDownTime + timeGap; prevTimestamp = timestamp; } else if (dotTotalCount > dotCount) { dotType = DotTypes.PEN_MOVE; timestamp = prevTimestamp + timeGap; prevTimestamp = timestamp; } else { dotType = DotTypes.PEN_UP; timestamp = penUpTime; isPenUp = true; } Dot.Builder builder; if (penMaxForce == 0) { builder = new Dot.Builder(); } else { builder = new Dot.Builder(penMaxForce); } offlineFilterForPaper.Put( builder .section(mSectionId) .owner(mOwnerId) .note(mNoteId) .page(mPageId) .coord(x + fx * 0.01f, y + fy * 0.01f) .force(force) .color(color) .timestamp(timestamp) .dotType(dotType).Build(), null ); dotSize += 8; if (isPenUp) { byte dotCalcCs = CalcChecksum(CopyOfRange(mBody, dotStartIndex, dotSize)); if (dotCalcCs == lineCheckSum) { for (int j = 0; j < offlineDots.Count; j++) { mDots.Add(offlineDots[j]); } } else { Debug.WriteLine("[OfflineDataParser] invalid CheckSum cs : " + lineCheckSum + ", calc : " + dotCalcCs); } offlineDots = new List <Dot>(); } i += BYTE_DOT_SIZE; } } }