See ISO 18004:2006, 6.4.1, Tables 2 and 3. This enum encapsulates the various modes in which data can be encoded to bits in the QR code standard.

Пример #1
0
 /// <summary>
 /// Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
 /// </summary>
 /// <param name="content">The content.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 /// <param name="encoding">The encoding.</param>
 internal static void appendBytes(String content,
                         Mode mode,
                         BitArray bits,
                         String encoding)
 {
    if (mode.Equals(Mode.NUMERIC))
       appendNumericBytes(content, bits);
    else
       if (mode.Equals(Mode.ALPHANUMERIC))
          appendAlphanumericBytes(content, bits);
       else
          if (mode.Equals(Mode.BYTE))
             append8BitBytes(content, bits, encoding);
          else
             if (mode.Equals(Mode.KANJI))
                appendKanjiBytes(content, bits);
             else
                throw new WriterException("Invalid mode: " + mode);
 }
Пример #2
0
 /// <summary>
 /// Append length info. On success, store the result in "bits".
 /// </summary>
 /// <param name="numLetters">The num letters.</param>
 /// <param name="version">The version.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 internal static void appendLengthInfo(int numLetters, Version version, Mode mode, BitArray bits)
 {
    int numBits = mode.getCharacterCountBits(version);
    if (numLetters >= (1 << numBits))
    {
       throw new WriterException(numLetters + " is bigger than " + ((1 << numBits) - 1));
    }
    bits.appendBits(numLetters, numBits);
 }
Пример #3
0
 /// <summary>
 /// Append mode info. On success, store the result in "bits".
 /// </summary>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 internal static void appendModeInfo(Mode mode, BitArray bits)
 {
    bits.appendBits(mode.Bits, 4);
 }
Пример #4
0
 /// <summary>
 /// Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
 /// </summary>
 /// <param name="content">The content.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 /// <param name="encoding">The encoding.</param>
 internal static void appendBytes(String content,
                       Mode mode,
                       BitArray bits,
                       String encoding)
 {
     // TODO: check the purpose of this .Equals(obj)
     if (mode == Mode.BYTE)
     append8BitBytes(content, bits, encoding);
     else
         throw new WriterException("Invalid mode: " + mode);
 }
Пример #5
0
 /// <summary>
 /// Append "bytes" in "mode" mode (encoding) into "bits". On success, store the result in "bits".
 /// </summary>
 /// <param name="content">The content.</param>
 /// <param name="mode">The mode.</param>
 /// <param name="bits">The bits.</param>
 /// <param name="encoding">The encoding.</param>
 internal static void appendBytes(String content,
                         Mode mode,
                         BitArray bits,
                         String encoding)
 {
   if (mode.Equals(Mode.BYTE))
       append8BitBytes(content, bits, encoding);
       else
           throw new WriterException("Invalid mode: " + mode);
 }
        internal static DecoderResult decode(byte[] bytes,
                                             Version version,
                                             ErrorCorrectionLevel ecLevel,
                                             IDictionary <DecodeHintType, object> hints)
        {
            var bits           = new BitSource(bytes);
            var result         = new StringBuilder(50);
            var byteSegments   = new List <byte[]>(1);
            var symbolSequence = -1;
            var parityData     = -1;
            int symbologyModifier;

            try
            {
                CharacterSetECI currentCharacterSetECI = null;
                bool            fc1InEffect            = false;
                bool            hasFNC1first           = false;
                bool            hasFNC1second          = false;
                Mode            mode;
                do
                {
                    // While still another segment to read...
                    if (bits.available() < 4)
                    {
                        // OK, assume we're done. Really, a TERMINATOR mode should have been recorded here
                        mode = Mode.TERMINATOR;
                    }
                    else
                    {
                        try
                        {
                            mode = Mode.forBits(bits.readBits(4)); // mode is encoded by 4 bits
                        }
                        catch (ArgumentException)
                        {
                            return(null);
                        }
                    }
                    switch (mode.Name)
                    {
                    case Mode.Names.TERMINATOR:
                        break;

                    case Mode.Names.FNC1_FIRST_POSITION:
                        hasFNC1first = true;     // symbology detection
                                                 // We do little with FNC1 except alter the parsed result a bit according to the spec
                        fc1InEffect = true;
                        break;

                    case Mode.Names.FNC1_SECOND_POSITION:
                        hasFNC1second = true;     // symbology detection
                        // We do little with FNC1 except alter the parsed result a bit according to the spec
                        fc1InEffect = true;
                        break;

                    case Mode.Names.STRUCTURED_APPEND:
                        if (bits.available() < 16)
                        {
                            return(null);
                        }
                        // not really supported; but sequence number and parity is added later to the result metadata
                        // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue
                        symbolSequence = bits.readBits(8);
                        parityData     = bits.readBits(8);
                        break;

                    case Mode.Names.ECI:
                        // Count doesn't apply to ECI
                        int value = parseECIValue(bits);
                        currentCharacterSetECI = CharacterSetECI.getCharacterSetECIByValue(value);
                        if (currentCharacterSetECI == null)
                        {
                            return(null);
                        }
                        break;

                    case Mode.Names.HANZI:
                        // First handle Hanzi mode which does not start with character count
                        //chinese mode contains a sub set indicator right after mode indicator
                        int subset     = bits.readBits(4);
                        int countHanzi = bits.readBits(mode.getCharacterCountBits(version));
                        if (subset == GB2312_SUBSET)
                        {
                            if (!decodeHanziSegment(bits, result, countHanzi))
                            {
                                return(null);
                            }
                        }
                        break;

                    default:
                        // "Normal" QR code modes:
                        // How many characters will follow, encoded in this mode?
                        int count = bits.readBits(mode.getCharacterCountBits(version));
                        switch (mode.Name)
                        {
                        case Mode.Names.NUMERIC:
                            if (!decodeNumericSegment(bits, result, count))
                            {
                                return(null);
                            }
                            break;

                        case Mode.Names.ALPHANUMERIC:
                            if (!decodeAlphanumericSegment(bits, result, count, fc1InEffect))
                            {
                                return(null);
                            }
                            break;

                        case Mode.Names.BYTE:
                            if (!decodeByteSegment(bits, result, count, currentCharacterSetECI, byteSegments, hints))
                            {
                                return(null);
                            }
                            break;

                        case Mode.Names.KANJI:
                            if (!decodeKanjiSegment(bits, result, count))
                            {
                                return(null);
                            }
                            break;

                        default:
                            return(null);
                        }
                        break;
                    }
                } while (mode != Mode.TERMINATOR);

                if (currentCharacterSetECI != null)
                {
                    if (hasFNC1first)
                    {
                        symbologyModifier = 4;
                    }
                    else if (hasFNC1second)
                    {
                        symbologyModifier = 6;
                    }
                    else
                    {
                        symbologyModifier = 2;
                    }
                }
                else
                {
                    if (hasFNC1first)
                    {
                        symbologyModifier = 3;
                    }
                    else if (hasFNC1second)
                    {
                        symbologyModifier = 5;
                    }
                    else
                    {
                        symbologyModifier = 1;
                    }
                }
            }
            catch (ArgumentException)
            {
                // from readBits() calls
                return(null);
            }

            return(new DecoderResult(bytes,
                                     result.ToString(),
                                     byteSegments.Count == 0 ? null : byteSegments,
                                     ecLevel == null ? null : ecLevel.ToString(),
                                     symbolSequence, parityData, symbologyModifier));
        }