123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- /*
- * Copyright 2014 ZXing authors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #import "ZXAztecHighLevelEncoder.h"
- #import "ZXAztecState.h"
- #import "ZXAztecToken.h"
- #import "ZXBitArray.h"
- #import "ZXByteArray.h"
-
- @implementation ZXAztecState
-
- - (id)initWithToken:(ZXAztecToken *)token mode:(int)mode binaryBytes:(int)binaryBytes bitCount:(int)bitCount {
- if (self = [super init]) {
- _token = token;
- _mode = mode;
- _binaryShiftByteCount = binaryBytes;
- _bitCount = bitCount;
- }
-
- return self;
- }
-
- + (ZXAztecState *)initialState {
- return [[ZXAztecState alloc] initWithToken:[ZXAztecToken empty] mode:ZX_AZTEC_MODE_UPPER binaryBytes:0 bitCount:0];
- }
-
- // Create a new state representing this state with a latch to a (not
- // necessary different) mode, and then a code.
- - (ZXAztecState *)latchAndAppend:(int)mode value:(int)value {
- int bitCount = self.bitCount;
- ZXAztecToken *token = self.token;
- if (mode != self.mode) {
- int latch = ZX_AZTEC_LATCH_TABLE[self.mode][mode];
- token = [token add:latch & 0xFFFF bitCount:latch >> 16];
- bitCount += latch >> 16;
- }
- int latchModeBitCount = mode == ZX_AZTEC_MODE_DIGIT ? 4 : 5;
- token = [token add:value bitCount:latchModeBitCount];
- return [[ZXAztecState alloc] initWithToken:token mode:mode binaryBytes:0 bitCount:bitCount + latchModeBitCount];
- }
-
- // Create a new state representing this state, with a temporary shift
- // to a different mode to output a single value.
- - (ZXAztecState *)shiftAndAppend:(int)mode value:(int)value {
- //assert binaryShiftByteCount == 0 && this.mode != mode;
- ZXAztecToken *token = self.token;
- int thisModeBitCount = self.mode == ZX_AZTEC_MODE_DIGIT ? 4 : 5;
- // Shifts exist only to UPPER and PUNCT, both with tokens size 5.
- token = [token add:ZX_AZTEC_SHIFT_TABLE[self.mode][mode] bitCount:thisModeBitCount];
- token = [token add:value bitCount:5];
- return [[ZXAztecState alloc] initWithToken:token mode:self.mode binaryBytes:0 bitCount:self.bitCount + thisModeBitCount + 5];
- }
-
- // Create a new state representing this state, but an additional character
- // output in Binary Shift mode.
- - (ZXAztecState *)addBinaryShiftChar:(int)index {
- ZXAztecToken *token = self.token;
- int mode = self.mode;
- int bitCount = self.bitCount;
- if (self.mode == ZX_AZTEC_MODE_PUNCT || self.mode == ZX_AZTEC_MODE_DIGIT) {
- int latch = ZX_AZTEC_LATCH_TABLE[mode][ZX_AZTEC_MODE_UPPER];
- token = [token add:latch & 0xFFFF bitCount:latch >> 16];
- bitCount += latch >> 16;
- mode = ZX_AZTEC_MODE_UPPER;
- }
- int deltaBitCount =
- (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount == 31) ? 18 :
- (self.binaryShiftByteCount == 62) ? 9 : 8;
- ZXAztecState *result = [[ZXAztecState alloc] initWithToken:token mode:mode binaryBytes:self.binaryShiftByteCount + 1 bitCount:bitCount + deltaBitCount];
- if (result.binaryShiftByteCount == 2047 + 31) {
- // The string is as long as it's allowed to be. We should end it.
- result = [result endBinaryShift:index + 1];
- }
- return result;
- }
-
- // Create the state identical to this one, but we are no longer in
- // Binary Shift mode.
- - (ZXAztecState *)endBinaryShift:(int)index {
- if (self.binaryShiftByteCount == 0) {
- return self;
- }
- ZXAztecToken *token = self.token;
- token = [token addBinaryShift:index - self.binaryShiftByteCount byteCount:self.binaryShiftByteCount];
- return [[ZXAztecState alloc] initWithToken:token mode:self.mode binaryBytes:0 bitCount:self.bitCount];
- }
-
- // Returns true if "this" state is better (or equal) to be in than "that"
- // state under all possible circumstances.
- - (BOOL)isBetterThanOrEqualTo:(ZXAztecState *)other {
- int mySize = self.bitCount + (ZX_AZTEC_LATCH_TABLE[self.mode][other.mode] >> 16);
- if (other.binaryShiftByteCount > 0 &&
- (self.binaryShiftByteCount == 0 || self.binaryShiftByteCount > other.binaryShiftByteCount)) {
- mySize += 10; // Cost of entering Binary Shift mode.
- }
- return mySize <= other.bitCount;
- }
-
- - (ZXBitArray *)toBitArray:(ZXByteArray *)text {
- // Reverse the tokens, so that they are in the order that they should
- // be output
- NSMutableArray *symbols = [NSMutableArray array];
- for (ZXAztecToken *token = [self endBinaryShift:text.length].token; token != nil; token = token.previous) {
- [symbols insertObject:token atIndex:0];
- }
- ZXBitArray *bitArray = [[ZXBitArray alloc] init];
- // Add each token to the result.
- for (ZXAztecToken *symbol in symbols) {
- [symbol appendTo:bitArray text:text];
- }
- return bitArray;
- }
-
- - (NSString *)description {
- return [NSString stringWithFormat:@"%@ bits=%d bytes=%d", ZX_AZTEC_MODE_NAMES[self.mode],
- self.bitCount, self.binaryShiftByteCount];
- }
-
- @end
|