Android Open Source - zxing-android-portrait Decode Hint Manager






From Project

Back to project page zxing-android-portrait.

License

The source code is released under:

Apache License

If you think the Android project zxing-android-portrait listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2013 ZXing authors/*from   w ww  . j a va2  s .c o m*/
 *
 * 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.
 */

package com.google.zxing.client.android;

import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

import com.google.zxing.DecodeHintType;

/**
 * @author Lachezar Dobrev
 */
final class DecodeHintManager {
  
  private static final String TAG = DecodeHintManager.class.getSimpleName();

  // This pattern is used in decoding integer arrays.
  private static final Pattern COMMA = Pattern.compile(",");

  private DecodeHintManager() {}

  /**
   * <p>Split a query string into a list of name-value pairs.</p>
   * 
   * <p>This is an alternative to the {@link Uri#getQueryParameterNames()} and
   * {@link Uri#getQueryParameters(String)}, which are quirky and not suitable
   * for exist-only Uri parameters.</p>
   * 
   * <p>This method ignores multiple parameters with the same name and returns the
   * first one only. This is technically incorrect, but should be acceptable due
   * to the method of processing Hints: no multiple values for a hint.</p>
   * 
   * @param query query to split
   * @return name-value pairs
   */
  private static Map<String,String> splitQuery(String query) {
    Map<String,String> map = new HashMap<>();
    int pos = 0;
    while (pos < query.length()) {
      if (query.charAt(pos) == '&') {
        // Skip consecutive ampersand separators.
        pos ++;
        continue;
      }
      int amp = query.indexOf('&', pos);
      int equ = query.indexOf('=', pos);
      if (amp < 0) {
        // This is the last element in the query, no more ampersand elements.
        String name;
        String text;
        if (equ < 0) {
          // No equal sign
          name = query.substring(pos);
          name = name.replace('+', ' '); // Preemptively decode +
          name = Uri.decode(name);
          text = "";
        } else {
          // Split name and text.
          name = query.substring(pos, equ);
          name = name.replace('+', ' '); // Preemptively decode +
          name = Uri.decode(name);
          text = query.substring(equ + 1);
          text = text.replace('+', ' '); // Preemptively decode +
          text = Uri.decode(text);
        }
        if (!map.containsKey(name)) {
          map.put(name, text);
        }
        break;
      }
      if (equ < 0 || equ > amp) {
        // No equal sign until the &: this is a simple parameter with no value.
        String name = query.substring(pos, amp);
        name = name.replace('+', ' '); // Preemptively decode +
        name = Uri.decode(name);
        if (!map.containsKey(name)) {
          map.put(name, "");
        }
        pos = amp + 1;
        continue;
      }
      String name = query.substring(pos, equ);
      name = name.replace('+', ' '); // Preemptively decode +
      name = Uri.decode(name);
      String text = query.substring(equ+1, amp);
      text = text.replace('+', ' '); // Preemptively decode +
      text = Uri.decode(text);
      if (!map.containsKey(name)) {
        map.put(name, text);
      }
      pos = amp + 1;
    }
    return map;
  }

  static Map<DecodeHintType,?> parseDecodeHints(Uri inputUri) {
    String query = inputUri.getEncodedQuery();
    if (query == null || query.isEmpty()) {
      return null;
    }

    // Extract parameters
    Map<String, String> parameters = splitQuery(query);

    Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);

    for (DecodeHintType hintType: DecodeHintType.values()) {

      if (hintType == DecodeHintType.CHARACTER_SET ||
          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
          hintType == DecodeHintType.POSSIBLE_FORMATS) {
        continue; // This hint is specified in another way
      }

      String parameterName = hintType.name();
      String parameterText = parameters.get(parameterName);
      if (parameterText == null) {
        continue;
      }
      if (hintType.getValueType().equals(Object.class)) {
        // This is an unspecified type of hint content. Use the value as is.
        // TODO: Can we make a different assumption on this?
        hints.put(hintType, parameterText);
        continue;
      }
      if (hintType.getValueType().equals(Void.class)) {
        // Void hints are just flags: use the constant specified by DecodeHintType
        hints.put(hintType, Boolean.TRUE);
        continue;
      }
      if (hintType.getValueType().equals(String.class)) {
        // A string hint: use the decoded value.
        hints.put(hintType, parameterText);
        continue;
      }
      if (hintType.getValueType().equals(Boolean.class)) {
        // A boolean hint: a few values for false, everything else is true.
        // An empty parameter is simply a flag-style parameter, assuming true
        if (parameterText.isEmpty()) {
          hints.put(hintType, Boolean.TRUE);
        } else if ("0".equals(parameterText) || 
                   "false".equalsIgnoreCase(parameterText) || 
                   "no".equalsIgnoreCase(parameterText)) {
          hints.put(hintType, Boolean.FALSE);
        } else {
          hints.put(hintType, Boolean.TRUE);
        }

        continue;
      }
      if (hintType.getValueType().equals(int[].class)) {
        // An integer array. Used to specify valid lengths.
        // Strip a trailing comma as in Java style array initialisers.
        if (!parameterText.isEmpty() && parameterText.charAt(parameterText.length() - 1) == ',') {
          parameterText = parameterText.substring(0, parameterText.length() - 1);
        }
        String[] values = COMMA.split(parameterText);
        int[] array = new int[values.length];
        for (int i = 0; i < values.length; i++) {
          try {
            array[i] = Integer.parseInt(values[i]);
          } catch (NumberFormatException ignored) {
            Log.w(TAG, "Skipping array of integers hint " + hintType + " due to invalid numeric value: '" + values[i] + '\'');
            array = null;
            break;
          }
        }
        if (array != null) {
          hints.put(hintType, array);
        }
        continue;
      } 
      Log.w(TAG, "Unsupported hint type '" + hintType + "' of type " + hintType.getValueType());
    }

    Log.i(TAG, "Hints from the URI: " + hints);
    return hints;
  }

  static Map<DecodeHintType, Object> parseDecodeHints(Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras == null || extras.isEmpty()) {
      return null;
    }
    Map<DecodeHintType,Object> hints = new EnumMap<>(DecodeHintType.class);

    for (DecodeHintType hintType: DecodeHintType.values()) {

      if (hintType == DecodeHintType.CHARACTER_SET ||
          hintType == DecodeHintType.NEED_RESULT_POINT_CALLBACK ||
          hintType == DecodeHintType.POSSIBLE_FORMATS) {
        continue; // This hint is specified in another way
      }

      String hintName = hintType.name();
      if (extras.containsKey(hintName)) {
        if (hintType.getValueType().equals(Void.class)) {
          // Void hints are just flags: use the constant specified by the DecodeHintType
          hints.put(hintType, Boolean.TRUE);
        } else {
          Object hintData = extras.get(hintName);
          if (hintType.getValueType().isInstance(hintData)) {
            hints.put(hintType, hintData);
          } else {
            Log.w(TAG, "Ignoring hint " + hintType + " because it is not assignable from " + hintData);
          }
        }
      }
    }

    Log.i(TAG, "Hints from the Intent: " + hints);
    return hints;
  }

}




Java Source Code List

com.google.zxing.client.android.AmbientLightManager.java
com.google.zxing.client.android.BeepManager.java
com.google.zxing.client.android.CaptureActivityHandler.java
com.google.zxing.client.android.CaptureActivity.java
com.google.zxing.client.android.Contents.java
com.google.zxing.client.android.DecodeFormatManager.java
com.google.zxing.client.android.DecodeHandler.java
com.google.zxing.client.android.DecodeHintManager.java
com.google.zxing.client.android.DecodeThread.java
com.google.zxing.client.android.FinishListener.java
com.google.zxing.client.android.HelpActivity.java
com.google.zxing.client.android.HttpHelper.java
com.google.zxing.client.android.InactivityTimer.java
com.google.zxing.client.android.IntentSource.java
com.google.zxing.client.android.Intents.java
com.google.zxing.client.android.LocaleManager.java
com.google.zxing.client.android.PreferencesActivity.java
com.google.zxing.client.android.PreferencesFragment.java
com.google.zxing.client.android.ScanFromWebPageManager.java
com.google.zxing.client.android.ViewfinderResultPointCallback.java
com.google.zxing.client.android.ViewfinderView.java
com.google.zxing.client.android.book.BrowseBookListener.java
com.google.zxing.client.android.book.SearchBookContentsActivity.java
com.google.zxing.client.android.book.SearchBookContentsAdapter.java
com.google.zxing.client.android.book.SearchBookContentsListItem.java
com.google.zxing.client.android.book.SearchBookContentsResult.java
com.google.zxing.client.android.camera.AutoFocusManager.java
com.google.zxing.client.android.camera.CameraConfigurationManager.java
com.google.zxing.client.android.camera.CameraManager.java
com.google.zxing.client.android.camera.FrontLightMode.java
com.google.zxing.client.android.camera.PreviewCallback.java
com.google.zxing.client.android.camera.metering.MeteringInterface.java
com.google.zxing.client.android.camera.open.OpenCameraInterface.java
com.google.zxing.client.android.clipboard.ClipboardInterface.java
com.google.zxing.client.android.encode.ContactEncoder.java
com.google.zxing.client.android.encode.EncodeActivity.java
com.google.zxing.client.android.encode.Formatter.java
com.google.zxing.client.android.encode.MECARDContactEncoder.java
com.google.zxing.client.android.encode.QRCodeEncoder.java
com.google.zxing.client.android.encode.VCardContactEncoder.java
com.google.zxing.client.android.encode.VCardFieldFormatter.java
com.google.zxing.client.android.encode.VCardTelDisplayFormatter.java
com.google.zxing.client.android.history.DBHelper.java
com.google.zxing.client.android.history.HistoryActivity.java
com.google.zxing.client.android.history.HistoryItemAdapter.java
com.google.zxing.client.android.history.HistoryItem.java
com.google.zxing.client.android.history.HistoryManager.java
com.google.zxing.client.android.result.AddressBookResultHandler.java
com.google.zxing.client.android.result.CalendarResultHandler.java
com.google.zxing.client.android.result.EmailAddressResultHandler.java
com.google.zxing.client.android.result.GeoResultHandler.java
com.google.zxing.client.android.result.ISBNResultHandler.java
com.google.zxing.client.android.result.ProductResultHandler.java
com.google.zxing.client.android.result.ResultButtonListener.java
com.google.zxing.client.android.result.ResultHandlerFactory.java
com.google.zxing.client.android.result.ResultHandler.java
com.google.zxing.client.android.result.SMSResultHandler.java
com.google.zxing.client.android.result.TelResultHandler.java
com.google.zxing.client.android.result.TextResultHandler.java
com.google.zxing.client.android.result.URIResultHandler.java
com.google.zxing.client.android.result.WifiResultHandler.java
com.google.zxing.client.android.result.supplement.BookResultInfoRetriever.java
com.google.zxing.client.android.result.supplement.ProductResultInfoRetriever.java
com.google.zxing.client.android.result.supplement.SupplementalInfoRetriever.java
com.google.zxing.client.android.result.supplement.TitleRetriever.java
com.google.zxing.client.android.result.supplement.URIResultInfoRetriever.java
com.google.zxing.client.android.share.AppInfo.java
com.google.zxing.client.android.share.AppPickerActivity.java
com.google.zxing.client.android.share.BookmarkAdapter.java
com.google.zxing.client.android.share.BookmarkPickerActivity.java
com.google.zxing.client.android.share.LoadPackagesAsyncTask.java
com.google.zxing.client.android.share.ShareActivity.java
com.google.zxing.client.android.wifi.NetworkType.java
com.google.zxing.client.android.wifi.WifiConfigManager.java