- Notifications
You must be signed in to change notification settings - Fork 9
Implement a get request #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
87d1682 186088c d772994 1bdd64d e3a764c c2e774f bafe676 923cf2b 423d8f9 48772a6 79b653f 9056f40 118b029 6bad1ff 437783a bfb446a bc1b03b 4288843 File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -41,3 +41,16 @@ extension ByteBuffer { | |
| } | ||
| } | ||
| } | ||
| | ||
| extension ByteBuffer { | ||
| /// Read flags from this `ByteBuffer`, moving the reader index forward appropriately. | ||
| /// | ||
| /// - returns: An instance of `MemcachedFlags` containing the flags read from the buffer. | ||
| mutating func readMemcachedFlags() -> MemcachedFlags { | ||
| var flagBytes: Set<UInt8> = [] | ||
| while let nextByte = self.readInteger(as: UInt8.self), nextByte != UInt8.whitespace { | ||
| ||
| flagBytes.insert(nextByte) | ||
| } | ||
| return MemcachedFlags(flagBytes: flagBytes) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -70,8 +70,10 @@ struct MemcachedResponseDecoder: NIOSingleStepByteToMessageDecoder { | |
| enum NextStep: Hashable { | ||
| /// The initial step. | ||
| case returnCode | ||
| /// Decode the data length, flags or check if we are the end | ||
| case dataLengthOrFlag(MemcachedResponse.ReturnCode) | ||
| /// Decode the data length | ||
| case dataLength(MemcachedResponse.ReturnCode) | ||
| /// Decode the flag | ||
| case flag(MemcachedResponse.ReturnCode, UInt64?) | ||
| /// Decode the next flag | ||
| case decodeNextFlag(MemcachedResponse.ReturnCode, UInt64?) | ||
| ||
| // TODO: Add a next step for decoding the response data if the return code is VA | ||
| | @@ -114,58 +116,53 @@ struct MemcachedResponseDecoder: NIOSingleStepByteToMessageDecoder { | |
| } | ||
| | ||
| let returnCode = MemcachedResponse.ReturnCode(bytes) | ||
| self.nextStep = .dataLengthOrFlag(returnCode) | ||
| self.nextStep = .dataLength(returnCode) | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should check the return code here and decide if we transition to | ||
| return .continueDecodeLoop | ||
| | ||
| case .dataLengthOrFlag(let returnCode): | ||
| case .dataLength(let returnCode): | ||
| if returnCode == .VA { | ||
| guard let dataLength = buffer.readInteger(as: UInt64.self) else { | ||
| ||
| return .waitForMoreBytes | ||
| } | ||
| | ||
| var flagBytes: Set<UInt8> = [] | ||
| while let nextByte = buffer.readInteger(as: UInt8.self), nextByte != UInt8.whitespace { | ||
| flagBytes.insert(nextByte) | ||
| } | ||
| | ||
| let flags = MemcachedFlags(flagBytes: flagBytes) | ||
| | ||
| guard let nextByte = buffer.readInteger(as: UInt8.self), | ||
| nextByte == UInt8.carriageReturn, | ||
| let nextNextByte = buffer.readInteger(as: UInt8.self), | ||
| nextNextByte == UInt8.newline else { | ||
| self.nextStep = .flag(returnCode, dataLength) | ||
| return .continueDecodeLoop | ||
| } else { | ||
| guard let nextByte = buffer.readInteger(as: UInt8.self) else { | ||
| return .waitForMoreBytes | ||
| } | ||
| | ||
| self.nextStep = .decodeValue(returnCode, dataLength, flags) | ||
| return .continueDecodeLoop | ||
| if nextByte == UInt8.whitespace { | ||
| self.nextStep = .decodeNextFlag(returnCode, nil) | ||
| return .continueDecodeLoop | ||
| } else if nextByte == UInt8.carriageReturn { | ||
| guard let nextNextByte = buffer.readInteger(as: UInt8.self), nextNextByte == UInt8.newline else { | ||
| return .waitForMoreBytes | ||
| } | ||
| let response = MemcachedResponse(returnCode: returnCode, dataLength: nil) | ||
| self.nextStep = .returnCode | ||
| return .returnDecodedResponse(response) | ||
| } else { | ||
| throw MemcachedDecoderError.unexpectedCharacter(nextByte) | ||
| } | ||
| } | ||
| | ||
| guard let nextByte = buffer.readInteger(as: UInt8.self) else { | ||
| case .flag(let returnCode, let dataLength): | ||
| let flags = buffer.readMemcachedFlags() | ||
| Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So this is where it gets a bit tricky and I would like us to take a shortcut for now. The problem is that we can have a partial buffer where we don't have the carriageReturn&newline yet and we would need to support reading partial flags. This also includes reading the partial tokens of flags which might be quite big. In a best world, we would go flag by flag and move ourselves forward. However, implementing this requires a bit of logic. What I would do for now is trying to scan the buffer forward to see if we have a Contributor Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good, we will create a new issue to handle the partial buffer implementation. | ||
| | ||
| guard let nextByte = buffer.readInteger(as: UInt8.self), | ||
| nextByte == UInt8.carriageReturn, | ||
| let nextNextByte = buffer.readInteger(as: UInt8.self), | ||
| nextNextByte == UInt8.newline else { | ||
| return .waitForMoreBytes | ||
| } | ||
| | ||
| if nextByte == UInt8.whitespace { | ||
| self.nextStep = .decodeNextFlag(returnCode, nil) | ||
| return .continueDecodeLoop | ||
| } else if nextByte == UInt8.carriageReturn { | ||
| guard let nextNextByte = buffer.readInteger(as: UInt8.self), nextNextByte == UInt8.newline else { | ||
| return .waitForMoreBytes | ||
| } | ||
| let response = MemcachedResponse(returnCode: returnCode, dataLength: nil) | ||
| self.nextStep = .returnCode | ||
| return .returnDecodedResponse(response) | ||
| } else { | ||
| throw MemcachedDecoderError.unexpectedCharacter(nextByte) | ||
| } | ||
| self.nextStep = .decodeValue(returnCode, dataLength!, flags) | ||
| return .continueDecodeLoop | ||
| | ||
| case .decodeNextFlag(let returnCode, let dataLength): | ||
| var flagBytes: Set<UInt8> = [] | ||
| while let nextByte = buffer.readInteger(as: UInt8.self), nextByte != UInt8.whitespace { | ||
| flagBytes.insert(nextByte) | ||
| } | ||
| let flags = buffer.readMemcachedFlags() | ||
| | ||
| let flags = MemcachedFlags(flagBytes: flagBytes) | ||
| let response = MemcachedResponse(returnCode: returnCode, dataLength: dataLength, flags: flags) | ||
| self.nextStep = .returnCode | ||
| return .returnDecodedResponse(response) | ||
| | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| | @@ -21,4 +21,3 @@ final class MemcachedFlagsTests: XCTestCase { | |
| XCTAssertTrue(flags.v) | ||
| } | ||
| } | ||
| | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allocating this set is unnecessary. I would rather init an "empty"
MemcachedFlagsin the beginning and then read byte by byte. For now we drop everything that is not avflag.