/**
   * Add data to the internal collection of data. This function is used by the data: scheme, about:
   * scheme and http/https schemes.
   *
   * @param data A byte array containing the content.
   * @param length The length of data. IMPORTANT: as this is called from network thread, can't call
   *     native directly
   */
  public void data(byte[] data, int length) {
    if (Config.LOGV) {
      Log.v(LOGTAG, "LoadListener.data(): url: " + url());
    }

    if (ignoreCallbacks()) {
      return;
    }

    // Decode base64 data
    // Note: It's fine that we only decode base64 here and not in the other
    // data call because the only caller of the stream version is not
    // base64 encoded.
    if ("base64".equalsIgnoreCase(mTransferEncoding)) {
      if (length < data.length) {
        byte[] trimmedData = new byte[length];
        System.arraycopy(data, 0, trimmedData, 0, length);
        data = trimmedData;
      }
      data = Base64.decodeBase64(data);
      length = data.length;
    }
    // Synchronize on mData because commitLoad may write mData to WebCore
    // and we don't want to replace mData or mDataLength at the same time
    // as a write.
    boolean sendMessage = false;
    synchronized (mDataBuilder) {
      sendMessage = mDataBuilder.isEmpty();
      mDataBuilder.append(data, 0, length);
    }
    if (sendMessage) {
      // Send a message whenever data comes in after a write to WebCore
      sendMessageInternal(obtainMessage(MSG_CONTENT_DATA));
    }
  }
  /** Commit the load. It should be ok to call repeatedly but only before tearDown is called. */
  private void commitLoad() {
    if (mCancelled) return;

    // Give the data to WebKit now
    PerfChecker checker = new PerfChecker();
    ByteArrayBuilder.Chunk c;
    while (true) {
      c = mDataBuilder.getFirstChunk();
      if (c == null) break;

      if (c.mLength != 0) {
        if (mCacheResult != null) {
          try {
            mCacheResult.outStream.write(c.mArray, 0, c.mLength);
          } catch (IOException e) {
            mCacheResult = null;
          }
        }
        nativeAddData(c.mArray, c.mLength);
      }
      mDataBuilder.releaseChunk(c);
      checker.responseAlert("res nativeAddData");
    }
  }
Пример #3
0
  /**
   * http://android-essential-devtopics.blogspot.com/2013/02/sending-bit-image-to-epson-printer.html
   *
   * @author Oleg Morozov 02/21/2013 (via public domain)
   * @author Tres Finocchiaro 10/01/2013
   * @param b
   */
  private void appendEpsonSlices(ByteArrayBuilder builder) {
    //        BitSet dots = data.getDots();
    //        outputStream.write(PrinterCommands.INIT);

    // So we have our bitmap data sitting in a bit array called "dots."
    // This is one long array of 1s (black) and 0s (white) pixels arranged
    // as if we had scanned the bitmap from top to bottom, left to right.
    // The printer wants to see these arranged in bytes stacked three high.
    // So, essentially, we need to read 24 bits for x = 0, generate those
    // bytes, and send them to the printer, then keep increasing x. If our
    // image is more than 24 dots high, we have to send a second bit image
    // command to draw the next slice of 24 dots in the image.

    // Set the line spacing to 24 dots, the height of each "stripe" of the
    // image that we're drawing. If we don't do this, and we need to
    // draw the bitmap in multiple passes, then we'll end up with some
    // whitespace between slices of the image since the default line
    // height--how much the printer moves on a newline--is 30 dots.
    builder.append(new byte[] {0x1B, 0x33, 24});

    // OK. So, starting from x = 0, read 24 bits down and send that data
    // to the printer. The offset variable keeps track of our global 'y'
    // position in the image. For example, if we were drawing a bitmap
    // that is 48 pixels high, then this while loop will execute twice,
    // once for each pass of 24 dots. On the first pass, the offset is
    // 0, and on the second pass, the offset is 24. We keep making
    // these 24-dot stripes until we've execute past the height of the
    // bitmap.
    int offset = 0;

    while (offset < getHeight()) {
      // The third and fourth parameters to the bit image command are
      // 'nL' and 'nH'. The 'L' and the 'H' refer to 'low' and 'high', respectively.
      // All 'n' really is is the width of the image that we're about to draw.
      // Since the width can be greater than 255 dots, the parameter has to
      // be split across two bytes, which is why the documentation says the
      // width is 'nL' + ('nH' * 256).
      // builder.append(new byte[] {0x1B, 0x2A, 33, -128, 0});
      byte nL = (byte) ((int) (getWidth() % 256));
      byte nH = (byte) ((int) (getWidth() / 256));
      builder.append(new byte[] {0x1B, 0x2A, (byte) dotDensity, nL, nH});

      for (int x = 0; x < getWidth(); ++x) {
        // Remember, 24 dots = 24 bits = 3 bytes.
        // The 'k' variable keeps track of which of those
        // three bytes that we're currently scribbling into.
        for (int k = 0; k < 3; ++k) {
          byte slice = 0;

          // A byte is 8 bits. The 'b' variable keeps track
          // of which bit in the byte we're recording.
          for (int b = 0; b < 8; ++b) {
            // Calculate the y position that we're currently
            // trying to draw. We take our offset, divide it
            // by 8 so we're talking about the y offset in
            // terms of bytes, add our current 'k' byte
            // offset to that, multiple by 8 to get it in terms
            // of bits again, and add our bit offset to it.
            int y = (((offset / 8) + k) * 8) + b;

            // Calculate the location of the pixel we want in the bit array.
            // It'll be at (y * width) + x.
            int i = (y * getWidth()) + x;

            // If the image (or this stripe of the image)
            // is shorter than 24 dots, pad with zero.
            boolean v = false;
            if (i < getImageAsBooleanArray().length) {
              v = getImageAsBooleanArray()[i];
            }

            // Finally, store our bit in the byte that we're currently
            // scribbling to. Our current 'b' is actually the exact
            // opposite of where we want it to be in the byte, so
            // subtract it from 7, shift our bit into place in a temp
            // byte, and OR it with the target byte to get it into there.
            slice |= (byte) ((v ? 1 : 0) << (7 - b));
          }

          // Phew! Write the damn byte to the buffer
          builder.append(new byte[] {slice});
        }
      }

      // We're done with this 24-dot high pass. Render a newline
      // to bump the print head down to the next line
      // and keep on trucking.
      offset += 24;
      builder.append(new byte[] {10});
    }

    // Restore the line spacing to the default of 30 dots.
    builder.append(new byte[] {0x1B, 0x33, 30});
  }