Swift 4, чтение байтовых данных - PullRequest
0 голосов
/ 19 сентября 2018

, поэтому я недавно обновил свой IMAC и Xcode, после обновления часть моего кода не работала так, как предполагалось.Здесь я первоначально проверяю сообщения.

func checkForMessages() {
    while true {
        if inputBuffer.length < 4 {
            return
        }
        var msgLength = (inputBuffer.bytes).load(as: UInt32.self)
        msgLength = UInt32(bigEndian: msgLength)
        print("msgLength = \(msgLength)")
        print("inputBuffer Length = \(inputBuffer.length)")
        print("inputBuffer = \(inputBuffer)")
        if inputBuffer.length < msgLength {
            return
        }
        //print("data = \(inputBuffer.subdata(with: NSRange(location: 4, length: Int(msgLength))))")
        if inputBuffer.length < msgLength + 4 {
            return
        }
        let message: Data? = inputBuffer.subdata(with: NSRange(location: 4, length: Int(msgLength)))
        processMessage(message!)
        let amtRemaining: Int = inputBuffer.length - Int(msgLength) - 4
        if amtRemaining == 0 {
            inputBuffer = NSMutableData()
        }
        else {
            print("Creating input buffer of length \(amtRemaining)")
            inputBuffer = NSMutableData(bytes: inputBuffer.bytes + 4 + Int(msgLength), length: amtRemaining)
        }
    }
}

, а затем функция обработки сообщений

func processMessage(_ data: Data) {

    let reader = MessageReader(data: data)
    print("this is the message data\(data)")
    let msgType  = reader?.readByte().hashValue
}

, а затем собственно MessageReader, входящий в Objective C, так как я снял его сИнтернет некоторое время назад.С тех пор он работал нормально для меня.До сих пор.

#import "MessageReader.h"

@implementation MessageReader

- (id)initWithData:(NSData *)data {
   if ((self = [super init])) {
      _data = data;
      _offset = 0;
}
return self;
}

- (unsigned char)readByte {
    unsigned char retval = *((unsigned char *) (_data.bytes + _offset));
    _offset += sizeof(unsigned char);
    return retval;
}

- (int)readInt {
    int retval = *((unsigned int *) (_data.bytes + _offset));
   retval = ntohl(retval);
   _offset += sizeof(unsigned int);
   return retval;
}

- (NSString *)readString {
   int strLen = [self readInt];
   NSString *retval = [NSString stringWithCString:_data.bytes + _offset encoding:NSUTF8StringEncoding];
   _offset += strLen;
   return retval;
}

- (void)dealloc {
}

@end

Теперь проблема в том, что вместо того, чтобы возвращать число, скажем, «1» или «2», «30» и т. Д., Возвращается некое огромное число, например 1836718193728. Я считаю, что проблемалежит в messageReader, функции readByte.

1 Ответ

0 голосов
/ 21 сентября 2018

Из вашего комментария reader?.readByte().hasValue возвращает огромное число .(Я полагаю, hasValue - это просто опечатка, и hashValue.)

Это возможноповедение hashValue.

Используете ли вы hashValue, как если бы это был инструмент преобразования UInt8 в Int?

Это неправильно.Свойство hashValue реализовано (и должно быть реализовано) для возврата некоторого значения Int, которое соответствует одной аксиоме:

where a == b, a.hashValue == b.hashValue

В более старых версиях Swift UInt8.hashValue могло возвращать то же значение типаInt, но вам не следует полагаться на такие подробности реализации, которые не документированы.Небольшое изменение реализации может привести к другим результатам.

И фактически, Swift 4.2 радикально изменил реализацию hashValue.

SE-0206 Hashable Enhancements

Возможно, вам придется исправить все части вашего проекта, используя hashValue.Обычно вы используете Int.init(_:) для преобразования UInt8 в Int.

В контексте, подобном Optional Chaining, как показано в вашем let msgType, вам может потребоваться написать что-то вроде этого.

    let msgType = (reader?.getByte()).map{Int($0)}

Если у вас много деталей, которые неправильно используют hashValue, лучше напишите расширение:

extension UInt8 {
    var integerValue: Int {
        return Int(self)
    }
}

    let msgType = reader?.getByte().integerValue

Как правило, лучше не включать такие неправильные хаки в ваш проект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...