宽窄优行-由【嘉易行】项目成品而来
younger_times
2023-04-06 a1ae6802080a22e6e6ce6d0935e95facb1daca5c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
//  RHSocketVariableLengthDecoder.m
//  RHSocketKitDemo
//
//  Created by zhuruhong on 16/2/15.
//  Copyright © 2016年 zhuruhong. All rights reserved.
//
 
#import "RHSocketVariableLengthDecoder.h"
#import "RHSocketException.h"
#import "RHSocketUtils.h"
#import "RHSocketPacketContext.h"
 
@implementation RHSocketVariableLengthDecoder
 
- (instancetype)init
{
    if (self = [super init]) {
        _maxFrameSize = 65536;
        _countOfLengthByte = 2;
        _reverseOfLengthByte = YES;
    }
    return self;
}
 
- (NSInteger)decodeData:(NSData *)downstreamData output:(id<RHSocketDecoderOutputProtocol>)output
{
    NSUInteger headIndex = 0;
    
    //先读区2个字节的协议长度 (前2个字节为数据包的长度)
    while (downstreamData && downstreamData.length - headIndex > _countOfLengthByte) {
        NSData *lenData = [downstreamData subdataWithRange:NSMakeRange(headIndex, _countOfLengthByte)];
        //长度字节数据,可能存在高低位互换,通过数值转换工具处理
        NSUInteger frameLen = (NSUInteger)[RHSocketUtils valueFromBytes:lenData reverse:_reverseOfLengthByte];
        if (frameLen >= _maxFrameSize - _countOfLengthByte) {
            [RHSocketException raiseWithReason:@"[Decode] Too Long Frame ..."];
            return -1;
        }//
        
        //剩余数据,不是完整的数据包,则break继续读取等待
        if (downstreamData.length - headIndex < _countOfLengthByte + frameLen) {
            break;
        }
        //数据包(长度+内容)
        NSData *frameData = [downstreamData subdataWithRange:NSMakeRange(headIndex, _countOfLengthByte + frameLen)];
        RHSocketLog(@"[Log]: frameData: %@", frameData);
        
        //去除数据长度后的数据内容
        RHSocketPacketResponse *ctx = [[RHSocketPacketResponse alloc] init];
        ctx.object = [frameData subdataWithRange:NSMakeRange(_countOfLengthByte, frameLen)];
        
        //责任链模式,丢给下一个处理器
        if (_nextDecoder) {
            [_nextDecoder decode:ctx output:output];
        } else {
            [output didDecode:ctx];
        }
        
        //调整已经解码数据
        headIndex += frameData.length;
    }//while
    return headIndex;
}
 
- (NSInteger)decode:(id<RHDownstreamPacket>)downstreamPacket output:(id<RHSocketDecoderOutputProtocol>)output
{
    id object = [downstreamPacket object];
    if (![object isKindOfClass:[NSData class]]) {
        [RHSocketException raiseWithReason:@"[Decode] object should be NSData ..."];
        return -1;
    }
    
    return [self decodeData:object output:output];
}
 
@end