diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml index 5ddf87a6..caa4bbdf 100644 --- a/.github/workflows/jira.yml +++ b/.github/workflows/jira.yml @@ -3,7 +3,7 @@ on: pull_request: types: [opened] jobs: - security: + security-jira: if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'snyk-bot' || contains(github.event.pull_request.head.ref, 'snyk-fix-') || contains(github.event.pull_request.head.ref, 'snyk-upgrade-')}} runs-on: ubuntu-latest steps: @@ -26,3 +26,8 @@ jobs: PR: ${{ github.event.pull_request.html_url }} fields: "${{ secrets.JIRA_FIELDS }}" + - name: Transition issue + uses: atlassian/gajira-transition@v3 + with: + issue: ${{ steps.create.outputs.issue }} + transition: ${{ secrets.JIRA_TRANSITION }} diff --git a/.github/workflows/publish-snapshot.yml b/.github/workflows/publish-snapshot.yml deleted file mode 100644 index b43da5ae..00000000 --- a/.github/workflows/publish-snapshot.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: Publish - Snapshot - -on: - push: - branches: - - master - -jobs: - publish: - runs-on: ubuntu-latest - steps: - - name: Checkout project sources - uses: actions/checkout@v3 - - name: Check whether the version is a snapshot - run: | - if grep -q "\-SNAPSHOT" ./contentstack/build.gradle - then - : - else - exit 1 - fi - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 - - name: Setup local.properties - run: | - cat << EOF >> local.properties - sdk.dir=$ANDROID_HOME - host="${{ secrets.HOST }}" - APIKey="${{ secrets.API_KEY }}" - deliveryToken="${{ secrets.DELIVERY_TOKEN }}" - environment="${{ secrets.ENVIRONMENT }}" - contentType="${{ secrets.CONTENT_TYPE }}" - assetUid="${{ secrets.ASSET_UID }}" - EOF - - name: Build the SDK - Snapshot - run: | - ./gradlew clean build - - name: Publish the SDK - Snapshot - run: | - ./gradlew publishAllPublicationsToMavenCentralRepository - env: - ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.mavenCentralUsername }} - ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.mavenCentralPassword }} - ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.signingInMemoryKey }} - ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.signingInMemoryKeyId }} - ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.signingInMemoryKeyPassword }} \ No newline at end of file diff --git a/.github/workflows/sast-scan.yml b/.github/workflows/sast-scan.yml new file mode 100644 index 00000000..3b9521a5 --- /dev/null +++ b/.github/workflows/sast-scan.yml @@ -0,0 +1,11 @@ +name: SAST Scan +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-sast: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Semgrep Scan + run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}:/src" returntocorp/semgrep semgrep scan --config auto \ No newline at end of file diff --git a/.github/workflows/sca-scan.yml b/.github/workflows/sca-scan.yml index 482bc0f7..1f9aa651 100644 --- a/.github/workflows/sca-scan.yml +++ b/.github/workflows/sca-scan.yml @@ -3,7 +3,7 @@ on: pull_request: types: [opened, synchronize, reopened] jobs: - security: + security-sca: runs-on: ubuntu-latest steps: - uses: actions/checkout@master @@ -19,6 +19,6 @@ jobs: assetUid="${{ secrets.ASSET_UID }}" EOF - uses: snyk/actions/setup@master - - run: snyk test + - run: snyk test --fail-on=all env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} diff --git a/.gitignore b/.gitignore index 66adfeb1..7e8a92bc 100644 --- a/.gitignore +++ b/.gitignore @@ -26,8 +26,8 @@ build/ # Local configuration file (sdk path, etc) local.properties -gradle.properties -/gradle.properties +# gradle.properties +# /gradle.properties # Proguard folder generated by Eclipse diff --git a/CHANGELOG.md b/CHANGELOG.md index 09870501..bc2f6274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,17 @@ # CHANGELOG +## Version 3.15.0 + +### Date: 20-May-2024 + +- Fixes and enhancements + +--- + ## Version 3.14.0 ### Date: 13-May-2024 -- support of new sync api -- initSeqSync in stack class -- seqSync in stack class - GCP support implementation --- diff --git a/contentstack/build.gradle b/contentstack/build.gradle index c7540b6e..035e17c7 100755 --- a/contentstack/build.gradle +++ b/contentstack/build.gradle @@ -10,7 +10,7 @@ android.buildFeatures.buildConfig true mavenPublishing { publishToMavenCentral(SonatypeHost.DEFAULT) signAllPublications() - coordinates("com.contentstack.sdk", "android", "3.14.0") + coordinates("com.contentstack.sdk", "android", "3.15.0") pom { name = "contentstack-android" @@ -146,6 +146,9 @@ dependencies { androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', { exclude group: 'com.android.support', module: 'support-annotations' }) + +// implementation 'com.squareup.okio:okio:3.9.0' + implementation 'com.github.rjeschke:txtmark:0.12' } tasks.register('clearJar', Delete) { delete 'build/libs/contentstack.jar' } tasks.register('unzip', Copy) { @@ -160,4 +163,4 @@ tasks.register('createJar', Jar) { include 'com/contentstack/' //include 'META-INF/' } -createJar.dependsOn(clearJar, unzip, build) +createJar.dependsOn(clearJar, unzip, build) \ No newline at end of file diff --git a/contentstack/src/main/java/com/contentstack/okio/AsyncTimeout.java b/contentstack/src/main/java/com/contentstack/okio/AsyncTimeout.java deleted file mode 100755 index d37f7e85..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/AsyncTimeout.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.io.InterruptedIOException; - -/** - * This timeout uses a background thread to take action exactly when the timeout - * occurs. Use this to implement timeouts where they aren't supported natively, - * such as to sockets that are blocked on writing. - * - *

Subclasses should override {@link #timedOut} to take action when a timeout - * occurs. This method will be invoked by the shared watchdog thread so it - * should not do any long-running operations. Otherwise we risk starving other - * timeouts from being triggered. - * - *

Use {@link #sink} and {@link #source} to apply this timeout to a stream. - * The returned value will apply the timeout to each operation on the wrapped - * stream. - * - *

Callers should call {@link #enter} before doing work that is subject to - * timeouts, and {@link #exit} afterwards. The return value of {@link #exit} - * indicates whether a timeout was triggered. Note that the call to {@link - * #timedOut} is asynchronous, and may be called after {@link #exit}. - */ -public class AsyncTimeout extends Timeout { - /** - * The watchdog thread processes a linked list of pending timeouts, sorted in - * the order to be triggered. This class synchronizes on AsyncTimeout.class. - * This lock guards the queue. - * - *

Head's 'next' points to the first element of the linked list. The first - * element is the next node to time out, or null if the queue is empty. The - * head is null until the watchdog thread is started. - */ - private static AsyncTimeout head; - - /** - * True if this node is currently in the queue. - */ - private boolean inQueue; - - /** - * The next node in the linked list. - */ - private AsyncTimeout next; - - /** - * If scheduled, this is the time that the watchdog should time this out. - */ - private long timeoutAt; - - public final void enter() { - if (inQueue) throw new IllegalStateException("Unbalanced enter/exit"); - long timeoutNanos = timeoutNanos(); - boolean hasDeadline = hasDeadline(); - if (timeoutNanos == 0 && !hasDeadline) { - return; // No timeout and no deadline? Don't bother with the queue. - } - inQueue = true; - scheduleTimeout(this, timeoutNanos, hasDeadline); - } - - private static synchronized void scheduleTimeout( - AsyncTimeout node, long timeoutNanos, boolean hasDeadline) { - // Start the watchdog thread and create the head node when the first timeout is scheduled. - if (head == null) { - head = new AsyncTimeout(); - new Watchdog().start(); - } - - long now = System.nanoTime(); - if (timeoutNanos != 0 && hasDeadline) { - // Compute the earliest event; either timeout or deadline. Because nanoTime can wrap around, - // Math.min() is undefined for absolute values, but meaningful for relative ones. - node.timeoutAt = now + Math.min(timeoutNanos, node.deadlineNanoTime() - now); - } else if (timeoutNanos != 0) { - node.timeoutAt = now + timeoutNanos; - } else if (hasDeadline) { - node.timeoutAt = node.deadlineNanoTime(); - } else { - throw new AssertionError(); - } - - // Insert the node in sorted order. - long remainingNanos = node.remainingNanos(now); - for (AsyncTimeout prev = head; true; prev = prev.next) { - if (prev.next == null || remainingNanos < prev.next.remainingNanos(now)) { - node.next = prev.next; - prev.next = node; - if (prev == head) { - AsyncTimeout.class.notify(); // Wake up the watchdog when inserting at the front. - } - break; - } - } - } - - /** - * Returns true if the timeout occurred. - */ - public final boolean exit() { - if (!inQueue) return false; - inQueue = false; - return cancelScheduledTimeout(this); - } - - /** - * Returns true if the timeout occurred. - */ - private static synchronized boolean cancelScheduledTimeout(AsyncTimeout node) { - // Remove the node from the linked list. - for (AsyncTimeout prev = head; prev != null; prev = prev.next) { - if (prev.next == node) { - prev.next = node.next; - node.next = null; - return false; - } - } - - // The node wasn't found in the linked list: it must have timed out! - return true; - } - - /** - * Returns the amount of time left until the time out. This will be negative - * if the timeout has elapsed and the timeout should occur immediately. - */ - private long remainingNanos(long now) { - return timeoutAt - now; - } - - /** - * Invoked by the watchdog thread when the time between calls to {@link - * #enter()} and {@link #exit()} has exceeded the timeout. - */ - protected void timedOut() { - } - - /** - * Returns a new sink that delegates to {@code sink}, using this to implement - * timeouts. This works best if {@link #timedOut} is overridden to interrupt - * {@code sink}'s current operation. - */ - public final Sink sink(final Sink sink) { - return new Sink() { - @Override - public void write(Buffer source, long byteCount) throws IOException { - boolean throwOnTimeout = false; - enter(); - try { - sink.write(source, byteCount); - throwOnTimeout = true; - } catch (IOException e) { - throw exit(e); - } finally { - exit(throwOnTimeout); - } - } - - @Override - public void flush() throws IOException { - boolean throwOnTimeout = false; - enter(); - try { - sink.flush(); - throwOnTimeout = true; - } catch (IOException e) { - throw exit(e); - } finally { - exit(throwOnTimeout); - } - } - - @Override - public void close() throws IOException { - boolean throwOnTimeout = false; - enter(); - try { - sink.close(); - throwOnTimeout = true; - } catch (IOException e) { - throw exit(e); - } finally { - exit(throwOnTimeout); - } - } - - @Override - public Timeout timeout() { - return AsyncTimeout.this; - } - - @Override - public String toString() { - return "AsyncTimeout.sink(" + sink + ")"; - } - }; - } - - /** - * Returns a new source that delegates to {@code source}, using this to - * implement timeouts. This works best if {@link #timedOut} is overridden to - * interrupt {@code sink}'s current operation. - */ - public final Source source(final Source source) { - return new Source() { - @Override - public long read(Buffer sink, long byteCount) throws IOException { - boolean throwOnTimeout = false; - enter(); - try { - long result = source.read(sink, byteCount); - throwOnTimeout = true; - return result; - } catch (IOException e) { - throw exit(e); - } finally { - exit(throwOnTimeout); - } - } - - @Override - public void close() throws IOException { - boolean throwOnTimeout = false; - try { - source.close(); - throwOnTimeout = true; - } catch (IOException e) { - throw exit(e); - } finally { - exit(throwOnTimeout); - } - } - - @Override - public Timeout timeout() { - return AsyncTimeout.this; - } - - @Override - public String toString() { - return "AsyncTimeout.source(" + source + ")"; - } - }; - } - - /** - * Throws an InterruptedIOException if {@code throwOnTimeout} is true and a - * timeout occurred. - */ - final void exit(boolean throwOnTimeout) throws IOException { - boolean timedOut = exit(); - if (timedOut && throwOnTimeout) throw new InterruptedIOException("timeout"); - } - - /** - * Returns either {@code cause} or an InterruptedIOException that's caused by - * {@code cause} if a timeout occurred. - */ - final IOException exit(IOException cause) throws IOException { - if (!exit()) return cause; - InterruptedIOException e = new InterruptedIOException("timeout"); - e.initCause(cause); - return e; - } - - private static final class Watchdog extends Thread { - public Watchdog() { - super("Okio Watchdog"); - setDaemon(true); - } - - public void run() { - while (true) { - try { - AsyncTimeout timedOut = awaitTimeout(); - - // Didn't find a node to interrupt. Try again. - if (timedOut == null) continue; - - // Close the timed out node. - timedOut.timedOut(); - } catch (InterruptedException ignored) { - } - } - } - } - - /** - * Removes and returns the node at the head of the list, waiting for it to - * time out if necessary. Returns null if the situation changes while waiting: - * either a newer node is inserted at the head, or the node being waited on - * has been removed. - */ - private static synchronized AsyncTimeout awaitTimeout() throws InterruptedException { - // Get the next eligible node. - AsyncTimeout node = head.next; - - // The queue is empty. Wait for something to be enqueued. - if (node == null) { - AsyncTimeout.class.wait(); - return null; - } - - long waitNanos = node.remainingNanos(System.nanoTime()); - - // The head of the queue hasn't timed out yet. Await that. - if (waitNanos > 0) { - // Waiting is made complicated by the fact that we work in nanoseconds, - // but the API wants (millis, nanos) in two arguments. - long waitMillis = waitNanos / 1000000L; - waitNanos -= (waitMillis * 1000000L); - AsyncTimeout.class.wait(waitMillis, (int) waitNanos); - return null; - } - - // The head of the queue has timed out. Remove it. - head.next = node.next; - node.next = null; - return node; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Base64.java b/contentstack/src/main/java/com/contentstack/okio/Base64.java deleted file mode 100755 index a93f9cf8..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Base64.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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. - */ - -/** - * @author Alexander Y. Kleymenov - */ -package com.contentstack.okio; - -import java.io.UnsupportedEncodingException; - -final class Base64 { - private Base64() { - } - - public static byte[] decode(String in) { - // Ignore trailing '=' padding and whitespace from the input. - int limit = in.length(); - for (; limit > 0; limit--) { - char c = in.charAt(limit - 1); - if (c != '=' && c != '\n' && c != '\r' && c != ' ' && c != '\t') { - break; - } - } - - // If the input includes whitespace, this output array will be longer than necessary. - byte[] out = new byte[(int) (limit * 6L / 8L)]; - int outCount = 0; - int inCount = 0; - - int word = 0; - for (int pos = 0; pos < limit; pos++) { - char c = in.charAt(pos); - - int bits; - if (c >= 'A' && c <= 'Z') { - // char ASCII value - // A 65 0 - // Z 90 25 (ASCII - 65) - bits = c - 65; - } else if (c >= 'a' && c <= 'z') { - // char ASCII value - // a 97 26 - // z 122 51 (ASCII - 71) - bits = c - 71; - } else if (c >= '0' && c <= '9') { - // char ASCII value - // 0 48 52 - // 9 57 61 (ASCII + 4) - bits = c + 4; - } else if (c == '+') { - bits = 62; - } else if (c == '/') { - bits = 63; - } else if (c == '\n' || c == '\r' || c == ' ' || c == '\t') { - continue; - } else { - return null; - } - - // Append this char's 6 bits to the word. - word = (word << 6) | (byte) bits; - - // For every 4 chars of input, we accumulate 24 bits of output. Emit 3 bytes. - inCount++; - if (inCount % 4 == 0) { - out[outCount++] = (byte) (word >> 16); - out[outCount++] = (byte) (word >> 8); - out[outCount++] = (byte) word; - } - } - - int lastWordChars = inCount % 4; - if (lastWordChars == 1) { - // We read 1 char followed by "===". But 6 bits is a truncated byte! Fail. - return null; - } else if (lastWordChars == 2) { - // We read 2 chars followed by "==". Emit 1 byte with 8 of those 12 bits. - word = word << 12; - out[outCount++] = (byte) (word >> 16); - } else if (lastWordChars == 3) { - // We read 3 chars, followed by "=". Emit 2 bytes for 16 of those 18 bits. - word = word << 6; - out[outCount++] = (byte) (word >> 16); - out[outCount++] = (byte) (word >> 8); - } - - // If we sized our out array perfectly, we're done. - if (outCount == out.length) return out; - - // Copy the decoded bytes to a new, right-sized array. - byte[] prefix = new byte[outCount]; - System.arraycopy(out, 0, prefix, 0, outCount); - return prefix; - } - - private static final byte[] MAP = new byte[]{ - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', - '5', '6', '7', '8', '9', '+', '/' - }; - - public static String encode(byte[] in) { - int length = (in.length + 2) * 4 / 3; - byte[] out = new byte[length]; - int index = 0, end = in.length - in.length % 3; - for (int i = 0; i < end; i += 3) { - out[index++] = MAP[(in[i] & 0xff) >> 2]; - out[index++] = MAP[((in[i] & 0x03) << 4) | ((in[i + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[i + 1] & 0x0f) << 2) | ((in[i + 2] & 0xff) >> 6)]; - out[index++] = MAP[(in[i + 2] & 0x3f)]; - } - switch (in.length % 3) { - case 1: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[(in[end] & 0x03) << 4]; - out[index++] = '='; - out[index++] = '='; - break; - case 2: - out[index++] = MAP[(in[end] & 0xff) >> 2]; - out[index++] = MAP[((in[end] & 0x03) << 4) | ((in[end + 1] & 0xff) >> 4)]; - out[index++] = MAP[((in[end + 1] & 0x0f) << 2)]; - out[index++] = '='; - break; - } - try { - return new String(out, 0, index, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new AssertionError(e); - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Buffer.java b/contentstack/src/main/java/com/contentstack/okio/Buffer.java deleted file mode 100755 index dbb7c125..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Buffer.java +++ /dev/null @@ -1,1032 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static com.contentstack.okio.Util.checkOffsetAndCount; -import static com.contentstack.okio.Util.reverseBytesLong; - -/** - * A collection of bytes in memory. - * - *

Moving data from one buffer to another is fast. Instead - * of copying bytes from one place in memory to another, this class just changes - * ownership of the underlying byte arrays. - * - *

This buffer grows with your data. Just like ArrayList, - * each buffer starts small. It consumes only the memory it needs to. - * - *

This buffer pools its byte arrays. When you allocate a - * byte array in Java, the runtime must zero-fill the requested array before - * returning it to you. Even if you're going to write over that space anyway. - * This class avoids zero-fill and GC churn by pooling byte arrays. - */ -public final class Buffer implements BufferedSource, BufferedSink, Cloneable { - Segment head; - long size; - - public Buffer() { - } - - /** - * Returns the number of bytes currently in this buffer. - */ - public long size() { - return size; - } - - @Override - public Buffer buffer() { - return this; - } - - @Override - public OutputStream outputStream() { - return new OutputStream() { - @Override - public void write(int b) { - writeByte((byte) b); - } - - @Override - public void write(byte[] data, int offset, int byteCount) { - Buffer.this.write(data, offset, byteCount); - } - - @Override - public void flush() { - } - - @Override - public void close() { - } - - @Override - public String toString() { - return this + ".outputStream()"; - } - }; - } - - @Override - public Buffer emitCompleteSegments() { - return this; // Nowhere to emit to! - } - - @Override - public boolean exhausted() { - return size == 0; - } - - @Override - public void require(long byteCount) throws EOFException { - if (this.size < byteCount) throw new EOFException(); - } - - @Override - public boolean request(long byteCount) throws IOException { - return size >= byteCount; - } - - @Override - public InputStream inputStream() { - return new InputStream() { - @Override - public int read() { - if (size > 0) return readByte() & 0xff; - return -1; - } - - @Override - public int read(byte[] sink, int offset, int byteCount) { - return Buffer.this.read(sink, offset, byteCount); - } - - @Override - public int available() { - return (int) Math.min(size, Integer.MAX_VALUE); - } - - @Override - public void close() { - } - - @Override - public String toString() { - return Buffer.this + ".inputStream()"; - } - }; - } - - /** - * Copy the contents of this to {@code out}. - */ - public Buffer copyTo(OutputStream out) throws IOException { - return copyTo(out, 0, size); - } - - /** - * Copy {@code byteCount} bytes from this, starting at {@code offset}, to - * {@code out}. - */ - public Buffer copyTo(OutputStream out, long offset, long byteCount) throws IOException { - if (out == null) throw new IllegalArgumentException("out == null"); - checkOffsetAndCount(size, offset, byteCount); - if (byteCount == 0) return this; - - // Skip segments that we aren't copying from. - Segment s = head; - for (; offset >= (s.limit - s.pos); s = s.next) { - offset -= (s.limit - s.pos); - } - - // Copy from one segment at a time. - for (; byteCount > 0; s = s.next) { - int pos = (int) (s.pos + offset); - int toWrite = (int) Math.min(s.limit - pos, byteCount); - out.write(s.data, pos, toWrite); - byteCount -= toWrite; - offset = 0; - } - - return this; - } - - /** - * Write the contents of this to {@code out}. - */ - public Buffer writeTo(OutputStream out) throws IOException { - return writeTo(out, size); - } - - /** - * Write {@code byteCount} bytes from this to {@code out}. - */ - public Buffer writeTo(OutputStream out, long byteCount) throws IOException { - if (out == null) throw new IllegalArgumentException("out == null"); - checkOffsetAndCount(size, 0, byteCount); - - Segment s = head; - while (byteCount > 0) { - int toCopy = (int) Math.min(byteCount, s.limit - s.pos); - out.write(s.data, s.pos, toCopy); - - s.pos += toCopy; - size -= toCopy; - byteCount -= toCopy; - - if (s.pos == s.limit) { - Segment toRecycle = s; - head = s = toRecycle.pop(); - SegmentPool.INSTANCE.recycle(toRecycle); - } - } - - return this; - } - - /** - * Read and exhaust bytes from {@code in} to this. - */ - public Buffer readFrom(InputStream in) throws IOException { - readFrom(in, Long.MAX_VALUE, true); - return this; - } - - /** - * Read {@code byteCount} bytes from {@code in} to this. - */ - public Buffer readFrom(InputStream in, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - readFrom(in, byteCount, false); - return this; - } - - private void readFrom(InputStream in, long byteCount, boolean forever) throws IOException { - if (in == null) throw new IllegalArgumentException("in == null"); - while (byteCount > 0 || forever) { - Segment tail = writableSegment(1); - int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit); - int bytesRead = in.read(tail.data, tail.limit, maxToCopy); - if (bytesRead == -1) { - if (forever) return; - throw new EOFException(); - } - tail.limit += bytesRead; - size += bytesRead; - byteCount -= bytesRead; - } - } - - /** - * Returns the number of bytes in segments that are not writable. This is the - * number of bytes that can be flushed immediately to an underlying sink - * without harming throughput. - */ - public long completeSegmentByteCount() { - long result = size; - if (result == 0) return 0; - - // Omit the tail if it's still writable. - Segment tail = head.prev; - if (tail.limit < Segment.SIZE) { - result -= tail.limit - tail.pos; - } - - return result; - } - - @Override - public byte readByte() { - if (size == 0) throw new IllegalStateException("size == 0"); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - byte[] data = segment.data; - byte b = data[pos++]; - size -= 1; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return b; - } - - /** - * Returns the byte at {@code pos}. - */ - public byte getByte(long pos) { - checkOffsetAndCount(size, pos, 1); - for (Segment s = head; true; s = s.next) { - int segmentByteCount = s.limit - s.pos; - if (pos < segmentByteCount) return s.data[s.pos + (int) pos]; - pos -= segmentByteCount; - } - } - - @Override - public short readShort() { - if (size < 2) throw new IllegalStateException("size < 2: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the short is split across multiple segments, delegate to readByte(). - if (limit - pos < 2) { - int s = (readByte() & 0xff) << 8 - | (readByte() & 0xff); - return (short) s; - } - - byte[] data = segment.data; - int s = (data[pos++] & 0xff) << 8 - | (data[pos++] & 0xff); - size -= 2; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return (short) s; - } - - @Override - public int readInt() { - if (size < 4) throw new IllegalStateException("size < 4: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the int is split across multiple segments, delegate to readByte(). - if (limit - pos < 4) { - return (readByte() & 0xff) << 24 - | (readByte() & 0xff) << 16 - | (readByte() & 0xff) << 8 - | (readByte() & 0xff); - } - - byte[] data = segment.data; - int i = (data[pos++] & 0xff) << 24 - | (data[pos++] & 0xff) << 16 - | (data[pos++] & 0xff) << 8 - | (data[pos++] & 0xff); - size -= 4; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return i; - } - - @Override - public long readLong() { - if (size < 8) throw new IllegalStateException("size < 8: " + size); - - Segment segment = head; - int pos = segment.pos; - int limit = segment.limit; - - // If the long is split across multiple segments, delegate to readInt(). - if (limit - pos < 8) { - return (readInt() & 0xffffffffL) << 32 - | (readInt() & 0xffffffffL); - } - - byte[] data = segment.data; - long v = (data[pos++] & 0xffL) << 56 - | (data[pos++] & 0xffL) << 48 - | (data[pos++] & 0xffL) << 40 - | (data[pos++] & 0xffL) << 32 - | (data[pos++] & 0xffL) << 24 - | (data[pos++] & 0xffL) << 16 - | (data[pos++] & 0xffL) << 8 - | (data[pos++] & 0xffL); - size -= 8; - - if (pos == limit) { - head = segment.pop(); - SegmentPool.INSTANCE.recycle(segment); - } else { - segment.pos = pos; - } - - return v; - } - - @Override - public short readShortLe() { - return Util.reverseBytesShort(readShort()); - } - - @Override - public int readIntLe() { - return Util.reverseBytesInt(readInt()); - } - - @Override - public long readLongLe() { - return Util.reverseBytesLong(readLong()); - } - - @Override - public ByteString readByteString() { - return new ByteString(readByteArray()); - } - - @Override - public ByteString readByteString(long byteCount) throws EOFException { - return new ByteString(readByteArray(byteCount)); - } - - @Override - public void readFully(Buffer sink, long byteCount) throws EOFException { - if (size < byteCount) { - sink.write(this, size); // Exhaust ourselves. - throw new EOFException(); - } - sink.write(this, byteCount); - } - - @Override - public long readAll(Sink sink) throws IOException { - long byteCount = size; - if (byteCount > 0) { - sink.write(this, byteCount); - } - return byteCount; - } - - @Override - public String readUtf8() { - try { - return readString(size, Util.UTF_8); - } catch (EOFException e) { - throw new AssertionError(e); - } - } - - @Override - public String readUtf8(long byteCount) throws EOFException { - return readString(byteCount, Util.UTF_8); - } - - @Override - public String readString(Charset charset) { - try { - return readString(size, charset); - } catch (EOFException e) { - throw new AssertionError(e); - } - } - - @Override - public String readString(long byteCount, Charset charset) throws EOFException { - checkOffsetAndCount(size, 0, byteCount); - if (charset == null) throw new IllegalArgumentException("charset == null"); - if (byteCount > Integer.MAX_VALUE) { - throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount); - } - if (byteCount == 0) return ""; - - Segment head = this.head; - if (head.pos + byteCount > head.limit) { - // If the string spans multiple segments, delegate to readBytes(). - return new String(readByteArray(byteCount), charset); - } - - String result = new String(head.data, head.pos, (int) byteCount, charset); - head.pos += byteCount; - size -= byteCount; - - if (head.pos == head.limit) { - this.head = head.pop(); - SegmentPool.INSTANCE.recycle(head); - } - - return result; - } - - @Override - public String readUtf8Line() throws EOFException { - long newline = indexOf((byte) '\n'); - - if (newline == -1) { - return size != 0 ? readUtf8(size) : null; - } - - return readUtf8Line(newline); - } - - @Override - public String readUtf8LineStrict() throws EOFException { - long newline = indexOf((byte) '\n'); - if (newline == -1) throw new EOFException(); - return readUtf8Line(newline); - } - - String readUtf8Line(long newline) throws EOFException { - if (newline > 0 && getByte(newline - 1) == '\r') { - // Read everything until '\r\n', then skip the '\r\n'. - String result = readUtf8((newline - 1)); - skip(2); - return result; - - } else { - // Read everything until '\n', then skip the '\n'. - String result = readUtf8(newline); - skip(1); - return result; - } - } - - @Override - public byte[] readByteArray() { - try { - return readByteArray(size); - } catch (EOFException e) { - throw new AssertionError(e); - } - } - - @Override - public byte[] readByteArray(long byteCount) throws EOFException { - checkOffsetAndCount(this.size, 0, byteCount); - if (byteCount > Integer.MAX_VALUE) { - throw new IllegalArgumentException("byteCount > Integer.MAX_VALUE: " + byteCount); - } - - byte[] result = new byte[(int) byteCount]; - readFully(result); - return result; - } - - @Override - public int read(byte[] sink) { - return read(sink, 0, sink.length); - } - - @Override - public void readFully(byte[] sink) throws EOFException { - int offset = 0; - while (offset < sink.length) { - int read = read(sink, offset, sink.length - offset); - if (read == -1) throw new EOFException(); - offset += read; - } - } - - @Override - public int read(byte[] sink, int offset, int byteCount) { - checkOffsetAndCount(sink.length, offset, byteCount); - - Segment s = this.head; - if (s == null) return -1; - int toCopy = Math.min(byteCount, s.limit - s.pos); - System.arraycopy(s.data, s.pos, sink, offset, toCopy); - - s.pos += toCopy; - this.size -= toCopy; - - if (s.pos == s.limit) { - this.head = s.pop(); - SegmentPool.INSTANCE.recycle(s); - } - - return toCopy; - } - - /** - * Discards all bytes in this buffer. Calling this method when you're done - * with a buffer will return its segments to the pool. - */ - public void clear() { - try { - skip(size); - } catch (EOFException e) { - throw new AssertionError(e); - } - } - - /** - * Discards {@code byteCount} bytes from the head of this buffer. - */ - @Override - public void skip(long byteCount) throws EOFException { - while (byteCount > 0) { - if (head == null) throw new EOFException(); - - int toSkip = (int) Math.min(byteCount, head.limit - head.pos); - size -= toSkip; - byteCount -= toSkip; - head.pos += toSkip; - - if (head.pos == head.limit) { - Segment toRecycle = head; - head = toRecycle.pop(); - SegmentPool.INSTANCE.recycle(toRecycle); - } - } - } - - @Override - public Buffer write(ByteString byteString) { - if (byteString == null) throw new IllegalArgumentException("byteString == null"); - return write(byteString.data, 0, byteString.data.length); - } - - @Override - public Buffer writeUtf8(String string) { - if (string == null) throw new IllegalArgumentException("string == null"); - return writeString(string, Util.UTF_8); - } - - @Override - public Buffer writeString(String string, Charset charset) { - if (string == null) throw new IllegalArgumentException("string == null"); - if (charset == null) throw new IllegalArgumentException("charset == null"); - byte[] data = string.getBytes(charset); - return write(data, 0, data.length); - } - - @Override - public Buffer write(byte[] source) { - if (source == null) throw new IllegalArgumentException("source == null"); - return write(source, 0, source.length); - } - - @Override - public Buffer write(byte[] source, int offset, int byteCount) { - if (source == null) throw new IllegalArgumentException("source == null"); - checkOffsetAndCount(source.length, offset, byteCount); - - int limit = offset + byteCount; - while (offset < limit) { - Segment tail = writableSegment(1); - - int toCopy = Math.min(limit - offset, Segment.SIZE - tail.limit); - System.arraycopy(source, offset, tail.data, tail.limit, toCopy); - - offset += toCopy; - tail.limit += toCopy; - } - - this.size += byteCount; - return this; - } - - @Override - public long writeAll(Source source) throws IOException { - if (source == null) throw new IllegalArgumentException("source == null"); - long totalBytesRead = 0; - for (long readCount; (readCount = source.read(this, Segment.SIZE)) != -1; ) { - totalBytesRead += readCount; - } - return totalBytesRead; - } - - @Override - public Buffer writeByte(int b) { - Segment tail = writableSegment(1); - tail.data[tail.limit++] = (byte) b; - size += 1; - return this; - } - - @Override - public Buffer writeShort(int s) { - Segment tail = writableSegment(2); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((s >>> 8) & 0xff); - data[limit++] = (byte) (s & 0xff); - tail.limit = limit; - size += 2; - return this; - } - - @Override - public Buffer writeShortLe(int s) { - return writeShort(Util.reverseBytesShort((short) s)); - } - - @Override - public Buffer writeInt(int i) { - Segment tail = writableSegment(4); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((i >>> 24) & 0xff); - data[limit++] = (byte) ((i >>> 16) & 0xff); - data[limit++] = (byte) ((i >>> 8) & 0xff); - data[limit++] = (byte) (i & 0xff); - tail.limit = limit; - size += 4; - return this; - } - - @Override - public Buffer writeIntLe(int i) { - return writeInt(Util.reverseBytesInt(i)); - } - - @Override - public Buffer writeLong(long v) { - Segment tail = writableSegment(8); - byte[] data = tail.data; - int limit = tail.limit; - data[limit++] = (byte) ((v >>> 56L) & 0xff); - data[limit++] = (byte) ((v >>> 48L) & 0xff); - data[limit++] = (byte) ((v >>> 40L) & 0xff); - data[limit++] = (byte) ((v >>> 32L) & 0xff); - data[limit++] = (byte) ((v >>> 24L) & 0xff); - data[limit++] = (byte) ((v >>> 16L) & 0xff); - data[limit++] = (byte) ((v >>> 8L) & 0xff); - data[limit++] = (byte) (v & 0xff); - tail.limit = limit; - size += 8; - return this; - } - - @Override - public Buffer writeLongLe(long v) { - return writeLong(reverseBytesLong(v)); - } - - /** - * Returns a tail segment that we can write at least {@code minimumCapacity} - * bytes to, creating it if necessary. - */ - Segment writableSegment(int minimumCapacity) { - if (minimumCapacity < 1 || minimumCapacity > Segment.SIZE) - throw new IllegalArgumentException(); - - if (head == null) { - head = SegmentPool.INSTANCE.take(); // Acquire a first segment. - return head.next = head.prev = head; - } - - Segment tail = head.prev; - if (tail.limit + minimumCapacity > Segment.SIZE) { - tail = tail.push(SegmentPool.INSTANCE.take()); // Append a new empty segment to fill up. - } - return tail; - } - - @Override - public void write(Buffer source, long byteCount) { - // Move bytes from the head of the source buffer to the tail of this buffer - // while balancing two conflicting goals: don't waste CPU and don't waste - // memory. - // - // - // Don't waste CPU (ie. don't copy data around). - // - // Copying large amounts of data is expensive. Instead, we prefer to - // reassign entire segments from one buffer to the other. - // - // - // Don't waste memory. - // - // As an invariant, adjacent pairs of segments in a buffer should be at - // least 50% full, except for the head segment and the tail segment. - // - // The head segment cannot maintain the invariant because the application is - // consuming bytes from this segment, decreasing its level. - // - // The tail segment cannot maintain the invariant because the application is - // producing bytes, which may require new nearly-empty tail segments to be - // appended. - // - // - // Moving segments between buffers - // - // When writing one buffer to another, we prefer to reassign entire segments - // over copying bytes into their most compact form. Suppose we have a buffer - // with these segment levels [91%, 61%]. If we append a buffer with a - // single [72%] segment, that yields [91%, 61%, 72%]. No bytes are copied. - // - // Or suppose we have a buffer with these segment levels: [100%, 2%], and we - // want to append it to a buffer with these segment levels [99%, 3%]. This - // operation will yield the following segments: [100%, 2%, 99%, 3%]. That - // is, we do not spend time copying bytes around to achieve more efficient - // memory use like [100%, 100%, 4%]. - // - // When combining buffers, we will compact adjacent buffers when their - // combined level doesn't exceed 100%. For example, when we start with - // [100%, 40%] and append [30%, 80%], the result is [100%, 70%, 80%]. - // - // - // Splitting segments - // - // Occasionally we write only part of a source buffer to a sink buffer. For - // example, given a sink [51%, 91%], we may want to write the first 30% of - // a source [92%, 82%] to it. To simplify, we first transform the source to - // an equivalent buffer [30%, 62%, 82%] and then move the head segment, - // yielding sink [51%, 91%, 30%] and source [62%, 82%]. - - if (source == null) throw new IllegalArgumentException("source == null"); - if (source == this) throw new IllegalArgumentException("source == this"); - checkOffsetAndCount(source.size, 0, byteCount); - - while (byteCount > 0) { - // Is a prefix of the source's head segment all that we need to move? - if (byteCount < (source.head.limit - source.head.pos)) { - Segment tail = head != null ? head.prev : null; - if (tail == null || byteCount + (tail.limit - tail.pos) > Segment.SIZE) { - // We're going to need another segment. Split the source's head - // segment in two, then move the first of those two to this buffer. - source.head = source.head.split((int) byteCount); - } else { - // Our existing segments are sufficient. Move bytes from source's head to our tail. - source.head.writeTo(tail, (int) byteCount); - source.size -= byteCount; - this.size += byteCount; - return; - } - } - - // Remove the source's head segment and append it to our tail. - Segment segmentToMove = source.head; - long movedByteCount = segmentToMove.limit - segmentToMove.pos; - source.head = segmentToMove.pop(); - if (head == null) { - head = segmentToMove; - head.next = head.prev = head; - } else { - Segment tail = head.prev; - tail = tail.push(segmentToMove); - tail.compact(); - } - source.size -= movedByteCount; - this.size += movedByteCount; - byteCount -= movedByteCount; - } - } - - @Override - public long read(Buffer sink, long byteCount) { - if (sink == null) throw new IllegalArgumentException("sink == null"); - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (this.size == 0) return -1L; - if (byteCount > this.size) byteCount = this.size; - sink.write(this, byteCount); - return byteCount; - } - - @Override - public long indexOf(byte b) { - return indexOf(b, 0); - } - - /** - * Returns the index of {@code b} in this at or beyond {@code fromIndex}, or - * -1 if this buffer does not contain {@code b} in that range. - */ - @Override - public long indexOf(byte b, long fromIndex) { - if (fromIndex < 0) throw new IllegalArgumentException("fromIndex < 0"); - - Segment s = head; - if (s == null) return -1L; - long offset = 0L; - do { - int segmentByteCount = s.limit - s.pos; - if (fromIndex >= segmentByteCount) { - fromIndex -= segmentByteCount; - } else { - byte[] data = s.data; - for (long pos = s.pos + fromIndex, limit = s.limit; pos < limit; pos++) { - if (data[(int) pos] == b) return offset + pos - s.pos; - } - fromIndex = 0; - } - offset += segmentByteCount; - s = s.next; - } while (s != head); - return -1L; - } - - @Override - public long indexOfElement(ByteString targetBytes) { - return indexOfElement(targetBytes, 0); - } - - @Override - public long indexOfElement(ByteString targetBytes, long fromIndex) { - if (fromIndex < 0) throw new IllegalArgumentException("fromIndex < 0"); - - Segment s = head; - if (s == null) return -1L; - long offset = 0L; - byte[] toFind = targetBytes.data; - do { - int segmentByteCount = s.limit - s.pos; - if (fromIndex >= segmentByteCount) { - fromIndex -= segmentByteCount; - } else { - byte[] data = s.data; - for (long pos = s.pos + fromIndex, limit = s.limit; pos < limit; pos++) { - byte b = data[(int) pos]; - for (byte targetByte : toFind) { - if (b == targetByte) return offset + pos - s.pos; - } - } - fromIndex = 0; - } - offset += segmentByteCount; - s = s.next; - } while (s != head); - return -1L; - } - - @Override - public void flush() { - } - - @Override - public void close() { - } - - @Override - public Timeout timeout() { - return Timeout.NONE; - } - - /** - * For testing. This returns the sizes of the segments in this buffer. - */ - List segmentSizes() { - if (head == null) return Collections.emptyList(); - List result = new ArrayList(); - result.add(head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - result.add(s.limit - s.pos); - } - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof Buffer)) return false; - Buffer that = (Buffer) o; - if (size != that.size) return false; - if (size == 0) return true; // Both buffers are empty. - - Segment sa = this.head; - Segment sb = that.head; - int posA = sa.pos; - int posB = sb.pos; - - for (long pos = 0, count; pos < size; pos += count) { - count = Math.min(sa.limit - posA, sb.limit - posB); - - for (int i = 0; i < count; i++) { - if (sa.data[posA++] != sb.data[posB++]) return false; - } - - if (posA == sa.limit) { - sa = sa.next; - posA = sa.pos; - } - - if (posB == sb.limit) { - sb = sb.next; - posB = sb.pos; - } - } - - return true; - } - - @Override - public int hashCode() { - Segment s = head; - if (s == null) return 0; - int result = 1; - do { - for (int pos = s.pos, limit = s.limit; pos < limit; pos++) { - result = 31 * result + s.data[pos]; - } - s = s.next; - } while (s != head); - return result; - } - - @Override - public String toString() { - if (size == 0) { - return "Buffer[size=0]"; - } - - if (size <= 16) { - ByteString data = clone().readByteString(); - return String.format("Buffer[size=%s data=%s]", size, data.hex()); - } - - try { - MessageDigest md5 = MessageDigest.getInstance("MD5"); - md5.update(head.data, head.pos, head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - md5.update(s.data, s.pos, s.limit - s.pos); - } - return String.format("Buffer[size=%s md5=%s]", - size, ByteString.of(md5.digest()).hex()); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(); - } - } - - /** - * Returns a deep copy of this buffer. - */ - @Override - public Buffer clone() { - Buffer result = new Buffer(); - if (size == 0) return result; - - result.write(head.data, head.pos, head.limit - head.pos); - for (Segment s = head.next; s != head; s = s.next) { - result.write(s.data, s.pos, s.limit - s.pos); - } - - return result; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/BufferedSink.java b/contentstack/src/main/java/com/contentstack/okio/BufferedSink.java deleted file mode 100755 index 3994ea7d..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/BufferedSink.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -/** - * A sink that keeps a buffer internally so that callers can do small writes - * without a performance penalty. - */ -public interface BufferedSink extends Sink { - /** - * Returns this sink's internal buffer. - */ - Buffer buffer(); - - BufferedSink write(ByteString byteString) throws IOException; - - /** - * Like {@link OutputStream#write(byte[])}, this writes a complete byte array to - * this sink. - */ - BufferedSink write(byte[] source) throws IOException; - - /** - * Like {@link OutputStream#write(byte[], int, int)}, this writes {@code byteCount} - * bytes of {@code source}, starting at {@code offset}. - */ - BufferedSink write(byte[] source, int offset, int byteCount) throws IOException; - - /** - * Removes all bytes from {@code source} and appends them to this. Returns the - * number of bytes read which will be 0 if {@code source} is exhausted. - */ - long writeAll(Source source) throws IOException; - - /** - * Encodes {@code string} in UTF-8 and writes it to this sink. - */ - BufferedSink writeUtf8(String string) throws IOException; - - /** - * Encodes {@code string} in {@code charset} and writes it to this sink. - */ - BufferedSink writeString(String string, Charset charset) throws IOException; - - /** - * Writes a byte to this sink. - */ - BufferedSink writeByte(int b) throws IOException; - - /** - * Writes a big-endian short to this sink using two bytes. - */ - BufferedSink writeShort(int s) throws IOException; - - /** - * Writes a little-endian short to this sink using two bytes. - */ - BufferedSink writeShortLe(int s) throws IOException; - - /** - * Writes a big-endian int to this sink using four bytes. - */ - BufferedSink writeInt(int i) throws IOException; - - /** - * Writes a little-endian int to this sink using four bytes. - */ - BufferedSink writeIntLe(int i) throws IOException; - - /** - * Writes a big-endian long to this sink using eight bytes. - */ - BufferedSink writeLong(long v) throws IOException; - - /** - * Writes a little-endian long to this sink using eight bytes. - */ - BufferedSink writeLongLe(long v) throws IOException; - - /** - * Writes complete segments to this sink. Like {@link #flush}, but weaker. - */ - BufferedSink emitCompleteSegments() throws IOException; - - /** - * Returns an output stream that writes to this sink. - */ - OutputStream outputStream(); -} diff --git a/contentstack/src/main/java/com/contentstack/okio/BufferedSource.java b/contentstack/src/main/java/com/contentstack/okio/BufferedSource.java deleted file mode 100755 index 28ce0b9e..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/BufferedSource.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; - -/** - * A source that keeps a buffer internally so that callers can do small reads - * without a performance penalty. It also allows clients to read ahead, - * buffering as much as necessary before consuming input. - */ -public interface BufferedSource extends Source { - /** - * Returns this source's internal buffer. - */ - Buffer buffer(); - - /** - * Returns true if there are no more bytes in this source. This will block - * until there are bytes to read or the source is definitely exhausted. - */ - boolean exhausted() throws IOException; - - /** - * Returns when the buffer contains at least {@code byteCount} bytes. Throws - * an {@link java.io.EOFException} if the source is exhausted before the - * required bytes can be read. - */ - void require(long byteCount) throws IOException; - - /** - * Returns true when the buffer contains at least {@code byteCount} bytes, - * expanding it as necessary. Returns false if the source is exhausted before - * the requested bytes can be read. - */ - boolean request(long byteCount) throws IOException; - - /** - * Removes a byte from this source and returns it. - */ - byte readByte() throws IOException; - - /** - * Removes two bytes from this source and returns a big-endian short. - */ - short readShort() throws IOException; - - /** - * Removes two bytes from this source and returns a little-endian short. - */ - short readShortLe() throws IOException; - - /** - * Removes four bytes from this source and returns a big-endian int. - */ - int readInt() throws IOException; - - /** - * Removes four bytes from this source and returns a little-endian int. - */ - int readIntLe() throws IOException; - - /** - * Removes eight bytes from this source and returns a big-endian long. - */ - long readLong() throws IOException; - - /** - * Removes eight bytes from this source and returns a little-endian long. - */ - long readLongLe() throws IOException; - - /** - * Reads and discards {@code byteCount} bytes from this source. Throws an - * {@link java.io.EOFException} if the source is exhausted before the - * requested bytes can be skipped. - */ - void skip(long byteCount) throws IOException; - - /** - * Removes all bytes bytes from this and returns them as a byte string. - */ - ByteString readByteString() throws IOException; - - /** - * Removes {@code byteCount} bytes from this and returns them as a byte string. - */ - ByteString readByteString(long byteCount) throws IOException; - - /** - * Removes all bytes from this and returns them as a byte array. - */ - byte[] readByteArray() throws IOException; - - /** - * Removes {@code byteCount} bytes from this and returns them as a byte array. - */ - byte[] readByteArray(long byteCount) throws IOException; - - /** - * Removes up to {@code sink.length} bytes from this and copies them into {@code sink}. - * Returns the number of bytes read, or -1 if this source is exhausted. - */ - int read(byte[] sink) throws IOException; - - /** - * Removes exactly {@code sink.length} bytes from this and copies them into {@code sink}. - * Throws an {@link java.io.EOFException} if the requested number of bytes cannot be read. - */ - void readFully(byte[] sink) throws IOException; - - /** - * Removes up to {@code byteCount} bytes from this and copies them into {@code sink} at - * {@code offset}. Returns the number of bytes read, or -1 if this source is exhausted. - */ - int read(byte[] sink, int offset, int byteCount) throws IOException; - - /** - * Removes exactly {@code byteCount} bytes from this and appends them to - * {@code sink}. Throws an {@link java.io.EOFException} if the requested - * number of bytes cannot be read. - */ - void readFully(Buffer sink, long byteCount) throws IOException; - - /** - * Removes all bytes from this and appends them to {@code sink}. Returns the - * total number of bytes written to {@code sink} which will be 0 if this is - * exhausted. - */ - long readAll(Sink sink) throws IOException; - - /** - * Removes all bytes from this, decodes them as UTF-8, and returns the string. - */ - String readUtf8() throws IOException; - - /** - * Removes {@code byteCount} bytes from this, decodes them as UTF-8, and - * returns the string. - */ - String readUtf8(long byteCount) throws IOException; - - /** - * Removes and returns characters up to but not including the next line break. - * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are - * not included in the result. - * - *

On the end of the stream this method returns null, just - * like {@link java.io.BufferedReader}. If the source doesn't end with a line - * break then an implicit line break is assumed. Null is returned once the - * source is exhausted. Use this for human-generated data, where a trailing - * line break is optional. - */ - String readUtf8Line() throws IOException; - - /** - * Removes and returns characters up to but not including the next line break. - * A line break is either {@code "\n"} or {@code "\r\n"}; these characters are - * not included in the result. - * - *

On the end of the stream this method throws. Every call - * must consume either '\r\n' or '\n'. If these characters are absent in the - * stream, an {@link java.io.EOFException} is thrown. Use this for - * machine-generated data where a missing line break implies truncated input. - */ - String readUtf8LineStrict() throws IOException; - - /** - * Removes all bytes from this, decodes them as {@code charset}, and returns - * the string. - */ - String readString(Charset charset) throws IOException; - - /** - * Removes {@code byteCount} bytes from this, decodes them as {@code charset}, - * and returns the string. - */ - String readString(long byteCount, Charset charset) throws IOException; - - /** - * Returns the index of the first {@code b} in the buffer. This expands the - * buffer as necessary until {@code b} is found. This reads an unbounded - * number of bytes into the buffer. Returns -1 if the stream is exhausted - * before the requested byte is found. - */ - long indexOf(byte b) throws IOException; - - /** - * Returns the index of the first {@code b} in the buffer at or after {@code - * fromIndex}. This expands the buffer as necessary until {@code b} is found. - * This reads an unbounded number of bytes into the buffer. Returns -1 if the - * stream is exhausted before the requested byte is found. - */ - long indexOf(byte b, long fromIndex) throws IOException; - - /** - * Returns the index of the first byte in {@code targetBytes} in the buffer. - * This expands the buffer as necessary until a target byte is found. This - * reads an unbounded number of bytes into the buffer. Returns -1 if the - * stream is exhausted before the requested byte is found. - */ - long indexOfElement(ByteString targetBytes) throws IOException; - - /** - * Returns the index of the first byte in {@code targetBytes} in the buffer - * at or after {@code fromIndex}. This expands the buffer as necessary until - * a target byte is found. This reads an unbounded number of bytes into the - * buffer. Returns -1 if the stream is exhausted before the requested byte is - * found. - */ - long indexOfElement(ByteString targetBytes, long fromIndex) throws IOException; - - /** - * Returns an input stream that reads from this source. - */ - InputStream inputStream(); -} diff --git a/contentstack/src/main/java/com/contentstack/okio/ByteString.java b/contentstack/src/main/java/com/contentstack/okio/ByteString.java deleted file mode 100755 index 3bab9ef8..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/ByteString.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2014 Square Inc. - * - * 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.contentstack.okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.io.Serializable; -import java.lang.reflect.Field; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Arrays; - -/** - * An immutable sequence of bytes. - * - *

Full disclosure: this class provides untrusted input and - * output streams with raw access to the underlying byte array. A hostile - * stream implementation could keep a reference to the mutable byte string, - * violating the immutable guarantee of this class. For this reason a byte - * string's immutability guarantee cannot be relied upon for security in applets - * and other environments that run both trusted and untrusted code in the same - * process. - */ -public final class ByteString implements Serializable { - private static final char[] HEX_DIGITS = - {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - private static final long serialVersionUID = 1L; - - /** - * A singleton empty {@code ByteString}. - */ - public static final ByteString EMPTY = ByteString.of(); - - final byte[] data; - private transient int hashCode; // Lazily computed; 0 if unknown. - private transient String utf8; // Lazily computed. - - ByteString(byte[] data) { - this.data = data; // Trusted internal constructor doesn't clone data. - } - - /** - * Returns a new byte string containing a clone of the bytes of {@code data}. - */ - public static ByteString of(byte... data) { - if (data == null) throw new IllegalArgumentException("data == null"); - return new ByteString(data.clone()); - } - - /** - * Returns a new byte string containing a copy of {@code byteCount} bytes of {@code data} starting - * at {@code offset}. - */ - public static ByteString of(byte[] data, int offset, int byteCount) { - if (data == null) throw new IllegalArgumentException("data == null"); - Util.checkOffsetAndCount(data.length, offset, byteCount); - - byte[] copy = new byte[byteCount]; - System.arraycopy(data, offset, copy, 0, byteCount); - return new ByteString(copy); - } - - /** - * Returns a new byte string containing the {@code UTF-8} bytes of {@code s}. - */ - public static ByteString encodeUtf8(String s) { - if (s == null) throw new IllegalArgumentException("s == null"); - ByteString byteString = new ByteString(s.getBytes(Util.UTF_8)); - byteString.utf8 = s; - return byteString; - } - - /** - * Constructs a new {@code String} by decoding the bytes as {@code UTF-8}. - */ - public String utf8() { - String result = utf8; - // We don't care if we double-allocate in racy code. - return result != null ? result : (utf8 = new String(data, Util.UTF_8)); - } - - /** - * Returns this byte string encoded as Base64. In violation of the - * RFC, the returned string does not wrap lines at 76 columns. - */ - public String base64() { - return Base64.encode(data); - } - - /** - * Decodes the Base64-encoded bytes and returns their value as a byte string. - * Returns null if {@code base64} is not a Base64-encoded sequence of bytes. - */ - public static ByteString decodeBase64(String base64) { - if (base64 == null) throw new IllegalArgumentException("base64 == null"); - byte[] decoded = Base64.decode(base64); - return decoded != null ? new ByteString(decoded) : null; - } - - /** - * Returns this byte string encoded in hexadecimal. - */ - public String hex() { - char[] result = new char[data.length * 2]; - int c = 0; - for (byte b : data) { - result[c++] = HEX_DIGITS[(b >> 4) & 0xf]; - result[c++] = HEX_DIGITS[b & 0xf]; - } - return new String(result); - } - - /** - * Decodes the hex-encoded bytes and returns their value a byte string. - */ - public static ByteString decodeHex(String hex) { - if (hex == null) throw new IllegalArgumentException("hex == null"); - if (hex.length() % 2 != 0) - throw new IllegalArgumentException("Unexpected hex string: " + hex); - - byte[] result = new byte[hex.length() / 2]; - for (int i = 0; i < result.length; i++) { - int d1 = decodeHexDigit(hex.charAt(i * 2)) << 4; - int d2 = decodeHexDigit(hex.charAt(i * 2 + 1)); - result[i] = (byte) (d1 + d2); - } - return of(result); - } - - private static int decodeHexDigit(char c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - throw new IllegalArgumentException("Unexpected hex digit: " + c); - } - - /** - * Reads {@code count} bytes from {@code in} and returns the result. - * - * @throws java.io.EOFException if {@code in} has fewer than {@code count} - * bytes to read. - */ - public static ByteString read(InputStream in, int byteCount) throws IOException { - if (in == null) throw new IllegalArgumentException("in == null"); - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - - byte[] result = new byte[byteCount]; - for (int offset = 0, read; offset < byteCount; offset += read) { - read = in.read(result, offset, byteCount - offset); - if (read == -1) throw new EOFException(); - } - return new ByteString(result); - } - - /** - * Returns a byte string equal to this byte string, but with the bytes 'A' - * through 'Z' replaced with the corresponding byte in 'a' through 'z'. - * Returns this byte string if it contains no bytes in 'A' through 'Z'. - */ - public ByteString toAsciiLowercase() { - // Search for an uppercase character. If we don't find one, return this. - for (int i = 0; i < data.length; i++) { - byte c = data[i]; - if (c < 'A' || c > 'Z') continue; - - // If we reach this point, this string is not not lowercase. Create and - // return a new byte string. - byte[] lowercase = data.clone(); - lowercase[i++] = (byte) (c - ('A' - 'a')); - for (; i < lowercase.length; i++) { - c = lowercase[i]; - if (c < 'A' || c > 'Z') continue; - lowercase[i] = (byte) (c - ('A' - 'a')); - } - return new ByteString(lowercase); - } - return this; - } - - /** - * Returns a byte string equal to this byte string, but with the bytes 'a' - * through 'z' replaced with the corresponding byte in 'A' through 'Z'. - * Returns this byte string if it contains no bytes in 'a' through 'z'. - */ - public ByteString toAsciiUppercase() { - // Search for an lowercase character. If we don't find one, return this. - for (int i = 0; i < data.length; i++) { - byte c = data[i]; - if (c < 'a' || c > 'z') continue; - - // If we reach this point, this string is not not uppercase. Create and - // return a new byte string. - byte[] lowercase = data.clone(); - lowercase[i++] = (byte) (c - ('a' - 'A')); - for (; i < lowercase.length; i++) { - c = lowercase[i]; - if (c < 'a' || c > 'z') continue; - lowercase[i] = (byte) (c - ('a' - 'A')); - } - return new ByteString(lowercase); - } - return this; - } - - /** - * Returns the byte at {@code pos}. - */ - public byte getByte(int pos) { - return data[pos]; - } - - /** - * Returns the number of bytes in this ByteString. - */ - public int size() { - return data.length; - } - - /** - * Returns a byte array containing a copy of the bytes in this {@code ByteString}. - */ - public byte[] toByteArray() { - return data.clone(); - } - - /** - * Writes the contents of this byte string to {@code out}. - */ - public void write(OutputStream out) throws IOException { - if (out == null) throw new IllegalArgumentException("out == null"); - out.write(data); - } - - @Override - public boolean equals(Object o) { - return o == this || o instanceof ByteString && Arrays.equals(((ByteString) o).data, data); - } - - @Override - public int hashCode() { - int result = hashCode; - return result != 0 ? result : (hashCode = Arrays.hashCode(data)); - } - - @Override - public String toString() { - if (data.length == 0) { - return "ByteString[size=0]"; - } - - if (data.length <= 16) { - return String.format("ByteString[size=%s data=%s]", data.length, hex()); - } - - try { - return String.format("ByteString[size=%s md5=%s]", data.length, - ByteString.of(MessageDigest.getInstance("MD5").digest(data)).hex()); - } catch (NoSuchAlgorithmException e) { - throw new AssertionError(); - } - } - - private void readObject(ObjectInputStream in) throws IOException { - int dataLength = in.readInt(); - ByteString byteString = ByteString.read(in, dataLength); - try { - Field field = ByteString.class.getDeclaredField("data"); - field.setAccessible(true); - field.set(this, byteString.data); - } catch (NoSuchFieldException e) { - throw new AssertionError(); - } catch (IllegalAccessException e) { - throw new AssertionError(); - } - } - - private void writeObject(ObjectOutputStream out) throws IOException { - out.writeInt(data.length); - out.write(data); - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/DeflaterSink.java b/contentstack/src/main/java/com/contentstack/okio/DeflaterSink.java deleted file mode 100755 index 22e541ec..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/DeflaterSink.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import android.annotation.SuppressLint; - -import java.io.IOException; -import java.util.zip.Deflater; - -/** - * A sink that uses DEFLATE to - * compress data written to another source. - * - *

Sync flush

- * Aggressive flushing of this stream may result in reduced compression. Each - * call to {@link #flush} immediately compresses all currently-buffered data; - * this early compression may be less effective than compression performed - * without flushing. - * - *

This is equivalent to using {@link Deflater} with the sync flush option. - * This class does not offer any partial flush mechanism. For best performance, - * only call {@link #flush} when application behavior requires it. - */ -public final class DeflaterSink implements Sink { - private final BufferedSink sink; - private final Deflater deflater; - private boolean closed; - - public DeflaterSink(Sink sink, Deflater deflater) { - this(Okio.buffer(sink), deflater); - } - - /** - * This package-private constructor shares a buffer with its trusted caller. - * In general we can't share a BufferedSource because the deflater holds input - * bytes until they are inflated. - */ - DeflaterSink(BufferedSink sink, Deflater deflater) { - if (sink == null) throw new IllegalArgumentException("source == null"); - if (deflater == null) throw new IllegalArgumentException("inflater == null"); - this.sink = sink; - this.deflater = deflater; - } - - @Override - public void write(Buffer source, long byteCount) - throws IOException { - Util.checkOffsetAndCount(source.size, 0, byteCount); - while (byteCount > 0) { - // Share bytes from the head segment of 'source' with the deflater. - Segment head = source.head; - int toDeflate = (int) Math.min(byteCount, head.limit - head.pos); - deflater.setInput(head.data, head.pos, toDeflate); - - // Deflate those bytes into sink. - deflate(false); - - // Mark those bytes as read. - source.size -= toDeflate; - head.pos += toDeflate; - if (head.pos == head.limit) { - source.head = head.pop(); - SegmentPool.INSTANCE.recycle(head); - } - - byteCount -= toDeflate; - } - } - - @SuppressLint("NewApi") - private void deflate(boolean syncFlush) throws IOException { - Buffer buffer = sink.buffer(); - while (true) { - Segment s = buffer.writableSegment(1); - - // The 4-parameter overload of deflate() doesn't exist in the RI until - // Java 1.7, and is public (although with @hide) on Android since 2.3. - // The @hide tag means that this code won't compile against the Android - // 2.3 SDK, but it will run fine there. - int deflated = syncFlush - ? deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit/*, Deflater.SYNC_FLUSH*/) - : deflater.deflate(s.data, s.limit, Segment.SIZE - s.limit); - - if (deflated > 0) { - s.limit += deflated; - buffer.size += deflated; - sink.emitCompleteSegments(); - } else if (deflater.needsInput()) { - return; - } - } - } - - @Override - public void flush() throws IOException { - deflate(true); - sink.flush(); - } - - void finishDeflate() throws IOException { - deflater.finish(); - deflate(false); - } - - @Override - public void close() throws IOException { - if (closed) return; - - // Emit deflated data to the underlying sink. If this fails, we still need - // to close the deflater and the sink; otherwise we risk leaking resources. - Throwable thrown = null; - try { - finishDeflate(); - } catch (Throwable e) { - thrown = e; - } - - try { - deflater.end(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - - try { - sink.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - closed = true; - - if (thrown != null) Util.sneakyRethrow(thrown); - } - - @Override - public Timeout timeout() { - return sink.timeout(); - } - - @Override - public String toString() { - return "DeflaterSink(" + sink + ")"; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/ForwardingSink.java b/contentstack/src/main/java/com/contentstack/okio/ForwardingSink.java deleted file mode 100755 index f57cda51..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/ForwardingSink.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; - -/** - * A {@link Sink} which forwards calls to another. Useful for subclassing. - */ -public abstract class ForwardingSink implements Sink { - private final Sink delegate; - - public ForwardingSink(Sink delegate) { - if (delegate == null) throw new IllegalArgumentException("delegate == null"); - this.delegate = delegate; - } - - /** - * {@link Sink} to which this instance is delegating. - */ - public final Sink delegate() { - return delegate; - } - - @Override - public void write(Buffer source, long byteCount) throws IOException { - delegate.write(source, byteCount); - } - - @Override - public void flush() throws IOException { - delegate.flush(); - } - - @Override - public Timeout timeout() { - return delegate.timeout(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "(" + delegate.toString() + ")"; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/ForwardingSource.java b/contentstack/src/main/java/com/contentstack/okio/ForwardingSource.java deleted file mode 100755 index b11251df..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/ForwardingSource.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; - -/** - * A {@link Source} which forwards calls to another. Useful for subclassing. - */ -public abstract class ForwardingSource implements Source { - private final Source delegate; - - public ForwardingSource(Source delegate) { - if (delegate == null) throw new IllegalArgumentException("delegate == null"); - this.delegate = delegate; - } - - /** - * {@link Source} to which this instance is delegating. - */ - public final Source delegate() { - return delegate; - } - - @Override - public long read(Buffer sink, long byteCount) throws IOException { - return delegate.read(sink, byteCount); - } - - @Override - public Timeout timeout() { - return delegate.timeout(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public String toString() { - return getClass().getSimpleName() + "(" + delegate.toString() + ")"; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/GzipSink.java b/contentstack/src/main/java/com/contentstack/okio/GzipSink.java deleted file mode 100755 index 90d6b34c..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/GzipSink.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.util.zip.CRC32; -import java.util.zip.Deflater; - -import static java.util.zip.Deflater.DEFAULT_COMPRESSION; - -/** - * A sink that uses GZIP to - * compress written data to another sink. - * - *

Sync flush

- * Aggressive flushing of this stream may result in reduced compression. Each - * call to {@link #flush} immediately compresses all currently-buffered data; - * this early compression may be less effective than compression performed - * without flushing. - * - *

This is equivalent to using {@link Deflater} with the sync flush option. - * This class does not offer any partial flush mechanism. For best performance, - * only call {@link #flush} when application behavior requires it. - */ -public final class GzipSink implements Sink { - /** - * Sink into which the GZIP format is written. - */ - private final BufferedSink sink; - - /** - * The deflater used to compress the body. - */ - private final Deflater deflater; - - /** - * The deflater sink takes care of moving data between decompressed source and - * compressed sink buffers. - */ - private final DeflaterSink deflaterSink; - - private boolean closed; - - /** - * Checksum calculated for the compressed body. - */ - private final CRC32 crc = new CRC32(); - - public GzipSink(Sink sink) { - if (sink == null) throw new IllegalArgumentException("sink == null"); - this.deflater = new Deflater(DEFAULT_COMPRESSION, true /* No wrap */); - this.sink = Okio.buffer(sink); - this.deflaterSink = new DeflaterSink(this.sink, deflater); - - writeHeader(); - } - - @Override - public void write(Buffer source, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (byteCount == 0) return; - - updateCrc(source, byteCount); - deflaterSink.write(source, byteCount); - } - - @Override - public void flush() throws IOException { - deflaterSink.flush(); - } - - @Override - public Timeout timeout() { - return sink.timeout(); - } - - @Override - public void close() throws IOException { - if (closed) return; - - // This method delegates to the DeflaterSink for finishing the deflate process - // but keeps responsibility for releasing the deflater's resources. This is - // necessary because writeFooter needs to query the proccessed byte count which - // only works when the defalter is still open. - - Throwable thrown = null; - try { - deflaterSink.finishDeflate(); - writeFooter(); - } catch (Throwable e) { - thrown = e; - } - - try { - deflater.end(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - - try { - sink.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - closed = true; - - if (thrown != null) Util.sneakyRethrow(thrown); - } - - private void writeHeader() { - // Write the Gzip header directly into the buffer for the sink to avoid handling IOException. - Buffer buffer = this.sink.buffer(); - buffer.writeShort(0x1f8b); // Two-byte Gzip ID. - buffer.writeByte(0x08); // 8 == Deflate compression method. - buffer.writeByte(0x00); // No flags. - buffer.writeInt(0x00); // No modification time. - buffer.writeByte(0x00); // No extra flags. - buffer.writeByte(0x00); // No OS. - } - - private void writeFooter() throws IOException { - sink.writeIntLe((int) crc.getValue()); // CRC of original data. - sink.writeIntLe(deflater.getTotalIn()); // Length of original data. - } - - /** - * Updates the CRC with the given bytes. - */ - private void updateCrc(Buffer buffer, long byteCount) { - for (Segment head = buffer.head; byteCount > 0; head = head.next) { - int segmentLength = (int) Math.min(byteCount, head.limit - head.pos); - crc.update(head.data, head.pos, segmentLength); - byteCount -= segmentLength; - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/GzipSource.java b/contentstack/src/main/java/com/contentstack/okio/GzipSource.java deleted file mode 100755 index 57e3089b..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/GzipSource.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.EOFException; -import java.io.IOException; -import java.util.zip.CRC32; -import java.util.zip.Inflater; - -/** - * A source that uses GZIP to - * decompress data read from another source. - */ -public final class GzipSource implements Source { - private static final byte FHCRC = 1; - private static final byte FEXTRA = 2; - private static final byte FNAME = 3; - private static final byte FCOMMENT = 4; - - private static final byte SECTION_HEADER = 0; - private static final byte SECTION_BODY = 1; - private static final byte SECTION_TRAILER = 2; - private static final byte SECTION_DONE = 3; - - /** - * The current section. Always progresses forward. - */ - private int section = SECTION_HEADER; - - /** - * Our source should yield a GZIP header (which we consume directly), followed - * by deflated bytes (which we consume via an InflaterSource), followed by a - * GZIP trailer (which we also consume directly). - */ - private final BufferedSource source; - - /** - * The inflater used to decompress the deflated body. - */ - private final Inflater inflater; - - /** - * The inflater source takes care of moving data between compressed source and - * decompressed sink buffers. - */ - private final InflaterSource inflaterSource; - - /** - * Checksum used to check both the GZIP header and decompressed body. - */ - private final CRC32 crc = new CRC32(); - - public GzipSource(Source source) { - if (source == null) throw new IllegalArgumentException("source == null"); - this.inflater = new Inflater(true); - this.source = Okio.buffer(source); - this.inflaterSource = new InflaterSource(this.source, inflater); - } - - @Override - public long read(Buffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (byteCount == 0) return 0; - - // If we haven't consumed the header, we must consume it before anything else. - if (section == SECTION_HEADER) { - consumeHeader(); - section = SECTION_BODY; - } - - // Attempt to read at least a byte of the body. If we do, we're done. - if (section == SECTION_BODY) { - long offset = sink.size; - long result = inflaterSource.read(sink, byteCount); - if (result != -1) { - updateCrc(sink, offset, result); - return result; - } - section = SECTION_TRAILER; - } - - // The body is exhausted; time to read the trailer. We always consume the - // trailer before returning a -1 exhausted result; that way if you read to - // the end of a GzipSource you guarantee that the CRC has been checked. - if (section == SECTION_TRAILER) { - consumeTrailer(); - section = SECTION_DONE; - - // Gzip streams self-terminate: they return -1 before their underlying - // source returns -1. Here we attempt to force the underlying stream to - // return -1 which may trigger it to release its resources. If it doesn't - // return -1, then our Gzip data finished prematurely! - if (!source.exhausted()) { - throw new IOException("gzip finished without exhausting source"); - } - } - - return -1; - } - - private void consumeHeader() throws IOException { - // Read the 10-byte header. We peek at the flags byte first so we know if we - // need to CRC the entire header. Then we read the magic ID1ID2 sequence. - // We can skip everything else in the first 10 bytes. - // +---+---+---+---+---+---+---+---+---+---+ - // |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) - // +---+---+---+---+---+---+---+---+---+---+ - source.require(10); - byte flags = source.buffer().getByte(3); - boolean fhcrc = ((flags >> FHCRC) & 1) == 1; - if (fhcrc) updateCrc(source.buffer(), 0, 10); - - short id1id2 = source.readShort(); - checkEqual("ID1ID2", (short) 0x1f8b, id1id2); - source.skip(8); - - // Skip optional extra fields. - // +---+---+=================================+ - // | XLEN |...XLEN bytes of "extra field"...| (more-->) - // +---+---+=================================+ - if (((flags >> FEXTRA) & 1) == 1) { - source.require(2); - if (fhcrc) updateCrc(source.buffer(), 0, 2); - int xlen = source.buffer().readShortLe(); - source.require(xlen); - if (fhcrc) updateCrc(source.buffer(), 0, xlen); - source.skip(xlen); - } - - // Skip an optional 0-terminated name. - // +=========================================+ - // |...original file name, zero-terminated...| (more-->) - // +=========================================+ - if (((flags >> FNAME) & 1) == 1) { - long index = source.indexOf((byte) 0); - if (index == -1) throw new EOFException(); - if (fhcrc) updateCrc(source.buffer(), 0, index + 1); - source.skip(index + 1); - } - - // Skip an optional 0-terminated comment. - // +===================================+ - // |...file comment, zero-terminated...| (more-->) - // +===================================+ - if (((flags >> FCOMMENT) & 1) == 1) { - long index = source.indexOf((byte) 0); - if (index == -1) throw new EOFException(); - if (fhcrc) updateCrc(source.buffer(), 0, index + 1); - source.skip(index + 1); - } - - // Confirm the optional header CRC. - // +---+---+ - // | CRC16 | - // +---+---+ - if (fhcrc) { - checkEqual("FHCRC", source.readShortLe(), (short) crc.getValue()); - crc.reset(); - } - } - - private void consumeTrailer() throws IOException { - // Read the eight-byte trailer. Confirm the body's CRC and size. - // +---+---+---+---+---+---+---+---+ - // | CRC32 | ISIZE | - // +---+---+---+---+---+---+---+---+ - checkEqual("CRC", source.readIntLe(), (int) crc.getValue()); - checkEqual("ISIZE", source.readIntLe(), inflater.getTotalOut()); - } - - @Override - public Timeout timeout() { - return source.timeout(); - } - - @Override - public void close() throws IOException { - inflaterSource.close(); - } - - /** - * Updates the CRC with the given bytes. - */ - private void updateCrc(Buffer buffer, long offset, long byteCount) { - // Skip segments that we aren't checksumming. - Segment s = buffer.head; - for (; offset >= (s.limit - s.pos); s = s.next) { - offset -= (s.limit - s.pos); - } - - // Checksum one segment at a time. - for (; byteCount > 0; s = s.next) { - int pos = (int) (s.pos + offset); - int toUpdate = (int) Math.min(s.limit - pos, byteCount); - crc.update(s.data, pos, toUpdate); - byteCount -= toUpdate; - offset = 0; - } - } - - private void checkEqual(String name, int expected, int actual) throws IOException { - if (actual != expected) { - throw new IOException(String.format( - "%s: actual 0x%08x != expected 0x%08x", name, actual, expected)); - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/InflaterSource.java b/contentstack/src/main/java/com/contentstack/okio/InflaterSource.java deleted file mode 100755 index c04d0d9d..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/InflaterSource.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.EOFException; -import java.io.IOException; -import java.util.zip.DataFormatException; -import java.util.zip.Inflater; - -/** - * A source that uses DEFLATE - * to decompress data read from another source. - */ -public final class InflaterSource implements Source { - private final BufferedSource source; - private final Inflater inflater; - - /** - * When we call Inflater.setInput(), the inflater keeps our byte array until - * it needs input again. This tracks how many bytes the inflater is currently - * holding on to. - */ - private int bufferBytesHeldByInflater; - private boolean closed; - - public InflaterSource(Source source, Inflater inflater) { - this(Okio.buffer(source), inflater); - } - - /** - * This package-private constructor shares a buffer with its trusted caller. - * In general we can't share a BufferedSource because the inflater holds input - * bytes until they are inflated. - */ - InflaterSource(BufferedSource source, Inflater inflater) { - if (source == null) throw new IllegalArgumentException("source == null"); - if (inflater == null) throw new IllegalArgumentException("inflater == null"); - this.source = source; - this.inflater = inflater; - } - - @Override - public long read( - Buffer sink, long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (closed) throw new IllegalStateException("closed"); - if (byteCount == 0) return 0; - - while (true) { - boolean sourceExhausted = refill(); - - // Decompress the inflater's compressed data into the sink. - try { - Segment tail = sink.writableSegment(1); - int bytesInflated = inflater.inflate(tail.data, tail.limit, Segment.SIZE - tail.limit); - if (bytesInflated > 0) { - tail.limit += bytesInflated; - sink.size += bytesInflated; - return bytesInflated; - } - if (inflater.finished() || inflater.needsDictionary()) { - releaseInflatedBytes(); - return -1; - } - if (sourceExhausted) throw new EOFException("source exhausted prematurely"); - } catch (DataFormatException e) { - throw new IOException(e); - } - } - } - - /** - * Refills the inflater with compressed data if it needs input. (And only if - * it needs input). Returns true if the inflater required input but the source - * was exhausted. - */ - public boolean refill() throws IOException { - if (!inflater.needsInput()) return false; - - releaseInflatedBytes(); - if (inflater.getRemaining() != 0) throw new IllegalStateException("?"); - - // If there are compressed bytes in the source, assign them to the inflater. - if (source.exhausted()) return true; - - // Assign buffer bytes to the inflater. - Segment head = source.buffer().head; - bufferBytesHeldByInflater = head.limit - head.pos; - inflater.setInput(head.data, head.pos, bufferBytesHeldByInflater); - return false; - } - - /** - * When the inflater has processed compressed data, remove it from the buffer. - */ - private void releaseInflatedBytes() throws IOException { - if (bufferBytesHeldByInflater == 0) return; - int toRelease = bufferBytesHeldByInflater - inflater.getRemaining(); - bufferBytesHeldByInflater -= toRelease; - source.skip(toRelease); - } - - @Override - public Timeout timeout() { - return source.timeout(); - } - - @Override - public void close() throws IOException { - if (closed) return; - inflater.end(); - closed = true; - source.close(); - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Okio.java b/contentstack/src/main/java/com/contentstack/okio/Okio.java deleted file mode 100755 index 8014efc5..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Okio.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.Socket; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.contentstack.okio.Util.checkOffsetAndCount; - -/** - * Essential APIs for working with Okio. - */ -public final class Okio { - private static final Logger logger = Logger.getLogger(Okio.class.getName()); - - private Okio() { - } - - /** - * Returns a new source that buffers reads from {@code source}. The returned - * source will perform bulk reads into its in-memory buffer. Use this wherever - * you read a source to get an ergonomic and efficient access to data. - */ - public static BufferedSource buffer(Source source) { - if (source == null) throw new IllegalArgumentException("source == null"); - return new RealBufferedSource(source); - } - - /** - * Returns a new sink that buffers writes to {@code sink}. The returned sink - * will batch writes to {@code sink}. Use this wherever you write to a sink to - * get an ergonomic and efficient access to data. - */ - public static BufferedSink buffer(Sink sink) { - if (sink == null) throw new IllegalArgumentException("sink == null"); - return new RealBufferedSink(sink); - } - - /** - * Returns a sink that writes to {@code out}. - */ - public static Sink sink(final OutputStream out) { - return sink(out, new Timeout()); - } - - private static Sink sink(final OutputStream out, final Timeout timeout) { - if (out == null) throw new IllegalArgumentException("out == null"); - if (timeout == null) throw new IllegalArgumentException("timeout == null"); - - return new Sink() { - @Override - public void write(Buffer source, long byteCount) throws IOException { - checkOffsetAndCount(source.size, 0, byteCount); - while (byteCount > 0) { - timeout.throwIfReached(); - Segment head = source.head; - int toCopy = (int) Math.min(byteCount, head.limit - head.pos); - out.write(head.data, head.pos, toCopy); - - head.pos += toCopy; - byteCount -= toCopy; - source.size -= toCopy; - - if (head.pos == head.limit) { - source.head = head.pop(); - SegmentPool.INSTANCE.recycle(head); - } - } - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - out.close(); - } - - @Override - public Timeout timeout() { - return timeout; - } - - @Override - public String toString() { - return "sink(" + out + ")"; - } - }; - } - - /** - * Returns a sink that writes to {@code socket}. Prefer this over {@link - * #sink(OutputStream)} because this method honors timeouts. When the socket - * write times out, the socket is asynchronously closed by a watchdog thread. - */ - public static Sink sink(final Socket socket) throws IOException { - if (socket == null) throw new IllegalArgumentException("socket == null"); - AsyncTimeout timeout = timeout(socket); - Sink sink = sink(socket.getOutputStream(), timeout); - return timeout.sink(sink); - } - - /** - * Returns a source that reads from {@code in}. - */ - public static Source source(final InputStream in) { - return source(in, new Timeout()); - } - - private static Source source(final InputStream in, final Timeout timeout) { - if (in == null) throw new IllegalArgumentException("in == null"); - if (timeout == null) throw new IllegalArgumentException("timeout == null"); - - return new Source() { - @Override - public long read(Buffer sink, long byteCount) throws IOException { - if (byteCount < 0) - throw new IllegalArgumentException("byteCount < 0: " + byteCount); - timeout.throwIfReached(); - Segment tail = sink.writableSegment(1); - int maxToCopy = (int) Math.min(byteCount, Segment.SIZE - tail.limit); - int bytesRead = in.read(tail.data, tail.limit, maxToCopy); - if (bytesRead == -1) return -1; - tail.limit += bytesRead; - sink.size += bytesRead; - return bytesRead; - } - - @Override - public void close() throws IOException { - in.close(); - } - - @Override - public Timeout timeout() { - return timeout; - } - - @Override - public String toString() { - return "source(" + in + ")"; - } - }; - } - - /** - * Returns a source that reads from {@code file}. - */ - public static Source source(File file) throws FileNotFoundException { - if (file == null) throw new IllegalArgumentException("file == null"); - return source(new FileInputStream(file)); - } - - /** Returns a source that reads from {@code path}. */ - // Should only be invoked on Java 7+. - /*public static Source source(android.graphics.Path path, OpenOption... options) throws IOException { - if (path == null) throw new IllegalArgumentException("path == null"); - return source(android.provider.MediaStore.Files.newInputStream(path, options)); - }*/ - - /** - * Returns a sink that writes to {@code file}. - */ - public static Sink sink(File file) throws FileNotFoundException { - if (file == null) throw new IllegalArgumentException("file == null"); - return sink(new FileOutputStream(file)); - } - - /** - * Returns a sink that appends to {@code file}. - */ - public static Sink appendingSink(File file) throws FileNotFoundException { - if (file == null) throw new IllegalArgumentException("file == null"); - return sink(new FileOutputStream(file, true)); - } - - /** Returns a sink that writes to {@code path}. */// Should only be invoked on Java 7+. - /* public static Sink sink(android.graphics.Path path, OpenOption... options) throws IOException { - if (path == null) throw new IllegalArgumentException("path == null"); - return sink(android.provider.MediaStore.Files.newOutputStream(path, options)); - }*/ - - /** - * Returns a source that reads from {@code socket}. Prefer this over {@link - * #source(InputStream)} because this method honors timeouts. When the socket - * read times out, the socket is asynchronously closed by a watchdog thread. - */ - public static Source source(final Socket socket) throws IOException { - if (socket == null) throw new IllegalArgumentException("socket == null"); - AsyncTimeout timeout = timeout(socket); - Source source = source(socket.getInputStream(), timeout); - return timeout.source(source); - } - - private static AsyncTimeout timeout(final Socket socket) { - return new AsyncTimeout() { - @Override - protected void timedOut() { - try { - socket.close(); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to close timed out socket " + socket, e); - } - } - }; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/RealBufferedSink.java b/contentstack/src/main/java/com/contentstack/okio/RealBufferedSink.java deleted file mode 100755 index f151b965..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/RealBufferedSink.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; - -final class RealBufferedSink implements BufferedSink { - public final Buffer buffer; - public final Sink sink; - private boolean closed; - - public RealBufferedSink(Sink sink, Buffer buffer) { - if (sink == null) throw new IllegalArgumentException("sink == null"); - this.buffer = buffer; - this.sink = sink; - } - - public RealBufferedSink(Sink sink) { - this(sink, new Buffer()); - } - - @Override - public Buffer buffer() { - return buffer; - } - - @Override - public void write(Buffer source, long byteCount) - throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source, byteCount); - emitCompleteSegments(); - } - - @Override - public BufferedSink write(ByteString byteString) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(byteString); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeUtf8(String string) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeUtf8(string); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeString(String string, Charset charset) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeString(string, charset); - return emitCompleteSegments(); - } - - @Override - public BufferedSink write(byte[] source) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source); - return emitCompleteSegments(); - } - - @Override - public BufferedSink write(byte[] source, int offset, int byteCount) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.write(source, offset, byteCount); - return emitCompleteSegments(); - } - - @Override - public long writeAll(Source source) throws IOException { - if (source == null) throw new IllegalArgumentException("source == null"); - long totalBytesRead = 0; - for (long readCount; (readCount = source.read(buffer, Segment.SIZE)) != -1; ) { - totalBytesRead += readCount; - emitCompleteSegments(); - } - return totalBytesRead; - } - - @Override - public BufferedSink writeByte(int b) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeByte(b); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeShort(int s) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeShort(s); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeShortLe(int s) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeShortLe(s); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeInt(int i) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeInt(i); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeIntLe(int i) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeIntLe(i); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeLong(long v) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeLong(v); - return emitCompleteSegments(); - } - - @Override - public BufferedSink writeLongLe(long v) throws IOException { - if (closed) throw new IllegalStateException("closed"); - buffer.writeLongLe(v); - return emitCompleteSegments(); - } - - @Override - public BufferedSink emitCompleteSegments() throws IOException { - if (closed) throw new IllegalStateException("closed"); - long byteCount = buffer.completeSegmentByteCount(); - if (byteCount > 0) sink.write(buffer, byteCount); - return this; - } - - @Override - public OutputStream outputStream() { - return new OutputStream() { - @Override - public void write(int b) throws IOException { - if (closed) throw new IOException("closed"); - buffer.writeByte((byte) b); - emitCompleteSegments(); - } - - @Override - public void write(byte[] data, int offset, int byteCount) throws IOException { - if (closed) throw new IOException("closed"); - buffer.write(data, offset, byteCount); - emitCompleteSegments(); - } - - @Override - public void flush() throws IOException { - // For backwards compatibility, a flush() on a closed stream is a no-op. - if (!closed) { - RealBufferedSink.this.flush(); - } - } - - @Override - public void close() throws IOException { - RealBufferedSink.this.close(); - } - - @Override - public String toString() { - return RealBufferedSink.this + ".outputStream()"; - } - }; - } - - @Override - public void flush() throws IOException { - if (closed) throw new IllegalStateException("closed"); - if (buffer.size > 0) { - sink.write(buffer, buffer.size); - } - sink.flush(); - } - - @Override - public void close() throws IOException { - if (closed) return; - - // Emit buffered data to the underlying sink. If this fails, we still need - // to close the sink; otherwise we risk leaking resources. - Throwable thrown = null; - try { - if (buffer.size > 0) { - sink.write(buffer, buffer.size); - } - } catch (Throwable e) { - thrown = e; - } - - try { - sink.close(); - } catch (Throwable e) { - if (thrown == null) thrown = e; - } - closed = true; - - if (thrown != null) Util.sneakyRethrow(thrown); - } - - @Override - public Timeout timeout() { - return sink.timeout(); - } - - @Override - public String toString() { - return "buffer(" + sink + ")"; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/RealBufferedSource.java b/contentstack/src/main/java/com/contentstack/okio/RealBufferedSource.java deleted file mode 100755 index c8d73bfb..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/RealBufferedSource.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.Charset; - -final class RealBufferedSource implements BufferedSource { - public final Buffer buffer; - public final Source source; - private boolean closed; - - public RealBufferedSource(Source source, Buffer buffer) { - if (source == null) throw new IllegalArgumentException("source == null"); - this.buffer = buffer; - this.source = source; - } - - public RealBufferedSource(Source source) { - this(source, new Buffer()); - } - - @Override - public Buffer buffer() { - return buffer; - } - - @Override - public long read(Buffer sink, long byteCount) throws IOException { - if (sink == null) throw new IllegalArgumentException("sink == null"); - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (closed) throw new IllegalStateException("closed"); - - if (buffer.size == 0) { - long read = source.read(buffer, Segment.SIZE); - if (read == -1) return -1; - } - - long toRead = Math.min(byteCount, buffer.size); - return buffer.read(sink, toRead); - } - - @Override - public boolean exhausted() throws IOException { - if (closed) throw new IllegalStateException("closed"); - return buffer.exhausted() && source.read(buffer, Segment.SIZE) == -1; - } - - @Override - public void require(long byteCount) throws IOException { - if (!request(byteCount)) throw new EOFException(); - } - - @Override - public boolean request(long byteCount) throws IOException { - if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); - if (closed) throw new IllegalStateException("closed"); - while (buffer.size < byteCount) { - if (source.read(buffer, Segment.SIZE) == -1) return false; - } - return true; - } - - @Override - public byte readByte() throws IOException { - require(1); - return buffer.readByte(); - } - - @Override - public ByteString readByteString() throws IOException { - buffer.writeAll(source); - return buffer.readByteString(); - } - - @Override - public ByteString readByteString(long byteCount) throws IOException { - require(byteCount); - return buffer.readByteString(byteCount); - } - - @Override - public byte[] readByteArray() throws IOException { - buffer.writeAll(source); - return buffer.readByteArray(); - } - - @Override - public byte[] readByteArray(long byteCount) throws IOException { - require(byteCount); - return buffer.readByteArray(byteCount); - } - - @Override - public int read(byte[] sink) throws IOException { - return read(sink, 0, sink.length); - } - - @Override - public void readFully(byte[] sink) throws IOException { - try { - require(sink.length); - } catch (EOFException e) { - // The underlying source is exhausted. Copy the bytes we got before rethrowing. - int offset = 0; - while (buffer.size > 0) { - int read = buffer.read(sink, offset, (int) buffer.size - offset); - if (read == -1) throw new AssertionError(); - offset += read; - } - throw e; - } - buffer.readFully(sink); - } - - @Override - public int read(byte[] sink, int offset, int byteCount) throws IOException { - Util.checkOffsetAndCount(sink.length, offset, byteCount); - - if (buffer.size == 0) { - long read = source.read(buffer, Segment.SIZE); - if (read == -1) return -1; - } - - int toRead = (int) Math.min(byteCount, buffer.size); - return buffer.read(sink, offset, toRead); - } - - @Override - public void readFully(Buffer sink, long byteCount) throws IOException { - try { - require(byteCount); - } catch (EOFException e) { - // The underlying source is exhausted. Copy the bytes we got before rethrowing. - sink.writeAll(buffer); - throw e; - } - buffer.readFully(sink, byteCount); - } - - @Override - public long readAll(Sink sink) throws IOException { - if (sink == null) throw new IllegalArgumentException("sink == null"); - - long totalBytesWritten = 0; - while (source.read(buffer, Segment.SIZE) != -1) { - long emitByteCount = buffer.completeSegmentByteCount(); - if (emitByteCount > 0) { - totalBytesWritten += emitByteCount; - sink.write(buffer, emitByteCount); - } - } - if (buffer.size() > 0) { - totalBytesWritten += buffer.size(); - sink.write(buffer, buffer.size()); - } - return totalBytesWritten; - } - - @Override - public String readUtf8() throws IOException { - buffer.writeAll(source); - return buffer.readUtf8(); - } - - @Override - public String readUtf8(long byteCount) throws IOException { - require(byteCount); - return buffer.readUtf8(byteCount); - } - - @Override - public String readString(Charset charset) throws IOException { - if (charset == null) throw new IllegalArgumentException("charset == null"); - - buffer.writeAll(source); - return buffer.readString(charset); - } - - @Override - public String readString(long byteCount, Charset charset) throws IOException { - require(byteCount); - if (charset == null) throw new IllegalArgumentException("charset == null"); - return buffer.readString(byteCount, charset); - } - - @Override - public String readUtf8Line() throws IOException { - long newline = indexOf((byte) '\n'); - - if (newline == -1) { - return buffer.size != 0 ? readUtf8(buffer.size) : null; - } - - return buffer.readUtf8Line(newline); - } - - @Override - public String readUtf8LineStrict() throws IOException { - long newline = indexOf((byte) '\n'); - if (newline == -1L) throw new EOFException(); - return buffer.readUtf8Line(newline); - } - - @Override - public short readShort() throws IOException { - require(2); - return buffer.readShort(); - } - - @Override - public short readShortLe() throws IOException { - require(2); - return buffer.readShortLe(); - } - - @Override - public int readInt() throws IOException { - require(4); - return buffer.readInt(); - } - - @Override - public int readIntLe() throws IOException { - require(4); - return buffer.readIntLe(); - } - - @Override - public long readLong() throws IOException { - require(8); - return buffer.readLong(); - } - - @Override - public long readLongLe() throws IOException { - require(8); - return buffer.readLongLe(); - } - - @Override - public void skip(long byteCount) throws IOException { - if (closed) throw new IllegalStateException("closed"); - while (byteCount > 0) { - if (buffer.size == 0 && source.read(buffer, Segment.SIZE) == -1) { - throw new EOFException(); - } - long toSkip = Math.min(byteCount, buffer.size()); - buffer.skip(toSkip); - byteCount -= toSkip; - } - } - - @Override - public long indexOf(byte b) throws IOException { - return indexOf(b, 0); - } - - @Override - public long indexOf(byte b, long fromIndex) throws IOException { - if (closed) throw new IllegalStateException("closed"); - while (fromIndex >= buffer.size) { - if (source.read(buffer, Segment.SIZE) == -1) return -1L; - } - long index; - while ((index = buffer.indexOf(b, fromIndex)) == -1) { - fromIndex = buffer.size; - if (source.read(buffer, Segment.SIZE) == -1) return -1L; - } - return index; - } - - @Override - public long indexOfElement(ByteString targetBytes) throws IOException { - return indexOfElement(targetBytes, 0); - } - - @Override - public long indexOfElement(ByteString targetBytes, long fromIndex) throws IOException { - if (closed) throw new IllegalStateException("closed"); - while (fromIndex >= buffer.size) { - if (source.read(buffer, Segment.SIZE) == -1) return -1L; - } - long index; - while ((index = buffer.indexOfElement(targetBytes, fromIndex)) == -1) { - fromIndex = buffer.size; - if (source.read(buffer, Segment.SIZE) == -1) return -1L; - } - return index; - } - - @Override - public InputStream inputStream() { - return new InputStream() { - @Override - public int read() throws IOException { - if (closed) throw new IOException("closed"); - if (buffer.size == 0) { - long count = source.read(buffer, Segment.SIZE); - if (count == -1) return -1; - } - return buffer.readByte() & 0xff; - } - - @Override - public int read(byte[] data, int offset, int byteCount) throws IOException { - if (closed) throw new IOException("closed"); - Util.checkOffsetAndCount(data.length, offset, byteCount); - - if (buffer.size == 0) { - long count = source.read(buffer, Segment.SIZE); - if (count == -1) return -1; - } - - return buffer.read(data, offset, byteCount); - } - - @Override - public int available() throws IOException { - if (closed) throw new IOException("closed"); - return (int) Math.min(buffer.size, Integer.MAX_VALUE); - } - - @Override - public void close() throws IOException { - RealBufferedSource.this.close(); - } - - @Override - public String toString() { - return RealBufferedSource.this + ".inputStream()"; - } - }; - } - - @Override - public void close() throws IOException { - if (closed) return; - closed = true; - source.close(); - buffer.clear(); - } - - @Override - public Timeout timeout() { - return source.timeout(); - } - - @Override - public String toString() { - return "buffer(" + source + ")"; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Segment.java b/contentstack/src/main/java/com/contentstack/okio/Segment.java deleted file mode 100755 index 6be3aa97..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Segment.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -/** - * A segment of a buffer. - * - *

Each segment in a buffer is a circularly-linked list node referencing - * the following and preceding segments in the buffer. - * - *

Each segment in the pool is a singly-linked list node referencing the rest - * of segments in the pool. - */ -final class Segment { - static final int SIZE = 2048; - final byte[] data = new byte[SIZE]; - /** - * The next byte of application data byte to read in this segment. - */ - int pos; - - /** - * The first byte of available data ready to be written to. - */ - int limit; - - /** - * Next segment in a linked or circularly-linked list. - */ - Segment next; - - /** - * Previous segment in a circularly-linked list. - */ - Segment prev; - - /** - * Removes this segment of a circularly-linked list and returns its successor. - * Returns null if the list is now empty. - */ - public Segment pop() { - Segment result = next != this ? next : null; - prev.next = next; - next.prev = prev; - next = null; - prev = null; - return result; - } - - /** - * Appends {@code segment} after this segment in the circularly-linked list. - * Returns the pushed segment. - */ - public Segment push(Segment segment) { - segment.prev = this; - segment.next = next; - next.prev = segment; - next = segment; - return segment; - } - - /** - * Splits this head of a circularly-linked list into two segments. The first - * segment contains the data in {@code [pos..pos+byteCount)}. The second - * segment contains the data in {@code [pos+byteCount..limit)}. This can be - * useful when moving partial segments from one buffer to another. - * - *

Returns the new head of the circularly-linked list. - */ - public Segment split(int byteCount) { - int aSize = byteCount; - int bSize = (limit - pos) - byteCount; - if (aSize <= 0 || bSize <= 0) throw new IllegalArgumentException(); - - // Which side of the split is larger? We want to copy as few bytes as possible. - if (aSize < bSize) { - // Create a segment of size 'aSize' before this segment. - Segment before = SegmentPool.INSTANCE.take(); - System.arraycopy(data, pos, before.data, before.pos, aSize); - pos += aSize; - before.limit += aSize; - prev.push(before); - return before; - } else { - // Create a new segment of size 'bSize' after this segment. - Segment after = SegmentPool.INSTANCE.take(); - System.arraycopy(data, pos + aSize, after.data, after.pos, bSize); - limit -= bSize; - after.limit += bSize; - push(after); - return this; - } - } - - /** - * Call this when the tail and its predecessor may both be less than half - * full. This will copy data so that segments can be recycled. - */ - public void compact() { - if (prev == this) throw new IllegalStateException(); - if ((prev.limit - prev.pos) + (limit - pos) > SIZE) return; // Cannot compact. - writeTo(prev, limit - pos); - pop(); - SegmentPool.INSTANCE.recycle(this); - } - - public void writeTo(Segment sink, int byteCount) { - if (byteCount + (sink.limit - sink.pos) > SIZE) throw new IllegalArgumentException(); - - if (sink.limit + byteCount > SIZE) { - // We can't fit byteCount bytes at the sink's current position. Compact sink first. - System.arraycopy(sink.data, sink.pos, sink.data, 0, sink.limit - sink.pos); - sink.limit -= sink.pos; - sink.pos = 0; - } - - System.arraycopy(data, pos, sink.data, sink.limit, byteCount); - sink.limit += byteCount; - pos += byteCount; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/SegmentPool.java b/contentstack/src/main/java/com/contentstack/okio/SegmentPool.java deleted file mode 100755 index f0b6bce2..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/SegmentPool.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -/** - * A collection of unused segments, necessary to avoid GC churn and zero-fill. - * This pool is a thread-safe static singleton. - */ -final class SegmentPool { - static final SegmentPool INSTANCE = new SegmentPool(); - - /** - * The maximum number of bytes to pool. - */ - static final long MAX_SIZE = 64 * 1024; // 64 KiB. - - /** - * Singly-linked list of segments. - */ - private Segment next; - - /** - * Total bytes in this pool. - */ - long byteCount; - - private SegmentPool() { - } - - Segment take() { - synchronized (this) { - if (next != null) { - Segment result = next; - next = result.next; - result.next = null; - byteCount -= Segment.SIZE; - return result; - } - } - return new Segment(); // Pool is empty. Don't zero-fill while holding a lock. - } - - void recycle(Segment segment) { - if (segment.next != null || segment.prev != null) throw new IllegalArgumentException(); - synchronized (this) { - if (byteCount + Segment.SIZE > MAX_SIZE) return; // Pool is full. - byteCount += Segment.SIZE; - segment.next = next; - segment.pos = segment.limit = 0; - next = segment; - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Sink.java b/contentstack/src/main/java/com/contentstack/okio/Sink.java deleted file mode 100755 index b42afa5d..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Sink.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Receives a stream of bytes. Use this interface to write data wherever it's - * needed: to the network, storage, or a buffer in memory. Sinks may be layered - * to transform received data, such as to compress, encrypt, throttle, or add - * protocol framing. - * - *

Most application code shouldn't operate on a sink directly, but rather - * {@link BufferedSink} which is both more efficient and more convenient. Use - * {@link Okio#buffer(Sink)} to wrap any sink with a buffer. - * - *

Sinks are easy to test: just use an {@link Buffer} in your tests, and - * read from it to confirm it received the data that was expected. - * - *

Comparison with OutputStream

- * This interface is functionally equivalent to {@link java.io.OutputStream}. - * - *

{@code OutputStream} requires multiple layers when emitted data is - * heterogeneous: a {@code DataOutputStream} for primitive values, a {@code - * BufferedOutputStream} for buffering, and {@code OutputStreamWriter} for - * charset encoding. This class uses {@code BufferedSink} for all of the above. - * - *

Sink is also easier to layer: there is no {@linkplain - * java.io.OutputStream#write(int) single-byte write} method that is awkward to - * implement efficiently. - * - *

Interop with OutputStream

- * Use {@link Okio#sink} to adapt an {@code OutputStream} to a sink. Use {@link - * BufferedSink#outputStream} to adapt a sink to an {@code OutputStream}. - */ -public interface Sink extends Closeable { - /** - * Removes {@code byteCount} bytes from {@code source} and appends them to this. - */ - void write(Buffer source, long byteCount) throws IOException; - - /** - * Pushes all buffered bytes to their final destination. - */ - void flush() throws IOException; - - /** - * Returns the timeout for this sink. - */ - Timeout timeout(); - - /** - * Pushes all buffered bytes to their final destination and releases the - * resources held by this sink. It is an error to write a closed sink. It is - * safe to close a sink more than once. - */ - @Override - void close() throws IOException; -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Source.java b/contentstack/src/main/java/com/contentstack/okio/Source.java deleted file mode 100755 index a7b6a0bd..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Source.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.Closeable; -import java.io.IOException; - -/** - * Supplies a stream of bytes. Use this interface to read data from wherever - * it's located: from the network, storage, or a buffer in memory. Sources may - * be layered to transform supplied data, such as to decompress, decrypt, or - * remove protocol framing. - * - *

Most applications shouldn't operate on a source directly, but rather - * {@link BufferedSource} which is both more efficient and more convenient. Use - * {@link Okio#buffer(Source)} to wrap any source with a buffer. - * - *

Sources are easy to test: just use an {@link Buffer} in your tests, and - * fill it with the data your application is to read. - * - *

Comparison with InputStream

- * This interface is functionally equivalent to {@link java.io.InputStream}. - * - *

{@code InputStream} requires multiple layers when consumed data is - * heterogeneous: a {@code DataInputStream} for primitive values, a {@code - * BufferedInputStream} for buffering, and {@code InputStreamReader} for - * strings. This class uses {@code BufferedSource} for all of the above. - * - *

Source avoids the impossible-to-implement {@linkplain - * java.io.InputStream#available available()} method. Instead callers specify - * how many bytes they {@link BufferedSource#require require}. - * - *

Source omits the unsafe-to-compose {@linkplain java.io.InputStream#mark - * mark and reset} state that's tracked by {@code InputStream}; callers instead - * just buffer what they need. - * - *

When implementing a source, you need not worry about the {@linkplain - * java.io.InputStream#read single-byte read} method that is awkward to - * implement efficiently and that returns one of 257 possible values. - * - *

And source has a stronger {@code skip} method: {@link BufferedSource#skip} - * won't return prematurely. - * - *

Interop with InputStream

- * Use {@link Okio#source} to adapt an {@code InputStream} to a source. Use - * {@link BufferedSource#inputStream} to adapt a source to an {@code - * InputStream}. - */ -public interface Source extends Closeable { - /** - * Removes at least 1, and up to {@code byteCount} bytes from this and appends - * them to {@code sink}. Returns the number of bytes read, or -1 if this - * source is exhausted. - */ - long read(Buffer sink, long byteCount) throws IOException; - - /** - * Returns the timeout for this source. - */ - Timeout timeout(); - - /** - * Closes this source and releases the resources held by this source. It is an - * error to read a closed source. It is safe to close a source more than once. - */ - @Override - void close() throws IOException; -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Timeout.java b/contentstack/src/main/java/com/contentstack/okio/Timeout.java deleted file mode 100755 index cf31c4eb..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Timeout.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.io.IOException; -import java.io.InterruptedIOException; -import java.util.concurrent.TimeUnit; - -/** - * A policy on how much time to spend on a task before giving up. When a task - * times out, it is left in an unspecified state and should be abandoned. For - * example, if reading from a source times out, that source should be closed and - * the read should be retried later. If writing to a sink times out, the same - * rules apply: close the sink and retry later. - * - *

Timeouts and Deadlines

- * This class offers two complementary controls to define a timeout policy. - * - *

Timeouts specify the maximum time to wait for a single - * operation to complete. Timeouts are typically used to detect problems like - * network partitions. For example, if a remote peer doesn't return any - * data for ten seconds, we may assume that the peer is unavailable. - * - *

Deadlines specify the maximum time to spend on a job, - * composed of one or more operations. Use deadlines to set an upper bound on - * the time invested on a job. For example, a battery-conscious app may limit - * how much time it spends preloading content. - */ -public class Timeout { - /** - * An empty timeout that neither tracks nor detects timeouts. Use this when - * timeouts aren't necessary, such as in implementations whose operations - * do not block. - */ - public static final Timeout NONE = new Timeout() { - @Override - public Timeout timeout(long timeout, TimeUnit unit) { - return this; - } - - @Override - public Timeout deadlineNanoTime(long deadlineNanoTime) { - return this; - } - - @Override - public void throwIfReached() throws IOException { - } - }; - - /** - * True if {@code deadlineNanoTime} is defined. There is no equivalent to null - * or 0 for {@link System#nanoTime}. - */ - private boolean hasDeadline; - private long deadlineNanoTime; - private long timeoutNanos; - - public Timeout() { - } - - /** - * Wait at most {@code timeout} time before aborting an operation. Using a - * per-operation timeout means that as long as forward progress is being made, - * no sequence of operations will fail. - * - *

If {@code timeout == 0}, operations will run indefinitely. (Operating - * system timeouts may still apply.) - */ - public Timeout timeout(long timeout, TimeUnit unit) { - if (timeout < 0) throw new IllegalArgumentException("timeout < 0: " + timeout); - if (unit == null) throw new IllegalArgumentException("unit == null"); - this.timeoutNanos = unit.toNanos(timeout); - return this; - } - - /** - * Returns the timeout in nanoseconds, or {@code 0} for no timeout. - */ - public long timeoutNanos() { - return timeoutNanos; - } - - /** - * Returns true if a deadline is enabled. - */ - public boolean hasDeadline() { - return hasDeadline; - } - - /** - * Returns the {@linkplain System#nanoTime() nano time} when the deadline will - * be reached. - * - * @throws IllegalStateException if no deadline is set. - */ - public long deadlineNanoTime() { - if (!hasDeadline) throw new IllegalStateException("No deadline"); - return deadlineNanoTime; - } - - /** - * Sets the {@linkplain System#nanoTime() nano time} when the deadline will be - * reached. All operations must complete before this time. Use a deadline to - * set a maximum bound on the time spent on a sequence of operations. - */ - public Timeout deadlineNanoTime(long deadlineNanoTime) { - this.hasDeadline = true; - this.deadlineNanoTime = deadlineNanoTime; - return this; - } - - /** - * Set a deadline of now plus {@code duration} time. - */ - public final Timeout deadline(long duration, TimeUnit unit) { - if (duration <= 0) throw new IllegalArgumentException("duration <= 0: " + duration); - if (unit == null) throw new IllegalArgumentException("unit == null"); - return deadlineNanoTime(System.nanoTime() + unit.toNanos(duration)); - } - - /** - * Clears the timeout. Operating system timeouts may still apply. - */ - public Timeout clearTimeout() { - this.timeoutNanos = 0; - return this; - } - - /** - * Clears the deadline. - */ - public Timeout clearDeadline() { - this.hasDeadline = false; - return this; - } - - /** - * Throws an {@link IOException} if the deadline has been reached or if the - * current thread has been interrupted. This method doesn't detect timeouts; - * that should be implemented to asynchronously abort an in-progress - * operation. - */ - public void throwIfReached() throws IOException { - if (Thread.interrupted()) { - throw new InterruptedIOException(); - } - - if (hasDeadline && System.nanoTime() > deadlineNanoTime) { - throw new IOException("deadline reached"); - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/Util.java b/contentstack/src/main/java/com/contentstack/okio/Util.java deleted file mode 100755 index 0f7a3f88..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/Util.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2014 Square, Inc. - * - * 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.contentstack.okio; - -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -final class Util { - /** - * A cheap and type-safe constant for the UTF-8 Charset. - */ - public static final Charset UTF_8 = StandardCharsets.UTF_8; - - private Util() { - } - - public static void checkOffsetAndCount(long size, long offset, long byteCount) { - if ((offset | byteCount) < 0 || offset > size || size - offset < byteCount) { - throw new ArrayIndexOutOfBoundsException( - String.format("size=%s offset=%s byteCount=%s", size, offset, byteCount)); - } - } - - public static short reverseBytesShort(short s) { - int i = s & 0xffff; - int reversed = (i & 0xff00) >>> 8 - | (i & 0x00ff) << 8; - return (short) reversed; - } - - public static int reverseBytesInt(int i) { - return (i & 0xff000000) >>> 24 - | (i & 0x00ff0000) >>> 8 - | (i & 0x0000ff00) << 8 - | (i & 0x000000ff) << 24; - } - - public static long reverseBytesLong(long v) { - return (v & 0xff00000000000000L) >>> 56 - | (v & 0x00ff000000000000L) >>> 40 - | (v & 0x0000ff0000000000L) >>> 24 - | (v & 0x000000ff00000000L) >>> 8 - | (v & 0x00000000ff000000L) << 8 - | (v & 0x0000000000ff0000L) << 24 - | (v & 0x000000000000ff00L) << 40 - | (v & 0x00000000000000ffL) << 56; - } - - /** - * Throws {@code t}, even if the declared throws clause doesn't permit it. - * This is a terrible – but terribly convenient – hack that makes it easy to - * catch and rethrow exceptions after cleanup. See Java Puzzlers #43. - */ - public static void sneakyRethrow(Throwable t) { - Util.sneakyThrow2(t); - } - - @SuppressWarnings("unchecked") - private static void sneakyThrow2(Throwable t) throws T { - throw (T) t; - } -} diff --git a/contentstack/src/main/java/com/contentstack/okio/package-info.java b/contentstack/src/main/java/com/contentstack/okio/package-info.java deleted file mode 100755 index 778e016a..00000000 --- a/contentstack/src/main/java/com/contentstack/okio/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Okio complements {@link java.io} and {@link java.nio} to make it much easier to access, store, - * and process your data. - */ -package com.contentstack.okio; diff --git a/contentstack/src/main/java/com/contentstack/sdk/Entry.java b/contentstack/src/main/java/com/contentstack/sdk/Entry.java index 2e83e300..64987ec8 100755 --- a/contentstack/src/main/java/com/contentstack/sdk/Entry.java +++ b/contentstack/src/main/java/com/contentstack/sdk/Entry.java @@ -4,8 +4,8 @@ import android.util.ArrayMap; import android.util.Log; -import com.contentstack.txtmark.Configuration; -import com.contentstack.txtmark.Processor; +import com.github.rjeschke.txtmark.Configuration; +import com.github.rjeschke.txtmark.Processor; import org.json.JSONArray; import org.json.JSONException; diff --git a/contentstack/src/main/java/com/contentstack/sdk/Group.java b/contentstack/src/main/java/com/contentstack/sdk/Group.java index 2d27905b..8c3e9b5c 100644 --- a/contentstack/src/main/java/com/contentstack/sdk/Group.java +++ b/contentstack/src/main/java/com/contentstack/sdk/Group.java @@ -2,8 +2,8 @@ import android.text.TextUtils; -import com.contentstack.txtmark.Configuration; -import com.contentstack.txtmark.Processor; +import com.github.rjeschke.txtmark.Configuration; +import com.github.rjeschke.txtmark.Processor; import org.json.JSONArray; import org.json.JSONObject; diff --git a/contentstack/src/main/java/com/contentstack/sdk/Stack.java b/contentstack/src/main/java/com/contentstack/sdk/Stack.java index 4c78cdd4..a7f0c0c3 100755 --- a/contentstack/src/main/java/com/contentstack/sdk/Stack.java +++ b/contentstack/src/main/java/com/contentstack/sdk/Stack.java @@ -80,7 +80,7 @@ protected void setConfig(Config config) { URL = "azure-na-cdn.contentstack.com"; } else if (region.equalsIgnoreCase("azure_eu")) { URL = "azure-eu-cdn.contentstack.com"; - }else if (region.equalsIgnoreCase("gcp_na")) { + } else if (region.equalsIgnoreCase("gcp_na")) { URL = "gcp-na-cdn.contentstack.com"; } else { URL = region + "-" + URL; diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Block.java b/contentstack/src/main/java/com/contentstack/txtmark/Block.java deleted file mode 100755 index 6c13495c..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Block.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * This class represents a block of lines. - * - * @author René Jeschke - */ -class Block { - /** - * This block's type. - */ - public BlockType type = BlockType.NONE; - /** - * Head and tail of linked lines. - */ - public Line lines = null, lineTail = null; - /** - * Head and tail of child blocks. - */ - public Block blocks = null, blockTail = null; - /** - * Next block. - */ - public Block next = null; - /** - * Depth of headline BlockType. - */ - public int hlDepth = 0; - /** - * ID for headlines and list items - */ - public String id = null; - /** - * Block meta information - */ - public String meta = ""; - - /** - * Constructor. - */ - public Block() { - // - } - - /** - * @return true if this block contains lines. - */ - public boolean hasLines() { - return this.lines != null; - } - - /** - * Removes leading and trailing empty lines. - */ - public void removeSurroundingEmptyLines() { - if (this.lines != null) { - this.removeTrailingEmptyLines(); - this.removeLeadingEmptyLines(); - } - } - - /** - * Sets hlDepth and takes care of '#' chars. - */ - public void transfromHeadline() { - if (this.hlDepth > 0) { - return; - } - int level = 0; - final Line line = this.lines; - if (line.isEmpty) { - return; - } - int start = line.leading; - while (start < line.value.length() && line.value.charAt(start) == '#') { - level++; - start++; - } - while (start < line.value.length() && line.value.charAt(start) == ' ') { - start++; - } - if (start >= line.value.length()) { - line.setEmpty(); - } else { - int end = line.value.length() - line.trailing - 1; - while (line.value.charAt(end) == '#') { - end--; - } - while (line.value.charAt(end) == ' ') { - end--; - } - line.value = line.value.substring(start, end + 1); - line.leading = line.trailing = 0; - } - this.hlDepth = Math.min(level, 6); - } - - /** - * Used for nested lists. Removes list markers and up to 4 leading spaces. - * - * @param configuration txtmark configuration - */ - public void removeListIndent(final Configuration configuration) { - Line line = this.lines; - while (line != null) { - if (!line.isEmpty) { - switch (line.getLineType(configuration)) { - case ULIST: - line.value = line.value.substring(line.leading + 2); - break; - case OLIST: - line.value = line.value.substring(line.value.indexOf('.') + 2); - break; - default: - line.value = line.value.substring(Math.min(line.leading, 4)); - break; - } - line.initLeading(); - } - line = line.next; - } - } - - /** - * Used for nested block quotes. Removes '>' char. - */ - public void removeBlockQuotePrefix() { - Line line = this.lines; - while (line != null) { - if (!line.isEmpty) { - if (line.value.charAt(line.leading) == '>') { - int rem = line.leading + 1; - if (line.leading + 1 < line.value.length() && line.value.charAt(line.leading + 1) == ' ') { - rem++; - } - line.value = line.value.substring(rem); - line.initLeading(); - } - } - line = line.next; - } - } - - /** - * Removes leading empty lines. - * - * @return true if an empty line was removed. - */ - public boolean removeLeadingEmptyLines() { - boolean wasEmpty = false; - Line line = this.lines; - while (line != null && line.isEmpty) { - this.removeLine(line); - line = this.lines; - wasEmpty = true; - } - return wasEmpty; - } - - /** - * Removes trailing empty lines. - */ - public void removeTrailingEmptyLines() { - Line line = this.lineTail; - while (line != null && line.isEmpty) { - this.removeLine(line); - line = this.lineTail; - } - } - - /** - * Splits this block's lines, creating a new child block having 'line' as - * it's lineTail. - * - * @param line The line to split from. - * @return The newly created Block. - */ - public Block split(final Line line) { - final Block block = new Block(); - - block.lines = this.lines; - block.lineTail = line; - this.lines = line.next; - line.next = null; - if (this.lines == null) { - this.lineTail = null; - } else { - this.lines.previous = null; - } - - if (this.blocks == null) { - this.blocks = this.blockTail = block; - } else { - this.blockTail.next = block; - this.blockTail = block; - } - - return block; - } - - /** - * Removes the given line from this block. - * - * @param line Line to remove. - */ - public void removeLine(final Line line) { - if (line.previous == null) { - this.lines = line.next; - } else { - line.previous.next = line.next; - } - if (line.next == null) { - this.lineTail = line.previous; - } else { - line.next.previous = line.previous; - } - line.previous = line.next = null; - } - - /** - * Appends the given line to this block. - * - * @param line Line to append. - */ - public void appendLine(final Line line) { - if (this.lineTail == null) { - this.lines = this.lineTail = line; - } else { - this.lineTail.nextEmpty = line.isEmpty; - line.prevEmpty = this.lineTail.isEmpty; - line.previous = this.lineTail; - this.lineTail.next = line; - this.lineTail = line; - } - } - - /** - * Changes all Blocks of type NONE to PARAGRAPH if - * this Block is a List and any of the ListItems contains a paragraph. - */ - public void expandListParagraphs() { - if (this.type != BlockType.ORDERED_LIST && this.type != BlockType.UNORDERED_LIST) { - return; - } - Block outer = this.blocks, inner; - boolean hasParagraph = false; - while (outer != null && !hasParagraph) { - if (outer.type == BlockType.LIST_ITEM) { - inner = outer.blocks; - while (inner != null && !hasParagraph) { - if (inner.type == BlockType.PARAGRAPH) { - hasParagraph = true; - } - inner = inner.next; - } - } - outer = outer.next; - } - if (hasParagraph) { - outer = this.blocks; - while (outer != null) { - if (outer.type == BlockType.LIST_ITEM) { - inner = outer.blocks; - while (inner != null) { - if (inner.type == BlockType.NONE) { - inner.type = BlockType.PARAGRAPH; - } - inner = inner.next; - } - } - outer = outer.next; - } - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/BlockEmitter.java b/contentstack/src/main/java/com/contentstack/txtmark/BlockEmitter.java deleted file mode 100755 index 37d2a029..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/BlockEmitter.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.util.List; - -/** - * Block emitter interface. An example for a code block emitter is given below: - * - *

- * public void emitBlock(StringBuilder out, List<String> lines, String meta)
- * {
- *     out.append("<pre><code>");
- *     for(final String s : lines)
- *     {
- *         for(int i = 0; i < s.length(); i++)
- *         {
- *             final char c = s.charAt(i);
- *             switch(c)
- *             {
- *             case '&':
- *                 out.append("&amp;");
- *                 break;
- *             case '<':
- *                 out.append("&lt;");
- *                 break;
- *             case '>':
- *                 out.append("&gt;");
- *                 break;
- *             default:
- *                 out.append(c);
- *                 break;
- *             }
- *         }
- *         out.append('\n');
- *     }
- *     out.append("</code></pre>\n");
- * }
- * 
- * 
- * - * @author René Jeschke <, rene_jeschke@yahoo.de>, - * @since 0.7 - */ -public interface BlockEmitter { - /** - * This method is responsible for outputting a markdown block and for any - * needed pre-processing like escaping HTML special characters. - * - * @param out The StringBuilder to append to - * @param lines List of lines - * @param meta Meta information as a single String (if any) or empty String - */ - public void emitBlock(StringBuilder out, List lines, String meta); -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/BlockType.java b/contentstack/src/main/java/com/contentstack/txtmark/BlockType.java deleted file mode 100755 index 3e314f21..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/BlockType.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Block type enum. - * - * @author René Jeschke - */ -enum BlockType { - /** - * Unspecified. Used for root block and list items without paragraphs. - */ - NONE, - /** - * A block quote. - */ - BLOCKQUOTE, - /** - * A code block. - */ - CODE, - /** - * A fenced code block. - */ - FENCED_CODE, - /** - * A headline. - */ - HEADLINE, - /** - * A list item. - */ - LIST_ITEM, - /** - * An ordered list. - */ - ORDERED_LIST, - /** - * A paragraph. - */ - PARAGRAPH, - /** - * A horizontal ruler. - */ - RULER, - /** - * An unordered list. - */ - UNORDERED_LIST, - /** - * A XML block. - */ - XML, - /** - * A GFM table - */ - TABLE -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Configuration.java b/contentstack/src/main/java/com/contentstack/txtmark/Configuration.java deleted file mode 100755 index 626ae7e7..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Configuration.java +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Txtmark configuration. - * - * @author René Jeschke <, rene_jeschke@yahoo.de>, - * @since 0.7 - */ -public class Configuration { - final boolean safeMode; - final boolean panicMode; - final String encoding; - final Decorator decorator; - final BlockEmitter codeBlockEmitter; - final boolean forceExtendedProfile; - final boolean allowSpacesInFencedDelimiters; - final SpanEmitter specialLinkEmitter; - - /** - *

- * This is the default configuration for txtmark's process - * methods - *

- * - *
    - *
  • safeMode = false
  • - *
  • encoding = UTF-8
  • - *
  • decorator = DefaultDecorator
  • - *
  • codeBlockEmitter = null
  • - *
- */ - public final static Configuration DEFAULT = Configuration.builder().build(); - - /** - *

- * Default safe configuration - *

- * - *
    - *
  • safeMode = true
  • - *
  • encoding = UTF-8
  • - *
  • decorator = DefaultDecorator
  • - *
  • codeBlockEmitter = null
  • - *
- */ - public final static Configuration DEFAULT_SAFE = Configuration.builder().enableSafeMode().build(); - - /** - * Constructor. - */ - Configuration(final boolean safeMode, final String encoding, final Decorator decorator, - final BlockEmitter codeBlockEmitter, - final boolean forceExtendedProfile, final SpanEmitter specialLinkEmitter, - final boolean allowSpacesInFencedDelimiters, final boolean panicMode) { - this.safeMode = safeMode; - this.encoding = encoding; - this.decorator = decorator; - this.codeBlockEmitter = codeBlockEmitter; - this.forceExtendedProfile = forceExtendedProfile; - this.specialLinkEmitter = specialLinkEmitter; - this.allowSpacesInFencedDelimiters = allowSpacesInFencedDelimiters; - this.panicMode = panicMode; - } - - /** - * Creates a new Builder instance. - * - * @return A new Builder instance. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Configuration builder. - * - * @author René Jeschke <, rene_jeschke@yahoo.de>, - * @since 0.7 - */ - public static class Builder { - private boolean safeMode = false; - private boolean panicMode = false; - private boolean forceExtendedProfile = false; - private boolean allowSpacesInFencedDelimiters = true; - private String encoding = "UTF-8"; - private Decorator decorator = new DefaultDecorator(); - private BlockEmitter codeBlockEmitter = null; - private SpanEmitter specialLinkEmitter = null; - - /** - * Constructor. - */ - Builder() { - // empty - } - - /** - * Enables HTML safe mode. - *

- * Default: false - * - * @return This builder - * @since 0.7 - */ - public Builder enableSafeMode() { - this.safeMode = true; - return this; - } - - /** - * Forces extened profile to be enabled by default. - * - * @return This builder. - * @since 0.7 - */ - public Builder forceExtentedProfile() { - this.forceExtendedProfile = true; - return this; - } - - /** - * Sets the HTML safe mode flag. - *

- * Default: false - * - * @param flag true to enable safe mode - * @return This builder - * @since 0.7 - */ - public Builder setSafeMode(final boolean flag) { - this.safeMode = flag; - return this; - } - - /** - * Sets the character encoding for txtmark. - *

- * Default: "UTF-8" - * - * @param encoding The encoding - * @return This builder - * @since 0.7 - */ - public Builder setEncoding(final String encoding) { - this.encoding = encoding; - return this; - } - - /** - * Sets the decorator for txtmark. - *

- * Default: DefaultDecorator() - * - * @param decorator The decorator - * @return This builder - * @see DefaultDecorator - * @since 0.7 - */ - public Builder setDecorator(final Decorator decorator) { - this.decorator = decorator; - return this; - } - - /** - * Sets the code block emitter. - *

- * Default: null - * - * @param emitter The BlockEmitter - * @return This builder - * @see BlockEmitter - * @since 0.7 - */ - public Builder setCodeBlockEmitter(final BlockEmitter emitter) { - this.codeBlockEmitter = emitter; - return this; - } - - /** - * Sets the emitter for special link spans ([[ ... ]]). - * - * @param emitter The emitter. - * @return This builder. - * @since 0.7 - */ - public Builder setSpecialLinkEmitter(final SpanEmitter emitter) { - this.specialLinkEmitter = emitter; - return this; - } - - /** - * (Dis-)Allows spaces in fenced code block delimiter lines. - * - * @param allow whether to allow or not - * @return This builder. - * @since 0.12 - */ - public Builder setAllowSpacesInFencedCodeBlockDelimiters(final boolean allow) { - this.allowSpacesInFencedDelimiters = allow; - return this; - } - - /** - * This allows you to enable 'panicMode'. When 'panicMode' is enabled, - * every {@code <} encountered will then be translated into {@code <} - * - * @param panic whether to enable or not - * @return This builder. - * @since 0.12 - */ - public Builder setEnablePanicMode(final boolean panic) { - this.panicMode = panic; - return this; - } - - /** - * This allows you to enable 'panicMode'. When 'panicMode' is enabled, - * every {@code <} encountered will then be translated into {@code <} - * - * @return This builder. - * @since 0.12 - */ - public Builder enablePanicMode() { - this.panicMode = true; - return this; - } - - /** - * Builds a configuration instance. - * - * @return a Configuration instance - * @since 0.7 - */ - public Configuration build() { - return new Configuration(this.safeMode, this.encoding, this.decorator, this.codeBlockEmitter, - this.forceExtendedProfile, this.specialLinkEmitter, this.allowSpacesInFencedDelimiters, - this.panicMode); - } - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Decorator.java b/contentstack/src/main/java/com/contentstack/txtmark/Decorator.java deleted file mode 100755 index a571c13f..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Decorator.java +++ /dev/null @@ -1,657 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Decorator interface. - * - * @author René Jeschke <, rene_jeschke@yahoo.de>, - */ -public interface Decorator { - /** - * Called when a paragraph is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<p>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openParagraph(final StringBuilder out); - - /** - * Called when a paragraph is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</p>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeParagraph(final StringBuilder out); - - /** - * Called when a blockquote is opened. - *

- * Default implementation is: - * - *

-     * out.append("<blockquote>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openBlockquote(final StringBuilder out); - - /** - * Called when a blockquote is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</blockquote>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeBlockquote(final StringBuilder out); - - /** - * Called when a code block is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<pre><code>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openCodeBlock(final StringBuilder out); - - /** - * Called when a code block is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</code></pre>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeCodeBlock(final StringBuilder out); - - /** - * Called when a code span is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<code>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openCodeSpan(final StringBuilder out); - - /** - * Called when a code span is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</code>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeCodeSpan(final StringBuilder out); - - /** - * Called when a headline is opened. - * - *

- * Note: Don't close the HTML tag! - *

- *

- * Default implementation is: - *

- * - *
-     *  out.append("<h");
-     * out.append(level);
-     * 
- * - * @param out The StringBuilder to write to. - * @param level The level to use. - */ - public void openHeadline(final StringBuilder out, int level); - - /** - * Called when a headline is closed. - * - *

- * Default implementation is: - *

- * - *
-     *  out.append("</h");
-     * out.append(level);
-     * out.append(">\n");
-     * 
- * - * @param out The StringBuilder to write to. - * @param level The level to use. - */ - public void closeHeadline(final StringBuilder out, int level); - - /** - * Called when a strong span is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<strong>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openStrong(final StringBuilder out); - - /** - * Called when a strong span is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</strong>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeStrong(final StringBuilder out); - - /** - * Called when an emphasis span is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<em>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openEmphasis(final StringBuilder out); - - /** - * Called when an emphasis span is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</em>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeEmphasis(final StringBuilder out); - - /** - * Called when a strikeout span is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<del>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openStrikeout(final StringBuilder out); - - /** - * Called when a strikeout span is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</del>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeStrikeout(final StringBuilder out); - - /** - * Called when a superscript span is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<sup>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openSuper(final StringBuilder out); - - /** - * Called when a superscript span is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</sup>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeSuper(final StringBuilder out); - - /** - * Called when an ordered list is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<ol>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openOrderedList(final StringBuilder out); - - /** - * Called when an ordered list is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</ol>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeOrderedList(final StringBuilder out); - - /** - * Called when an unordered list is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<ul>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openUnorderedList(final StringBuilder out); - - /** - * Called when an unordered list is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</ul>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeUnorderedList(final StringBuilder out); - - /** - * Called when a list item is opened. - * - *

- * Note: Don't close the HTML tag! - *

- *

- * Default implementation is: - *

- * - *
-     * out.append("<li");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openListItem(final StringBuilder out); - - /** - * Called when a list item is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</li>\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeListItem(final StringBuilder out); - - /** - * Called when a horizontal ruler is encountered. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("<hr />\n");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void horizontalRuler(final StringBuilder out); - - /** - * Called when a link is opened. - * - *

- * Note: Don't close the HTML tag! - *

- *

- * Default implementation is: - *

- * - *
-     * out.append("<a");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openLink(final StringBuilder out); - - /** - * Called when a link is closed - * - *

- * Default implementation is: - *

- * - *
-     * out.append("</a>");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeLink(final StringBuilder out); - - /** - * Called when an image is opened. - * - *

- * Note: Don't close the HTML tag! - *

- *

- * Default implementation is: - *

- * - *
-     * out.append("<img");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openImage(final StringBuilder out); - - /** - * Called when an image is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append(" />");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeImage(final StringBuilder out); - - /** - * Called when a table is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
-     *
-     * @param out The StringBuilder to write to.
-     */
-    public void openTable(final StringBuilder out);
-
-    /**
-     * Called when a table is closed.
-     *
-     * 

- * Default implementation is: - *

- * - *
-     * out.append("
"); - *
- * - * @param out The StringBuilder to write to. - */ - public void closeTable(final StringBuilder out); - - /** - * Called when a table body is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openTableBody(final StringBuilder out); - - /** - * Called when a table body is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeTableBody(final StringBuilder out); - - /** - * Called when a table head is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openTableHead(final StringBuilder out); - - /** - * Called when a table head is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeTableHead(final StringBuilder out); - - /** - * Called when a table row is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void openTableRow(final StringBuilder out); - - /** - * Called when a table row is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeTableRow(final StringBuilder out); - - /** - * Called when a table data is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - * @param align one of null | left | center | right. - * If null no align is set - */ - public void openTableData(final StringBuilder out, final String align); - - /** - * Called when a table data is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeTableData(final StringBuilder out); - - /** - * Called when a table header is opened. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - * @param align one of null | left | center | right. - * If null no align is set - */ - public void openTableHeader(final StringBuilder out, final String align); - - /** - * Called when a table header is closed. - * - *

- * Default implementation is: - *

- * - *
-     * out.append("");
-     * 
- * - * @param out The StringBuilder to write to. - */ - public void closeTableHeader(final StringBuilder out); -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/DefaultDecorator.java b/contentstack/src/main/java/com/contentstack/txtmark/DefaultDecorator.java deleted file mode 100755 index 95811d1d..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/DefaultDecorator.java +++ /dev/null @@ -1,387 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Default Decorator implementation. - * - *

- * Example for a user Decorator having a class attribute on <p> tags. - *

- * - *
- * public class MyDecorator extends DefaultDecorator
- * {
- *     @Override
- *     public void openParagraph(StringBuilder out)
- *     {
- *         out.append("<p class=\"myclass\">");
- *     }
- * }
- * 
- * 
- * - * @author René Jeschke <rene_jeschke@yahoo.de> - */ -public class DefaultDecorator implements Decorator { - /** - * Constructor. - */ - public DefaultDecorator() { - // empty - } - - /** - * @see Decorator#openParagraph(StringBuilder) - */ - @Override - public void openParagraph(final StringBuilder out) { - out.append("

"); - } - - /** - * @see Decorator#closeParagraph(StringBuilder) - */ - @Override - public void closeParagraph(final StringBuilder out) { - out.append("

\n"); - } - - /** - * @see Decorator#openBlockquote(StringBuilder) - */ - @Override - public void openBlockquote(final StringBuilder out) { - out.append("
"); - } - - /** - * @see Decorator#closeBlockquote(StringBuilder) - */ - @Override - public void closeBlockquote(final StringBuilder out) { - out.append("
\n"); - } - - /** - * @see Decorator#openCodeBlock(StringBuilder) - */ - @Override - public void openCodeBlock(final StringBuilder out) { - out.append("
");
-    }
-
-    /**
-     * @see Decorator#closeCodeBlock(StringBuilder)
-     */
-    @Override
-    public void closeCodeBlock(final StringBuilder out) {
-        out.append("
\n"); - } - - /** - * @see Decorator#openCodeSpan(StringBuilder) - */ - @Override - public void openCodeSpan(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#closeCodeSpan(StringBuilder) - */ - @Override - public void closeCodeSpan(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openHeadline(StringBuilder, - * int) - */ - @Override - public void openHeadline(final StringBuilder out, final int level) { - out.append("\n"); - } - - /** - * @see Decorator#openStrong(StringBuilder) - */ - @Override - public void openStrong(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#closeStrong(StringBuilder) - */ - @Override - public void closeStrong(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openEmphasis(StringBuilder) - */ - @Override - public void openEmphasis(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#closeEmphasis(StringBuilder) - */ - @Override - public void closeEmphasis(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openStrikeout(StringBuilder) - */ - @Override - public void openStrikeout(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#closeStrikeout(StringBuilder) - */ - @Override - public void closeStrikeout(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openSuper(StringBuilder) - */ - @Override - public void openSuper(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#closeSuper(StringBuilder) - */ - @Override - public void closeSuper(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openOrderedList(StringBuilder) - */ - @Override - public void openOrderedList(final StringBuilder out) { - out.append("
    \n"); - } - - /** - * @see Decorator#closeOrderedList(StringBuilder) - */ - @Override - public void closeOrderedList(final StringBuilder out) { - out.append("
\n"); - } - - /** - * @see Decorator#openUnorderedList(StringBuilder) - */ - @Override - public void openUnorderedList(final StringBuilder out) { - out.append("
    \n"); - } - - /** - * @see Decorator#closeUnorderedList(StringBuilder) - */ - @Override - public void closeUnorderedList(final StringBuilder out) { - out.append("
\n"); - } - - /** - * @see Decorator#openListItem(StringBuilder) - */ - @Override - public void openListItem(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#horizontalRuler(StringBuilder) - */ - @Override - public void horizontalRuler(final StringBuilder out) { - out.append("
\n"); - } - - /** - * @see Decorator#openLink(StringBuilder) - */ - @Override - public void openLink(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openImage(StringBuilder) - */ - @Override - public void openImage(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openTable(java.lang.StringBuilder) - */ - @Override - public void openTable(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#closeTable(java.lang.StringBuilder) - */ - @Override - public void closeTable(final StringBuilder out) { - out.append("
\n"); - } - - /** - * @see Decorator#openTableHead(java.lang.StringBuilder) - */ - @Override - public void openTableHead(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#closeTableHead(java.lang.StringBuilder) - */ - @Override - public void closeTableHead(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#openTableBody(java.lang.StringBuilder) - */ - @Override - public void openTableBody(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#closeTableBody(java.lang.StringBuilder) - */ - @Override - public void closeTableBody(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#openTableRow(java.lang.StringBuilder) - */ - @Override - public void openTableRow(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#closeTableRow(java.lang.StringBuilder) - */ - @Override - public void closeTableRow(final StringBuilder out) { - out.append("\n"); - } - - /** - * @see Decorator#openTableData(java.lang.StringBuilder, java.lang.String) - */ - @Override - public void openTableData(final StringBuilder out, final String align) { - if (align == null) { - out.append(""); - } else { - out.append(""); - } - } - - /** - * @see Decorator#closeTableData(java.lang.StringBuilder) - */ - @Override - public void closeTableData(final StringBuilder out) { - out.append(""); - } - - /** - * @see Decorator#openTableHeader(java.lang.StringBuilder, java.lang.String) - */ - @Override - public void openTableHeader(final StringBuilder out, final String align) { - if (align == null) { - out.append(""); - } else { - out.append(""); - } - } - - /** - * @see Decorator#closeTableHeader(java.lang.StringBuilder) - */ - @Override - public void closeTableHeader(final StringBuilder out) { - out.append(""); - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Emitter.java b/contentstack/src/main/java/com/contentstack/txtmark/Emitter.java deleted file mode 100755 index abc15ee7..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Emitter.java +++ /dev/null @@ -1,1010 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; - -/** - * Emitter class responsible for generating HTML output. - * - * @author René Jeschke - */ -class Emitter { - /** - * Link references. - */ - private final HashMap linkRefs = new HashMap(); - /** - * The configuration. - */ - private final Configuration config; - /** - * Extension flag. - */ - public boolean useExtensions = false; - - /** - * Constructor. - */ - public Emitter(final Configuration config) { - this.config = config; - this.useExtensions = config.forceExtendedProfile; - } - - /** - * Adds a LinkRef to this set of LinkRefs. - * - * @param key The key/id. - * @param linkRef The LinkRef. - */ - public void addLinkRef(final String key, final LinkRef linkRef) { - this.linkRefs.put(key.toLowerCase(), linkRef); - } - - /** - * Transforms the given block recursively into HTML. - * - * @param out The StringBuilder to write to. - * @param root The Block to process. - */ - public void emit(final StringBuilder out, final Block root) { - root.removeSurroundingEmptyLines(); - - switch (root.type) { - case RULER: - this.config.decorator.horizontalRuler(out); - return; - case NONE: - case XML: - break; - case HEADLINE: - this.config.decorator.openHeadline(out, root.hlDepth); - if (this.useExtensions && root.id != null) { - out.append(" id=\""); - Utils.appendCode(out, root.id, 0, root.id.length()); - out.append('"'); - } - out.append('>'); - break; - case PARAGRAPH: - this.config.decorator.openParagraph(out); - break; - case CODE: - case FENCED_CODE: - if (this.config.codeBlockEmitter == null) { - this.config.decorator.openCodeBlock(out); - } - break; - case BLOCKQUOTE: - this.config.decorator.openBlockquote(out); - break; - case UNORDERED_LIST: - this.config.decorator.openUnorderedList(out); - break; - case ORDERED_LIST: - this.config.decorator.openOrderedList(out); - break; - case LIST_ITEM: - this.config.decorator.openListItem(out); - if (this.useExtensions && root.id != null) { - out.append(" id=\""); - Utils.appendCode(out, root.id, 0, root.id.length()); - out.append('"'); - } - out.append('>'); - break; - case TABLE: - this.config.decorator.openTable(out); - break; - } - - if (root.hasLines()) { - this.emitLines(out, root); - } else { - Block block = root.blocks; - while (block != null) { - this.emit(out, block); - block = block.next; - } - } - - switch (root.type) { - case RULER: - case NONE: - case XML: - break; - case HEADLINE: - this.config.decorator.closeHeadline(out, root.hlDepth); - break; - case PARAGRAPH: - this.config.decorator.closeParagraph(out); - break; - case CODE: - case FENCED_CODE: - if (this.config.codeBlockEmitter == null) { - this.config.decorator.closeCodeBlock(out); - } - break; - case BLOCKQUOTE: - this.config.decorator.closeBlockquote(out); - break; - case UNORDERED_LIST: - this.config.decorator.closeUnorderedList(out); - break; - case ORDERED_LIST: - this.config.decorator.closeOrderedList(out); - break; - case LIST_ITEM: - this.config.decorator.closeListItem(out); - break; - case TABLE: - this.config.decorator.closeTable(out); - break; - } - } - - /** - * Transforms lines into HTML. - * - * @param out The StringBuilder to write to. - * @param block The Block to process. - */ - private void emitLines(final StringBuilder out, final Block block) { - switch (block.type) { - case CODE: - this.emitCodeLines(out, block.lines, block.meta, true); - break; - case FENCED_CODE: - this.emitCodeLines(out, block.lines, block.meta, false); - break; - case XML: - this.emitRawLines(out, block.lines); - break; - case TABLE: - this.emitTableLines(out, block.lines); - break; - default: - this.emitMarkedLines(out, block.lines); - break; - } - } - - /** - * Finds the position of the given Token in the given String. - * - * @param in The String to search on. - * @param start The starting character position. - * @param token The token to find. - * @return The position of the token or -1 if none could be found. - */ - private int findToken(final String in, final int start, final MarkToken token) { - int pos = start; - while (pos < in.length()) { - if (this.getToken(in, pos) == token) { - return pos; - } - pos++; - } - return -1; - } - - /** - * Checks if there is a valid markdown link definition. - * - * @param out The StringBuilder containing the generated output. - * @param in Input String. - * @param start Starting position. - * @param token Either LINK or IMAGE. - * @return The new position or -1 if there is no valid markdown link. - */ - private int checkLink(final StringBuilder out, final String in, final int start, final MarkToken token) { - boolean isAbbrev = false; - int pos = start + (token == MarkToken.LINK ? 1 : 2); - final StringBuilder temp = new StringBuilder(); - - temp.setLength(0); - pos = Utils.readMdLinkId(temp, in, pos); - if (pos < start) { - return -1; - } - - final String name = temp.toString(); - String link = null, comment = null; - final int oldPos = pos++; - pos = Utils.skipSpaces(in, pos); - if (pos < start) { - final LinkRef lr = this.linkRefs.get(name.toLowerCase()); - if (lr != null) { - isAbbrev = lr.isAbbrev; - link = lr.link; - comment = lr.title; - pos = oldPos; - } else { - return -1; - } - } else if (in.charAt(pos) == '(') { - pos++; - pos = Utils.skipSpaces(in, pos); - if (pos < start) { - return -1; - } - temp.setLength(0); - final boolean useLt = in.charAt(pos) == '<'; - pos = useLt ? Utils.readUntil(temp, in, pos + 1, '>') : Utils.readMdLink(temp, in, pos); - if (pos < start) { - return -1; - } - if (useLt) { - pos++; - } - link = temp.toString(); - - if (in.charAt(pos) == ' ') { - pos = Utils.skipSpaces(in, pos); - if (pos > start && in.charAt(pos) == '"') { - pos++; - temp.setLength(0); - pos = Utils.readUntil(temp, in, pos, '"'); - if (pos < start) { - return -1; - } - comment = temp.toString(); - pos++; - pos = Utils.skipSpaces(in, pos); - if (pos == -1) { - return -1; - } - } - } - if (in.charAt(pos) != ')') { - return -1; - } - } else if (in.charAt(pos) == '[') { - pos++; - temp.setLength(0); - pos = Utils.readRawUntil(temp, in, pos, ']'); - if (pos < start) { - return -1; - } - final String id = temp.length() > 0 ? temp.toString() : name; - final LinkRef lr = this.linkRefs.get(id.toLowerCase()); - if (lr != null) { - link = lr.link; - comment = lr.title; - } - } else { - final LinkRef lr = this.linkRefs.get(name.toLowerCase()); - if (lr != null) { - isAbbrev = lr.isAbbrev; - link = lr.link; - comment = lr.title; - pos = oldPos; - } else { - return -1; - } - } - - if (link == null) { - return -1; - } - - if (token == MarkToken.LINK) { - if (isAbbrev && comment != null) { - if (!this.useExtensions) { - return -1; - } - out.append(""); - this.recursiveEmitLine(out, name, 0, MarkToken.NONE); - out.append(""); - } else { - this.config.decorator.openLink(out); - out.append(" href=\""); - Utils.appendValue(out, link, 0, link.length()); - out.append('"'); - if (comment != null) { - out.append(" title=\""); - Utils.appendValue(out, comment, 0, comment.length()); - out.append('"'); - } - out.append('>'); - this.recursiveEmitLine(out, name, 0, MarkToken.LINK); - this.config.decorator.closeLink(out); - } - } else { - this.config.decorator.openImage(out); - out.append(" src=\""); - Utils.appendValue(out, link, 0, link.length()); - out.append("\" alt=\""); - Utils.appendValue(out, name, 0, name.length()); - out.append('"'); - if (comment != null) { - out.append(" title=\""); - Utils.appendValue(out, comment, 0, comment.length()); - out.append('"'); - } - this.config.decorator.closeImage(out); - } - - return pos; - } - - /** - * Check if there is a valid HTML tag here. This method also transforms auto - * links and mailto auto links. - * - * @param out The StringBuilder to write to. - * @param in Input String. - * @param start Starting position. - * @return The new position or -1 if nothing valid has been found. - */ - private int checkHtml(final StringBuilder out, final String in, final int start) { - final StringBuilder temp = new StringBuilder(); - int pos; - - // Check for auto links - temp.setLength(0); - pos = Utils.readUntil(temp, in, start + 1, ':', ' ', '>', '\n'); - if (pos != -1 && in.charAt(pos) == ':' && HTML.isLinkPrefix(temp.toString())) { - pos = Utils.readUntil(temp, in, pos, '>'); - if (pos != -1) { - final String link = temp.toString(); - this.config.decorator.openLink(out); - out.append(" href=\""); - Utils.appendValue(out, link, 0, link.length()); - out.append("\">"); - Utils.appendValue(out, link, 0, link.length()); - this.config.decorator.closeLink(out); - return pos; - } - } - - // Check for mailto auto link - temp.setLength(0); - pos = Utils.readUntil(temp, in, start + 1, '@', ' ', '>', '\n'); - if (pos != -1 && in.charAt(pos) == '@') { - pos = Utils.readUntil(temp, in, pos, '>'); - if (pos != -1) { - final String link = temp.toString(); - this.config.decorator.openLink(out); - out.append(" href=\""); - Utils.appendMailto(out, "mailto:", 0, 7); - Utils.appendMailto(out, link, 0, link.length()); - out.append("\">"); - Utils.appendMailto(out, link, 0, link.length()); - this.config.decorator.closeLink(out); - return pos; - } - } - - // Check for inline html - if (start + 2 < in.length()) { - temp.setLength(0); - return Utils.readXML(out, in, start, this.config.safeMode); - } - - return -1; - } - - /** - * Check if this is a valid XML/HTML entity. - * - * @param out The StringBuilder to write to. - * @param in Input String. - * @param start Starting position - * @return The new position or -1 if this entity in invalid. - */ - private static int checkEntity(final StringBuilder out, final String in, final int start) { - final int pos = Utils.readUntil(out, in, start, ';'); - if (pos < 0 || out.length() < 3) { - return -1; - } - if (out.charAt(1) == '#') { - if (out.charAt(2) == 'x' || out.charAt(2) == 'X') { - if (out.length() < 4) { - return -1; - } - for (int i = 3; i < out.length(); i++) { - final char c = out.charAt(i); - if ((c < '0' || c > '9') && ((c < 'a' || c > 'f') && (c < 'A' || c > 'F'))) { - return -1; - } - } - } else { - for (int i = 2; i < out.length(); i++) { - final char c = out.charAt(i); - if (c < '0' || c > '9') { - return -1; - } - } - } - out.append(';'); - } else { - for (int i = 1; i < out.length(); i++) { - final char c = out.charAt(i); - if (!Character.isLetterOrDigit(c)) { - return -1; - } - } - out.append(';'); - return HTML.isEntity(out.toString()) ? pos : -1; - } - - return pos; - } - - /** - * Recursively scans through the given line, taking care of any markdown - * stuff. - * - * @param out The StringBuilder to write to. - * @param in Input String. - * @param start Start position. - * @param token The matching Token (for e.g. '*') - * @return The position of the matching Token or -1 if token was NONE or no - * Token could be found. - */ - private int recursiveEmitLine(final StringBuilder out, final String in, final int start, final MarkToken token) { - int pos = start, a, b; - final StringBuilder temp = new StringBuilder(); - while (pos < in.length()) { - final MarkToken mt = this.getToken(in, pos); - if (token != MarkToken.NONE && token != MarkToken.LINK - && (mt == token || token == MarkToken.EM_STAR && mt == MarkToken.STRONG_STAR || token == MarkToken.EM_UNDERSCORE - && mt == MarkToken.STRONG_UNDERSCORE)) { - return pos; - } - - switch (mt) { - case IMAGE: - case LINK: - temp.setLength(0); - b = this.checkLink(temp, in, pos, mt); - if (b > 0) { - out.append(temp); - pos = b; - } else { - out.append(in.charAt(pos)); - } - break; - case EM_STAR: - case EM_UNDERSCORE: - temp.setLength(0); - b = this.recursiveEmitLine(temp, in, pos + 1, mt); - if (b > 0) { - this.config.decorator.openEmphasis(out); - out.append(temp); - this.config.decorator.closeEmphasis(out); - pos = b; - } else { - out.append(in.charAt(pos)); - } - break; - case STRONG_STAR: - case STRONG_UNDERSCORE: - temp.setLength(0); - b = this.recursiveEmitLine(temp, in, pos + 2, mt); - if (b > 0) { - this.config.decorator.openStrong(out); - out.append(temp); - this.config.decorator.closeStrong(out); - pos = b + 1; - } else { - out.append(in.charAt(pos)); - } - break; - case STRIKEOUT: - temp.setLength(0); - b = this.recursiveEmitLine(temp, in, pos + 2, mt); - if (b > 0) { - this.config.decorator.openStrikeout(out); - out.append(temp); - this.config.decorator.closeStrikeout(out); - pos = b + 1; - } else { - out.append(in.charAt(pos)); - } - break; - case SUPER: - temp.setLength(0); - b = this.recursiveEmitLine(temp, in, pos + 1, mt); - if (b > 0) { - this.config.decorator.openSuper(out); - out.append(temp); - this.config.decorator.closeSuper(out); - pos = b; - } else { - out.append(in.charAt(pos)); - } - break; - case CODE_SINGLE: - case CODE_DOUBLE: - a = pos + (mt == MarkToken.CODE_DOUBLE ? 2 : 1); - b = this.findToken(in, a, mt); - if (b > 0) { - pos = b + (mt == MarkToken.CODE_DOUBLE ? 1 : 0); - while (a < b && in.charAt(a) == ' ') { - a++; - } - if (a < b) { - while (in.charAt(b - 1) == ' ') { - b--; - } - this.config.decorator.openCodeSpan(out); - Utils.appendCode(out, in, a, b); - this.config.decorator.closeCodeSpan(out); - } - } else { - out.append(in.charAt(pos)); - } - break; - case HTML: - temp.setLength(0); - b = this.checkHtml(temp, in, pos); - if (b > 0) { - out.append(temp); - pos = b; - } else { - out.append("<"); - } - break; - case ENTITY: - temp.setLength(0); - b = checkEntity(temp, in, pos); - if (b > 0) { - out.append(temp); - pos = b; - } else { - out.append("&"); - } - break; - case GFM_AUTOLINK: - if (token == MarkToken.LINK) { - out.append(in.charAt(pos)); - break; - } - temp.setLength(0); - b = checkGFMAutolink(temp, in, pos); - if (b > 0) { - String url = temp.toString(); - this.config.decorator.openLink(out); - out.append(" href=\""); - Utils.appendValue(out, url, 0, url.length()); - out.append("\">"); - Utils.appendCode(out, url, 0, url.length()); - this.config.decorator.closeLink(out); - pos += url.length() - 1; - } else { - out.append(in.charAt(pos)); - } - break; - case X_LINK_OPEN: - temp.setLength(0); - b = this.recursiveEmitLine(temp, in, pos + 2, MarkToken.X_LINK_CLOSE); - if (b > 0 && this.config.specialLinkEmitter != null) { - this.config.specialLinkEmitter.emitSpan(out, temp.toString()); - pos = b + 1; - } else { - out.append(in.charAt(pos)); - } - break; - case X_COPY: - out.append("©"); - pos += 2; - break; - case X_REG: - out.append("®"); - pos += 2; - break; - case X_TRADE: - out.append("™"); - pos += 3; - break; - case X_NDASH: - out.append("–"); - pos++; - break; - case X_MDASH: - out.append("—"); - pos += 2; - break; - case X_HELLIP: - out.append("…"); - pos += 2; - break; - case X_LAQUO: - out.append("«"); - pos++; - break; - case X_RAQUO: - out.append("»"); - pos++; - break; - case X_RDQUO: - out.append("”"); - break; - case X_LDQUO: - out.append("“"); - break; - case ESCAPE: - pos++; - //$FALL-THROUGH$ - default: - out.append(in.charAt(pos)); - break; - } - pos++; - } - return -1; - } - - /** - * Turns every whitespace character into a space character. - * - * @param c Character to check - * @return 32 is c was a whitespace, c otherwise - */ - private static char whitespaceToSpace(final char c) { - return Character.isWhitespace(c) ? ' ' : c; - } - - /** - * Check if there is any markdown Token. - * - * @param in Input String. - * @param pos Starting position. - * @return The Token. - */ - private MarkToken getToken(final String in, final int pos) { - final char c0 = pos > 0 ? whitespaceToSpace(in.charAt(pos - 1)) : ' '; - final char c = whitespaceToSpace(in.charAt(pos)); - final char c1 = pos + 1 < in.length() ? whitespaceToSpace(in.charAt(pos + 1)) : ' '; - final char c2 = pos + 2 < in.length() ? whitespaceToSpace(in.charAt(pos + 2)) : ' '; - final char c3 = pos + 3 < in.length() ? whitespaceToSpace(in.charAt(pos + 3)) : ' '; - - switch (c) { - case '*': - if (c1 == '*') { - return c0 != ' ' || c2 != ' ' ? MarkToken.STRONG_STAR : MarkToken.EM_STAR; - } - return c0 != ' ' || c1 != ' ' ? MarkToken.EM_STAR : MarkToken.NONE; - case '_': - if (c1 == '_') { - return c0 != ' ' || c2 != ' ' ? MarkToken.STRONG_UNDERSCORE : MarkToken.EM_UNDERSCORE; - } - if (this.useExtensions) { - return Character.isLetterOrDigit(c0) && c0 != '_' && Character.isLetterOrDigit(c1) ? MarkToken.NONE - : MarkToken.EM_UNDERSCORE; - } - return c0 != ' ' || c1 != ' ' ? MarkToken.EM_UNDERSCORE : MarkToken.NONE; - case '~': - if (this.useExtensions && c1 == '~') { - return MarkToken.STRIKEOUT; - } - return MarkToken.NONE; - case '!': - if (c1 == '[') { - return MarkToken.IMAGE; - } - return MarkToken.NONE; - case '[': - if (this.useExtensions && c1 == '[') { - return MarkToken.X_LINK_OPEN; - } - return MarkToken.LINK; - case ']': - if (this.useExtensions && c1 == ']') { - return MarkToken.X_LINK_CLOSE; - } - return MarkToken.NONE; - case '`': - return c1 == '`' ? MarkToken.CODE_DOUBLE : MarkToken.CODE_SINGLE; - case '\\': - switch (c1) { - case '\\': - case '[': - case ']': - case '(': - case ')': - case '{': - case '}': - case '#': - case '"': - case '\'': - case '.': - case '>': - case '<': - case '*': - case '+': - case '-': - case '_': - case '!': - case '`': - case '~': - case '^': - return MarkToken.ESCAPE; - default: - return MarkToken.NONE; - } - case '<': - if (this.useExtensions && c1 == '<') { - return MarkToken.X_LAQUO; - } - return MarkToken.HTML; - case '&': - return MarkToken.ENTITY; - default: - if (this.useExtensions) { - if (c0 == ' ' && c == 'h' && c1 == 't' && c2 == 't' && c3 == 'p' - && in.startsWith("://", (pos + 4 < in.length() && in.charAt(pos + 4) == 's') ? pos + 5 : pos + 4)) { - return MarkToken.GFM_AUTOLINK; - } - switch (c) { - case '-': - if (c1 == '-') { - return c2 == '-' ? MarkToken.X_MDASH : MarkToken.X_NDASH; - } - break; - case '^': - return c0 == '^' || c1 == '^' ? MarkToken.NONE : MarkToken.SUPER; - case '>': - if (c1 == '>') { - return MarkToken.X_RAQUO; - } - break; - case '.': - if (c1 == '.' && c2 == '.') { - return MarkToken.X_HELLIP; - } - break; - case '(': - if (c1 == 'C' && c2 == ')') { - return MarkToken.X_COPY; - } - if (c1 == 'R' && c2 == ')') { - return MarkToken.X_REG; - } - if (c1 == 'T' & c2 == 'M' & c3 == ')') { - return MarkToken.X_TRADE; - } - break; - case '"': - if (!Character.isLetterOrDigit(c0) && c1 != ' ') { - return MarkToken.X_LDQUO; - } - if (c0 != ' ' && !Character.isLetterOrDigit(c1)) { - return MarkToken.X_RDQUO; - } - break; - } - } - return MarkToken.NONE; - } - } - - /** - * Writes a set of markdown lines into the StringBuilder. - * - * @param out The StringBuilder to write to. - * @param lines The lines to write. - */ - private void emitMarkedLines(final StringBuilder out, final Line lines) { - final StringBuilder in = new StringBuilder(); - Line line = lines; - while (line != null) { - if (!line.isEmpty) { - in.append(line.value.substring(line.leading, line.value.length() - line.trailing)); - if (line.trailing >= 2) { - in.append("
"); - } - } - if (line.next != null) { - in.append('\n'); - } - line = line.next; - } - - this.recursiveEmitLine(out, in.toString(), 0, MarkToken.NONE); - } - - /** - * Writes a set of raw lines into the StringBuilder. - * - * @param out The StringBuilder to write to. - * @param lines The lines to write. - */ - private void emitRawLines(final StringBuilder out, final Line lines) { - Line line = lines; - if (this.config.safeMode) { - final StringBuilder temp = new StringBuilder(); - while (line != null) { - if (!line.isEmpty) { - temp.append(line.value); - } - temp.append('\n'); - line = line.next; - } - final String in = temp.toString(); - for (int pos = 0; pos < in.length(); pos++) { - if (in.charAt(pos) == '<') { - temp.setLength(0); - final int t = Utils.readXML(temp, in, pos, this.config.safeMode); - if (t != -1) { - out.append(temp); - pos = t; - } else { - out.append(in.charAt(pos)); - } - } else { - out.append(in.charAt(pos)); - } - } - } else { - while (line != null) { - if (!line.isEmpty) { - out.append(line.value); - } - out.append('\n'); - line = line.next; - } - } - } - - /** - * Writes a code block into the StringBuilder. - * - * @param out The StringBuilder to write to. - * @param lines The lines to write. - * @param meta Meta information. - */ - private void emitCodeLines(final StringBuilder out, final Line lines, final String meta, final boolean removeIndent) { - Line line = lines; - if (this.config.codeBlockEmitter != null) { - final ArrayList list = new ArrayList(); - while (line != null) { - if (line.isEmpty) { - list.add(""); - } else { - list.add(removeIndent ? line.value.substring(4) : line.value); - } - line = line.next; - } - this.config.codeBlockEmitter.emitBlock(out, list, meta); - } else { - while (line != null) { - if (!line.isEmpty) { - for (int i = removeIndent ? 4 : 0; i < line.value.length(); i++) { - final char c; - switch (c = line.value.charAt(i)) { - case '&': - out.append("&"); - break; - case '<': - out.append("<"); - break; - case '>': - out.append(">"); - break; - default: - out.append(c); - break; - } - } - } - out.append('\n'); - line = line.next; - } - } - } - - private void emitTableLines(final StringBuilder out, final Line lines) { - Line line = lines; - if (line == null) { - return; - } - TableDef table = (TableDef) line.data; - Decorator decorator = this.config.decorator; - // emit header row - decorator.openTableHead(out); - decorator.openTableRow(out); - int i = 0; - for (String cellText : table.header) { - decorator.openTableHeader(out, table.getAlign(i++)); - recursiveEmitLine(out, cellText, 0, MarkToken.NONE); - decorator.closeTableHeader(out); - } - decorator.closeTableRow(out); - decorator.closeTableHead(out); - // emit rows - decorator.openTableBody(out); - for (LinkedList row : table.rows) { - decorator.openTableRow(out); - i = 0; - for (String cellText : row) { - decorator.openTableData(out, table.getAlign(i++)); - recursiveEmitLine(out, cellText, 0, MarkToken.NONE); - decorator.closeTableData(out); - } - decorator.closeTableRow(out); - } - decorator.closeTableBody(out); - } - - private static int checkGFMAutolink(final StringBuilder out, final String in, final int start) { - int s = in.indexOf("://", start) + 3; - if (s == -1) { - return -1; - } - - // find first non space preceding char - int i = start - 1; - char c = 0; - while (i > -1) { - c = in.charAt(i); - if (!Character.isWhitespace(c)) { - break; - } - i--; - } - // the following characters are not allowed to precede the url - if (c == '>' || c == '<' || c == '(' || c == '[' || c == '"' || c == '\'') { - return -1; - } - - // The links cannot contains: ", ', ), <, > or spaces. I they end in \s*", \s*', \s*), >\s* or\s*< they are not treated as a link - // Also a link must start with a space (or at beginning of the line) - // to avoid conflicting with real markdown link definitions: [..](url "title") - - int len = in.length(); - c = 0; - i = s; - out.append(in, start, s); - while (i < len) { - c = in.charAt(i); - if (c == '>' || c == '<' || c == '"' || c == '\'' || c == ')') { - return -1; // not an GFM auto link - } - if (Character.isWhitespace(c)) { - // get the first non space char - int k = Utils.skipSpaces(in, i + 1); - if (k > -1) { - c = in.charAt(i); - if (c == '>' || c == '<' || c == '"' || c == '\'' || c == ')') { - return -1; // not an GFM auto link - } - } - break; - } - out.append(c); - i++; - } - - // remove any ending punctuation marks if needed - if (c == '.' || c == ',' || c == ';' || c == '?' || c == '!' || c == ':') { - out.setLength(out.length() - 1); - i--; - } - if (i <= s) { - // invalid url - return -1; - } - return i; - } - -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/HTML.java b/contentstack/src/main/java/com/contentstack/txtmark/HTML.java deleted file mode 100755 index 4cdd1c68..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/HTML.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.util.HashMap; -import java.util.HashSet; - -/** - * HTML utility class. - * - * @author René Jeschke - */ -class HTML { - /** - * List of valid HTML/XML entity names. - */ - private final static String[] ENTITY_NAMES = { - "Â", "â", "´", "Æ", "æ", "À", "à", "ℵ", - "Α", "α", "&", "∧", "∠", "'", "Å", "å", - "≈", "Ã", "ã", "Ä", "ä", "„", "Β", "β", - "¦", "•", "∩", "Ç", "ç", "¸", "¢", "Χ", - "χ", "ˆ", "♣", "≅", "©", "↵", "∪", "¤", - "‡", "†", "⇓", "↓", "°", "Δ", "δ", "♦", - "÷", "É", "é", "Ê", "ê", "È", "è", "∅", - " ", " ", "Ε", "ε", "≡", "Η", "η", "Ð", - "ð", "Ë", "ë", "€", "∃", "ƒ", "∀", "½", - "¼", "¾", "⁄", "Γ", "γ", "≥", ">", "⇔", - "↔", "♥", "…", "Í", "í", "Î", "î", "¡", - "Ì", "ì", "ℑ", "∞", "∫", "Ι", "ι", "¿", - "∈", "Ï", "ï", "Κ", "κ", "Λ", "λ", "⟨", - "«", "⇐", "←", "⌈", "“", "≤", "⌊", "∗", - "◊", "‎", "‹", "‘", "<", "¯", "—", "µ", - "·", "−", "Μ", "μ", "∇", " ", "–", "≠", - "∋", "¬", "∉", "⊄", "Ñ", "ñ", "Ν", "ν", - "Ó", "ó", "Ô", "ô", "Œ", "œ", "Ò", "ò", - "‾", "Ω", "ω", "Ο", "ο", "⊕", "∨", "ª", - "º", "Ø", "ø", "Õ", "õ", "⊗", "Ö", "ö", - "¶", "∂", "‰", "⊥", "Φ", "φ", "Π", "π", - "ϖ", "±", "£", "″", "′", "∏", "∝", "Ψ", - "ψ", """, "√", "⟩", "»", "⇒", "→", "⌉", - "”", "ℜ", "®", "⌋", "Ρ", "ρ", "‏", "›", - "’", "‚", "Š", "š", "⋅", "§", "­", "Σ", - "σ", "ς", "∼", "♠", "⊂", "⊆", "∑", "⊃", - "¹", "²", "³", "⊇", "ß", "Τ", "τ", "∴", - "Θ", "θ", "ϑ", " ", "þ", "˜", "×", "™", - "Ú", "ú", "⇑", "↑", "Û", "û", "Ù", "ù", - "¨", "ϒ", "Υ", "υ", "Ü", "ü", "℘", "Ξ", - "ξ", "Ý", "ý", "¥", "Ÿ", "ÿ", "Ζ", "ζ", - "‍", "‌" - }; - /** - * Characters corresponding to ENTITY_NAMES. - */ - private final static char[] ENTITY_CHARS = { - '\u00C2', '\u00E2', '\u00B4', '\u00C6', '\u00E6', '\u00C0', '\u00E0', '\u2135', - '\u0391', '\u03B1', '\u0026', '\u2227', '\u2220', '\'', '\u00C5', '\u00E5', - '\u2248', '\u00C3', '\u00E3', '\u00C4', '\u00E4', '\u201E', '\u0392', '\u03B2', - '\u00A6', '\u2022', '\u2229', '\u00C7', '\u00E7', '\u00B8', '\u00A2', '\u03A7', - '\u03C7', '\u02C6', '\u2663', '\u2245', '\u00A9', '\u21B5', '\u222A', '\u00A4', - '\u2021', '\u2020', '\u21D3', '\u2193', '\u00B0', '\u0394', '\u03B4', '\u2666', - '\u00F7', '\u00C9', '\u00E9', '\u00CA', '\u00EA', '\u00C8', '\u00E8', '\u2205', - '\u2003', '\u2002', '\u0395', '\u03B5', '\u2261', '\u0397', '\u03B7', '\u00D0', - '\u00F0', '\u00CB', '\u00EB', '\u20AC', '\u2203', '\u0192', '\u2200', '\u00BD', - '\u00BC', '\u00BE', '\u2044', '\u0393', '\u03B3', '\u2265', '\u003E', '\u21D4', - '\u2194', '\u2665', '\u2026', '\u00CD', '\u00ED', '\u00CE', '\u00EE', '\u00A1', - '\u00CC', '\u00EC', '\u2111', '\u221E', '\u222B', '\u0399', '\u03B9', '\u00BF', - '\u2208', '\u00CF', '\u00EF', '\u039A', '\u03BA', '\u039B', '\u03BB', '\u2329', - '\u00AB', '\u21D0', '\u2190', '\u2308', '\u201C', '\u2264', '\u230A', '\u2217', - '\u25CA', '\u200E', '\u2039', '\u2018', '\u003C', '\u00AF', '\u2014', '\u00B5', - '\u00B7', '\u2212', '\u039C', '\u03BC', '\u2207', '\u00A0', '\u2013', '\u2260', - '\u220B', '\u00AC', '\u2209', '\u2284', '\u00D1', '\u00F1', '\u039D', '\u03BD', - '\u00D3', '\u00F3', '\u00D4', '\u00F4', '\u0152', '\u0153', '\u00D2', '\u00F2', - '\u203E', '\u03A9', '\u03C9', '\u039F', '\u03BF', '\u2295', '\u2228', '\u00AA', - '\u00BA', '\u00D8', '\u00F8', '\u00D5', '\u00F5', '\u2297', '\u00D6', '\u00F6', - '\u00B6', '\u2202', '\u2030', '\u22A5', '\u03A6', '\u03C6', '\u03A0', '\u03C0', - '\u03D6', '\u00B1', '\u00A3', '\u2033', '\u2032', '\u220F', '\u221D', '\u03A8', - '\u03C8', '\u0022', '\u221A', '\u232A', '\u00BB', '\u21D2', '\u2192', '\u2309', - '\u201D', '\u211C', '\u00AE', '\u230B', '\u03A1', '\u03C1', '\u200F', '\u203A', - '\u2019', '\u201A', '\u0160', '\u0161', '\u22C5', '\u00A7', '\u00AD', '\u03A3', - '\u03C3', '\u03C2', '\u223C', '\u2660', '\u2282', '\u2286', '\u2211', '\u2283', - '\u00B9', '\u00B2', '\u00B3', '\u2287', '\u00DF', '\u03A4', '\u03C4', '\u2234', - '\u0398', '\u03B8', '\u03D1', '\u00DE', '\u00FE', '\u02DC', '\u00D7', '\u2122', - '\u00DA', '\u00FA', '\u21D1', '\u2191', '\u00DB', '\u00FB', '\u00D9', '\u00F9', - '\u00A8', '\u03D2', '\u03A5', '\u03C5', '\u00DC', '\u00FC', '\u2118', '\u039E', - '\u03BE', '\u00DD', '\u00FD', '\u00A5', '\u0178', '\u00FF', '\u0396', '\u03B6', - '\u200D', '\u200C' - }; - /** - * Valid markdown link prefixes for auto links. - */ - private final static String[] LINK_PREFIXES = { - "http", "https", - "ftp", "ftps" - }; - - /** - * HTML block level elements. - */ - private final static HTMLElement[] BLOCK_ELEMENTS = { - HTMLElement.address, - HTMLElement.blockquote, - HTMLElement.del, HTMLElement.div, HTMLElement.dl, - HTMLElement.fieldset, HTMLElement.form, - HTMLElement.h1, HTMLElement.h2, HTMLElement.h3, HTMLElement.h4, HTMLElement.h5, HTMLElement.h6, HTMLElement.hr, - HTMLElement.ins, - HTMLElement.noscript, - HTMLElement.ol, - HTMLElement.p, HTMLElement.pre, - HTMLElement.table, - HTMLElement.ul - }; - - /** - * HTML unsafe elements. - */ - private final static HTMLElement[] UNSAFE_ELEMENTS = { - HTMLElement.applet, - HTMLElement.head, - HTMLElement.html, - HTMLElement.body, - HTMLElement.frame, - HTMLElement.frameset, - HTMLElement.iframe, - HTMLElement.script, - HTMLElement.object, - }; - - /** - * Character to entity encoding map. - */ - private final static HashMap encodeMap = new HashMap(); - /** - * Entity to character decoding map. - */ - private final static HashMap decodeMap = new HashMap(); - /** - * Set of valid HTML tags. - */ - private final static HashSet HTML_ELEMENTS = new HashSet(); - /** - * Set of unsafe HTML tags. - */ - private final static HashSet HTML_UNSAFE = new HashSet(); - /** - * Set of HTML block level tags. - */ - private final static HashSet HTML_BLOCK_ELEMENTS = new HashSet(); - /** - * Set of valid markdown link prefixes. - */ - private final static HashSet LINK_PREFIX = new HashSet(); - - static { - for (final HTMLElement h : HTMLElement.values()) { - HTML_ELEMENTS.add(h.toString()); - } - for (final HTMLElement h : UNSAFE_ELEMENTS) { - HTML_UNSAFE.add(h.toString()); - } - for (final HTMLElement h : BLOCK_ELEMENTS) { - HTML_BLOCK_ELEMENTS.add(h.toString()); - } - for (int i = 0; i < ENTITY_NAMES.length; i++) { - encodeMap.put(ENTITY_CHARS[i], ENTITY_NAMES[i]); - decodeMap.put(ENTITY_NAMES[i], ENTITY_CHARS[i]); - } - for (int i = 0; i < LINK_PREFIXES.length; i++) { - LINK_PREFIX.add(LINK_PREFIXES[i]); - } - } - - /** - * Constructor. (Singleton) - */ - private HTML() { - // - } - - /** - * @param value String to check. - * @return Returns true if the given String is a link prefix. - */ - public final static boolean isLinkPrefix(final String value) { - return LINK_PREFIX.contains(value); - } - - /** - * @param value String to check. - * @return Returns true if the given String is an entity. - */ - public final static boolean isEntity(final String value) { - return decodeMap.containsKey(value); - } - - /** - * @param value String to check. - * @return Returns true if the given String is a HTML tag. - */ - public final static boolean isHtmlElement(final String value) { - return HTML_ELEMENTS.contains(value); - } - - /** - * @param value String to check. - * @return Returns true if the given String is a HTML block - * level tag. - */ - public final static boolean isHtmlBlockElement(final String value) { - return HTML_BLOCK_ELEMENTS.contains(value); - } - - /** - * @param value String to check. - * @return Returns true if the given String is an unsafe HTML - * tag. - */ - public final static boolean isUnsafeHtmlElement(final String value) { - return HTML_UNSAFE.contains(value); - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/HTMLElement.java b/contentstack/src/main/java/com/contentstack/txtmark/HTMLElement.java deleted file mode 100755 index 157ba9de..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/HTMLElement.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Enum of HTML tags. - * - * @author Shailesh Mishra - */ -enum HTMLElement { - NONE, - a, abbr, acronym, address, applet, area, - b, base, basefont, bdo, big, blockquote, body, br, button, - caption, cite, code, col, colgroup, - dd, del, dfn, div, dl, dt, - em, - fieldset, font, form, frame, frameset, - h1, h2, h3, h4, h5, h6, head, hr, html, - i, iframe, img, input, ins, - kbd, - label, legend, li, link, - map, meta, - noscript, - object, ol, optgroup, option, - p, param, pre, - q, - s, samp, script, select, small, span, strike, strong, style, sub, sup, - table, tbody, td, textarea, tfoot, th, thead, title, tr, tt, - u, ul, - var -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Line.java b/contentstack/src/main/java/com/contentstack/txtmark/Line.java deleted file mode 100755 index 0c30fbd1..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Line.java +++ /dev/null @@ -1,512 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.util.LinkedList; - -/** - * This class represents a text line. - * - *

- * It also provides methods for processing and analyzing a line. - *

- * - * @author René Jeschke - */ -class Line { - /** - * Current cursor position. - */ - public int pos; - /** - * Leading and trailing spaces. - */ - public int leading = 0, trailing = 0; - /** - * Is this line empty? - */ - public boolean isEmpty = true; - /** - * This line's value. - */ - public String value = null; - /** - * Previous and next line. - */ - public Line previous = null, next = null; - /** - * Is previous/next line empty? - */ - public boolean prevEmpty, nextEmpty; - /** - * Final line of a XML block. - */ - public Line xmlEndLine; - /** - * additional data associated with that line if any - */ - public Object data = null; - - /** - * Constructor. - */ - public Line() { - // - } - - /** - * Calculates leading and trailing spaces. Also sets empty if needed. - */ - public void init() { - this.leading = 0; - while (this.leading < this.value.length() && this.value.charAt(this.leading) == ' ') { - this.leading++; - } - - if (this.leading == this.value.length()) { - this.setEmpty(); - } else { - this.isEmpty = false; - this.trailing = 0; - while (this.value.charAt(this.value.length() - this.trailing - 1) == ' ') { - this.trailing++; - } - } - } - - /** - * Recalculate leading spaces. - */ - public void initLeading() { - this.leading = 0; - while (this.leading < this.value.length() && this.value.charAt(this.leading) == ' ') { - this.leading++; - } - - if (this.leading == this.value.length()) { - this.setEmpty(); - } - } - - /** - * Skips spaces. - * - * @return false if end of line is reached - */ - public boolean skipSpaces() { - while (this.pos < this.value.length() && this.value.charAt(this.pos) == ' ') { - this.pos++; - } - return this.pos < this.value.length(); - } - - /** - * Reads chars from this line until any 'end' char is reached. - * - * @param end Delimiting character(s) - * @return The read String or null if no 'end' char was - * reached. - */ - public String readUntil(final char... end) { - final StringBuilder sb = new StringBuilder(); - int pos = this.pos; - while (pos < this.value.length()) { - final char ch = this.value.charAt(pos); - if (ch == '\\' && pos + 1 < this.value.length()) { - final char c; - switch (c = this.value.charAt(pos + 1)) { - case '\\': - case '[': - case ']': - case '(': - case ')': - case '{': - case '}': - case '#': - case '"': - case '\'': - case '.': - case '>': - case '*': - case '+': - case '-': - case '_': - case '!': - case '`': - case '~': - sb.append(c); - pos++; - break; - default: - sb.append(ch); - break; - } - } else { - boolean endReached = false; - for (int n = 0; n < end.length; n++) { - if (ch == end[n]) { - endReached = true; - break; - } - } - if (endReached) { - break; - } - sb.append(ch); - } - pos++; - } - - final char ch = pos < this.value.length() ? this.value.charAt(pos) : '\n'; - for (int n = 0; n < end.length; n++) { - if (ch == end[n]) { - this.pos = pos; - return sb.toString(); - } - } - return null; - } - - /** - * Marks this line empty. Also sets previous/next line's empty attributes. - */ - public void setEmpty() { - this.value = ""; - this.leading = this.trailing = 0; - this.isEmpty = true; - if (this.previous != null) { - this.previous.nextEmpty = true; - } - if (this.next != null) { - this.next.prevEmpty = true; - } - } - - /** - * Counts the amount of 'ch' in this line. - * - * @param ch The char to count. - * @return A value > 0 if this line only consists of 'ch' end spaces. - */ - private int countChars(final char ch) { - int count = 0; - for (int i = 0; i < this.value.length(); i++) { - final char c = this.value.charAt(i); - if (c == ' ') { - continue; - } - if (c == ch) { - count++; - continue; - } - count = 0; - break; - } - return count; - } - - /** - * Counts the amount of 'ch' at the start of this line optionally ignoring - * spaces. - * - * @param ch The char to count. - * @param allowSpaces Whether to allow spaces or not - * @return Number of characters found. - * @since 0.12 - */ - private int countCharsStart(final char ch, final boolean allowSpaces) { - int count = 0; - for (int i = 0; i < this.value.length(); i++) { - final char c = this.value.charAt(i); - if (c == ' ' && allowSpaces) { - continue; - } - if (c == ch) { - count++; - } else { - break; - } - } - return count; - } - - /** - * Gets this line's type. - * - * @param configuration txtmark configuration - * @return The LineType. - */ - public LineType getLineType(final Configuration configuration) { - if (this.isEmpty) { - return LineType.EMPTY; - } - - if (this.leading > 3) { - return LineType.CODE; - } - - if (this.value.charAt(this.leading) == '#') { - return LineType.HEADLINE; - } - - if (this.value.charAt(this.leading) == '>') { - return LineType.BQUOTE; - } - - if (configuration.forceExtendedProfile) { - if (this.value.length() - this.leading - this.trailing > 2) { - if (this.value.charAt(this.leading) == '`' - && this.countCharsStart('`', configuration.allowSpacesInFencedDelimiters) >= 3) { - return LineType.FENCED_CODE; - } - if (this.value.charAt(this.leading) == '~' - && this.countCharsStart('~', configuration.allowSpacesInFencedDelimiters) >= 3) { - return LineType.FENCED_CODE; - } - } - } - - if (this.value.length() - this.leading - this.trailing > 2 - && (this.value.charAt(this.leading) == '*' || this.value.charAt(this.leading) == '-' || this.value - .charAt(this.leading) == '_')) { - if (this.countChars(this.value.charAt(this.leading)) >= 3) { - return LineType.HR; - } - } - - if (this.value.length() - this.leading >= 2 && this.value.charAt(this.leading + 1) == ' ') { - switch (this.value.charAt(this.leading)) { - case '*': - case '-': - case '+': - return LineType.ULIST; - } - } - - if (this.value.length() - this.leading >= 3 && Character.isDigit(this.value.charAt(this.leading))) { - int i = this.leading + 1; - while (i < this.value.length() && Character.isDigit(this.value.charAt(i))) { - i++; - } - if (i + 1 < this.value.length() && this.value.charAt(i) == '.' && this.value.charAt(i + 1) == ' ') { - return LineType.OLIST; - } - } - - if (this.value.charAt(this.leading) == '<') { - if (this.checkHTML()) { - return LineType.XML; - } - } - - if (this.next != null && !this.next.isEmpty) { - if ((this.next.value.charAt(0) == '-') && (this.next.countChars('-') > 0)) { - return LineType.HEADLINE2; - } - if ((this.next.value.charAt(0) == '=') && (this.next.countChars('=') > 0)) { - return LineType.HEADLINE1; - } - if (configuration.forceExtendedProfile && (this.previous == null || this.previous.isEmpty)) { - TableDef table = TableDef.parse(this.value, this.next.value); - if (table != null) { - this.data = table; // attach the table definition to be used later - return LineType.TABLE; - } - } - } - - return LineType.OTHER; - } - - /** - * Reads an XML comment. Sets xmlEndLine. - * - * @param firstLine The Line to start reading from. - * @param start The starting position. - * @return The new position or -1 if it is no valid comment. - */ - private int readXMLComment(final Line firstLine, final int start) { - Line line = firstLine; - if (start + 3 < line.value.length()) { - if (line.value.charAt(2) == '-' && line.value.charAt(3) == '-') { - int pos = start + 4; - while (line != null) { - while (pos < line.value.length() && line.value.charAt(pos) != '-') { - pos++; - } - if (pos == line.value.length()) { - line = line.next; - pos = 0; - } else { - if (pos + 2 < line.value.length()) { - if (line.value.charAt(pos + 1) == '-' && line.value.charAt(pos + 2) == '>') { - this.xmlEndLine = line; - return pos + 3; - } - } - pos++; - } - } - } - } - return -1; - } - - /** - * Checks if this line contains an ID at it's end and removes it from the - * line. - * - * @return The ID or null if no valid ID exists. - */ - public String stripID() { - if (this.isEmpty || this.value.charAt(this.value.length() - this.trailing - 1) != '}') { - return null; - } - int p = this.leading; - boolean found = false; - while (p < this.value.length() && !found) { - switch (this.value.charAt(p)) { - case '\\': - if (p + 1 < this.value.length()) { - switch (this.value.charAt(p + 1)) { - case '{': - p++; - break; - } - } - p++; - break; - case '{': - found = true; - break; - default: - p++; - break; - } - } - - if (found) { - if (p + 1 < this.value.length() && this.value.charAt(p + 1) == '#') { - final int start = p + 2; - p = start; - found = false; - while (p < this.value.length() && !found) { - switch (this.value.charAt(p)) { - case '\\': - if (p + 1 < this.value.length()) { - switch (this.value.charAt(p + 1)) { - case '}': - p++; - break; - } - } - p++; - break; - case '}': - found = true; - break; - default: - p++; - break; - } - } - if (found) { - final String id = this.value.substring(start, p).trim(); - if (this.leading != 0) { - this.value = this.value.substring(0, this.leading) - + this.value.substring(this.leading, start - 2).trim(); - } else { - this.value = this.value.substring(this.leading, start - 2).trim(); - } - this.trailing = 0; - return id.length() > 0 ? id : null; - } - } - } - return null; - } - - /** - * Checks for a valid HTML block. Sets xmlEndLine. - * - * @return true if it is a valid block. - */ - private boolean checkHTML() { - final LinkedList tags = new LinkedList(); - final StringBuilder temp = new StringBuilder(); - int pos = this.leading; - if (this.leading + 1 < this.value.length() && this.value.charAt(this.leading + 1) == '!') { - if (this.readXMLComment(this, this.leading) > 0) { - return true; - } - } - pos = Utils.readXML(temp, this.value, this.leading, false); - String element, tag; - if (pos > -1) { - element = temp.toString(); - temp.setLength(0); - Utils.getXMLTag(temp, element); - tag = temp.toString().toLowerCase(); - if (!HTML.isHtmlBlockElement(tag)) { - return false; - } - if (tag.equals("hr") || element.endsWith("/>")) { - this.xmlEndLine = this; - return true; - } - tags.add(tag); - - Line line = this; - while (line != null) { - while (pos < line.value.length() && line.value.charAt(pos) != '<') { - pos++; - } - if (pos >= line.value.length()) { - line = line.next; - pos = 0; - } else { - temp.setLength(0); - final int newPos = Utils.readXML(temp, line.value, pos, false); - if (newPos > 0) { - element = temp.toString(); - temp.setLength(0); - Utils.getXMLTag(temp, element); - tag = temp.toString().toLowerCase(); - if (HTML.isHtmlBlockElement(tag) && !tag.equals("hr") && !element.endsWith("/>")) { - if (element.charAt(1) == '/') { - if (!tags.getLast().equals(tag)) { - return false; - } - tags.removeLast(); - } else { - tags.addLast(tag); - } - } - if (tags.size() == 0) { - this.xmlEndLine = line; - break; - } - pos = newPos; - } else { - pos++; - } - } - } - return tags.size() == 0; - } - return false; - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/LineType.java b/contentstack/src/main/java/com/contentstack/txtmark/LineType.java deleted file mode 100755 index 1c3356ef..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/LineType.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Line type enumeration. - * - * @author René Jeschke - */ -enum LineType { - /** - * Empty line. - */ - EMPTY, - /** - * Undefined content. - */ - OTHER, - /** - * A markdown headline. - */ - HEADLINE, HEADLINE1, HEADLINE2, - /** - * A code block line. - */ - CODE, - /** - * A list. - */ - ULIST, OLIST, - /** - * A block quote. - */ - BQUOTE, - /** - * A horizontal ruler. - */ - HR, - /** - * Start of a XML block. - */ - XML, - /** - * Fenced code block start/end - */ - FENCED_CODE, - /** - * GFM table - **/ - TABLE -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/LinkRef.java b/contentstack/src/main/java/com/contentstack/txtmark/LinkRef.java deleted file mode 100755 index 9f27835f..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/LinkRef.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * A markdown link reference. - * - * @author René Jeschke - */ -class LinkRef { - /** - * The link. - */ - public final String link; - /** - * The optional comment/title. - */ - public String title; - /** - * Flag indicating that this is an abbreviation. - */ - public final boolean isAbbrev; - - /** - * Constructor. - * - * @param link The link. - * @param title The title (may be null). - */ - public LinkRef(final String link, final String title, final boolean isAbbrev) { - this.link = link; - this.title = title; - this.isAbbrev = isAbbrev; - } - - /** - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return this.link + " \"" + this.title + "\""; - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/MarkToken.java b/contentstack/src/main/java/com/contentstack/txtmark/MarkToken.java deleted file mode 100755 index d974aa0b..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/MarkToken.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -/** - * Markdown token enumeration. - * - * @author René Jeschke - */ -enum MarkToken { - /** - * No token. - */ - NONE, - /** - * * - */ - EM_STAR, // x*x - /** - * _ - */ - EM_UNDERSCORE, // x_x - /** - * ** - */ - STRONG_STAR, // x**x - /** - * __ - */ - STRONG_UNDERSCORE, // x__x - /** - * ~~ - */ - STRIKEOUT, // ~~ - /** - * ` - */ - CODE_SINGLE, // ` - /** - * `` - */ - CODE_DOUBLE, // `` - /** - * [ - */ - LINK, // [ - /** - * < - */ - HTML, // < - /** - * ![ - */ - IMAGE, // ![ - /** - * & - */ - ENTITY, // & - /** - * https?://domain[/path][?query][#hash] - */ - GFM_AUTOLINK, // https?://domain[/path][?query][#hash] - /** - * \ - */ - ESCAPE, // \x - /** - * Extended: ^ - */ - SUPER, // ^ - /** - * Extended: (C) - */ - X_COPY, // (C) - /** - * Extended: (R) - */ - X_REG, // (R) - /** - * Extended: (TM) - */ - X_TRADE, // (TM) - /** - * Extended: << - */ - X_LAQUO, // << - /** - * Extended: >> - */ - X_RAQUO, // >> - /** - * Extended: -- - */ - X_NDASH, // -- - /** - * Extended: --- - */ - X_MDASH, // --- - /** - * Extended: ... - */ - X_HELLIP, // ... - /** - * Extended: "x - */ - X_RDQUO, // " - /** - * Extended: x" - */ - X_LDQUO, // " - /** - * [[ - */ - X_LINK_OPEN, // [[ - /** - * ]] - */ - X_LINK_CLOSE, // ]] -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Processor.java b/contentstack/src/main/java/com/contentstack/txtmark/Processor.java deleted file mode 100755 index fb3f6253..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Processor.java +++ /dev/null @@ -1,842 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; - -/** - * Markdown processor class. - * - *

- * Example usage: - *

- * - *
- * String result = Processor.process("This is ***TXTMARK***");
- * 
- * 
- * - * @author René Jeschke <, rene_jeschke@yahoo.de>, - */ -public class Processor { - /** - * The reader. - */ - private final Reader reader; - /** - * The emitter. - */ - private final Emitter emitter; - /** - * The Configuration. - */ - final Configuration config; - /** - * Extension flag. - */ - private boolean useExtensions = false; - - /** - * Constructor. - * - * @param reader The input reader. - */ - private Processor(final Reader reader, final Configuration config) { - this.reader = reader; - this.config = config; - this.useExtensions = config.forceExtendedProfile; - this.emitter = new Emitter(this.config); - } - - /** - * Transforms an input stream into HTML using the given Configuration. - * - * @param reader The Reader to process. - * @param configuration The Configuration. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration - * @since 0.7 - */ - public final static String process(final Reader reader, final Configuration configuration) throws IOException { - final Processor p = new Processor(!(reader instanceof BufferedReader) ? new BufferedReader(reader) : reader, - configuration); - return p.process(); - } - - /** - * Transforms an input String into HTML using the given Configuration. - * - * @param input The String to process. - * @param configuration The Configuration. - * @return The processed String. - * @see Configuration - * @since 0.7 - */ - public final static String process(final String input, final Configuration configuration) { - try { - return process(new StringReader(input), configuration); - } catch (final IOException e) { - // This _can never_ happen - return null; - } - } - - /** - * Transforms an input file into HTML using the given Configuration. - * - * @param file The File to process. - * @param configuration the Configuration - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration - * @since 0.7 - */ - public final static String process(final File file, final Configuration configuration) throws IOException { - final FileInputStream input = new FileInputStream(file); - final String ret = process(input, configuration); - input.close(); - return ret; - } - - /** - * Transforms an input stream into HTML using the given Configuration. - * - * @param input The InputStream to process. - * @param configuration The Configuration. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration - * @since 0.7 - */ - public final static String process(final InputStream input, final Configuration configuration) throws IOException { - final Processor p = new Processor(new BufferedReader(new InputStreamReader(input, configuration.encoding)), - configuration); - return p.process(); - } - - /** - * Transforms an input String into HTML using the default Configuration. - * - * @param input The String to process. - * @return The processed String. - * @see Configuration#DEFAULT - */ - public final static String process(final String input) { - return process(input, Configuration.DEFAULT); - } - - /** - * Transforms an input String into HTML. - * - * @param input The String to process. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @see Configuration#DEFAULT - */ - public final static String process(final String input, final boolean safeMode) { - return process(input, Configuration.builder().setSafeMode(safeMode).build()); - } - - /** - * Transforms an input String into HTML. - * - * @param input The String to process. - * @param decorator The decorator to use. - * @return The processed String. - * @see Configuration#DEFAULT - */ - public final static String process(final String input, final Decorator decorator) { - return process(input, Configuration.builder().setDecorator(decorator).build()); - } - - /** - * Transforms an input String into HTML. - * - * @param input The String to process. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @see Configuration#DEFAULT - */ - public final static String process(final String input, final Decorator decorator, final boolean safeMode) { - return process(input, Configuration.builder().setDecorator(decorator).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input file into HTML using the default Configuration. - * - * @param file The File to process. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file) throws IOException { - return process(file, Configuration.DEFAULT); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final boolean safeMode) throws IOException { - return process(file, Configuration.builder().setSafeMode(safeMode).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param decorator The decorator to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final Decorator decorator) throws IOException { - return process(file, Configuration.builder().setDecorator(decorator).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final Decorator decorator, final boolean safeMode) - throws IOException { - return process(file, Configuration.builder().setDecorator(decorator).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param encoding The encoding to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final String encoding) throws IOException { - return process(file, Configuration.builder().setEncoding(encoding).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param encoding The encoding to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final String encoding, final boolean safeMode) - throws IOException { - return process(file, Configuration.builder().setEncoding(encoding).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param encoding The encoding to use. - * @param decorator The decorator to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final String encoding, final Decorator decorator) - throws IOException { - return process(file, Configuration.builder().setEncoding(encoding).setDecorator(decorator).build()); - } - - /** - * Transforms an input file into HTML. - * - * @param file The File to process. - * @param encoding The encoding to use. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final File file, final String encoding, final Decorator decorator, - final boolean safeMode) throws IOException { - return process(file, Configuration.builder().setEncoding(encoding).setSafeMode(safeMode) - .setDecorator(decorator).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input) throws IOException { - return process(input, Configuration.DEFAULT); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final boolean safeMode) throws IOException { - return process(input, Configuration.builder().setSafeMode(safeMode).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param decorator The decorator to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final Decorator decorator) throws IOException { - return process(input, Configuration.builder().setDecorator(decorator).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final Decorator decorator, final boolean safeMode) - throws IOException { - return process(input, Configuration.builder().setDecorator(decorator).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param encoding The encoding to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final String encoding) throws IOException { - return process(input, Configuration.builder().setEncoding(encoding).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param encoding The encoding to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final String encoding, final boolean safeMode) - throws IOException { - return process(input, Configuration.builder().setEncoding(encoding).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param encoding The encoding to use. - * @param decorator The decorator to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final String encoding, final Decorator decorator) - throws IOException { - return process(input, Configuration.builder().setEncoding(encoding).setDecorator(decorator).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param input The InputStream to process. - * @param encoding The encoding to use. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final InputStream input, final String encoding, final Decorator decorator, - final boolean safeMode) throws IOException { - return process(input, - Configuration.builder().setEncoding(encoding).setDecorator(decorator).setSafeMode(safeMode).build()); - } - - /** - * Transforms an input stream into HTML using the default Configuration. - * - * @param reader The Reader to process. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final Reader reader) throws IOException { - return process(reader, Configuration.DEFAULT); - } - - /** - * Transforms an input stream into HTML. - * - * @param reader The Reader to process. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final Reader reader, final boolean safeMode) throws IOException { - return process(reader, Configuration.builder().setSafeMode(safeMode).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param reader The Reader to process. - * @param decorator The decorator to use. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final Reader reader, final Decorator decorator) throws IOException { - return process(reader, Configuration.builder().setDecorator(decorator).build()); - } - - /** - * Transforms an input stream into HTML. - * - * @param reader The Reader to process. - * @param decorator The decorator to use. - * @param safeMode Set to true to escape unsafe HTML tags. - * @return The processed String. - * @throws IOException if an IO error occurs - * @see Configuration#DEFAULT - */ - public final static String process(final Reader reader, final Decorator decorator, final boolean safeMode) - throws IOException { - return process(reader, Configuration.builder().setDecorator(decorator).setSafeMode(safeMode).build()); - } - - /** - * Reads all lines from our reader. - *

- * Takes care of markdown link references. - *

- * - * @return A Block containing all lines. - * @throws IOException If an IO error occurred. - */ - private Block readLines() throws IOException { - final Block block = new Block(); - final StringBuilder sb = new StringBuilder(80); - int c = this.reader.read(); - LinkRef lastLinkRef = null; - while (c != -1) { - sb.setLength(0); - int pos = 0; - boolean eol = false; - while (!eol) { - switch (c) { - case -1: - eol = true; - break; - case '\n': - c = this.reader.read(); - if (c == '\r') { - c = this.reader.read(); - } - eol = true; - break; - case '\r': - c = this.reader.read(); - if (c == '\n') { - c = this.reader.read(); - } - eol = true; - break; - case '\t': { - final int np = pos + (4 - (pos & 3)); - while (pos < np) { - sb.append(' '); - pos++; - } - c = this.reader.read(); - break; - } - default: - if (c != '<' || !this.config.panicMode) { - pos++; - sb.append((char) c); - } else { - pos += 4; - sb.append("<"); - } - c = this.reader.read(); - break; - } - } - - final Line line = new Line(); - line.value = sb.toString(); - line.init(); - - // Check for link definitions - boolean isLinkRef = false; - String id = null, link = null, comment = null; - if (!line.isEmpty && line.leading < 4 && line.value.charAt(line.leading) == '[') { - line.pos = line.leading + 1; - // Read ID up to ']' - id = line.readUntil(']'); - // Is ID valid and are there any more characters? - if (id != null && line.pos + 2 < line.value.length()) { - // Check for ':' ([...]:...) - if (line.value.charAt(line.pos + 1) == ':') { - line.pos += 2; - if (!line.skipSpaces()) { - isLinkRef = false; - } - // Check for link syntax - else if (line.value.charAt(line.pos) == '<') { - line.pos++; - link = line.readUntil('>'); - line.pos++; - } else { - link = line.readUntil(' ', '\n'); - } - - // Is link valid? - if (link != null) { - // Any non-whitespace characters following? - if (line.skipSpaces()) { - final char ch = line.value.charAt(line.pos); - // Read comment - if (ch == '\"' || ch == '\'' || ch == '(') { - line.pos++; - comment = line.readUntil(ch == '(' ? ')' : ch); - // Valid linkRef only if comment is valid - if (comment != null) { - isLinkRef = true; - } - } - } else { - isLinkRef = true; - } - } - } - } - } - - // To make compiler happy: add != null checks - if (isLinkRef && id != null && link != null) { - if (id.toLowerCase().equals("$profile$")) { - this.emitter.useExtensions = this.useExtensions = link.toLowerCase().equals("extended"); - lastLinkRef = null; - } else { - // Store linkRef and skip line - final LinkRef lr = new LinkRef(link, comment, comment != null - && (link.length() == 1 && link.charAt(0) == '*')); - this.emitter.addLinkRef(id, lr); - if (comment == null) { - lastLinkRef = lr; - } - } - } else { - comment = null; - // Check for multi-line linkRef - if (!line.isEmpty && lastLinkRef != null) { - line.pos = line.leading; - final char ch = line.value.charAt(line.pos); - if (ch == '\"' || ch == '\'' || ch == '(') { - line.pos++; - comment = line.readUntil(ch == '(' ? ')' : ch); - } - if (comment != null) { - lastLinkRef.title = comment; - } - - lastLinkRef = null; - } - - // No multi-line linkRef, store line - if (comment == null) { - line.pos = 0; - block.appendLine(line); - } - } - } - - return block; - } - - /** - * Initializes a list block by separating it into list item blocks. - * - * @param root The Block to process. - */ - private void initListBlock(final Block root) { - Line line = root.lines; - line = line.next; - while (line != null) { - final LineType t = line.getLineType(this.config); - if ((t == LineType.OLIST || t == LineType.ULIST) - || (!line.isEmpty && (line.prevEmpty && line.leading == 0 && !(t == LineType.OLIST || t == LineType.ULIST)))) { - root.split(line.previous).type = BlockType.LIST_ITEM; - } - line = line.next; - } - root.split(root.lineTail).type = BlockType.LIST_ITEM; - } - - /** - * Recursively process the given Block. - * - * @param root The Block to process. - * @param listMode Flag indicating that we're in a list item block. - */ - private void recurse(final Block root, final boolean listMode) { - Block block, list; - Line line = root.lines; - - if (listMode) { - root.removeListIndent(this.config); - if (this.useExtensions && root.lines != null && root.lines.getLineType(this.config) != LineType.CODE) { - root.id = root.lines.stripID(); - } - } - - while (line != null && line.isEmpty) { - line = line.next; - } - if (line == null) { - return; - } - - while (line != null) { - final LineType type = line.getLineType(this.config); - switch (type) { - case OTHER: { - final boolean wasEmpty = line.prevEmpty; - while (line != null && !line.isEmpty) { - final LineType t = line.getLineType(this.config); - if ((listMode || this.useExtensions) && (t == LineType.OLIST || t == LineType.ULIST)) { - break; - } - if (this.useExtensions && (t == LineType.CODE || t == LineType.FENCED_CODE)) { - break; - } - if (t == LineType.HEADLINE || t == LineType.HEADLINE1 || t == LineType.HEADLINE2 - || t == LineType.HR - || t == LineType.BQUOTE || t == LineType.XML) { - break; - } - line = line.next; - } - final BlockType bt; - if (line != null && !line.isEmpty) { - bt = (listMode && !wasEmpty) ? BlockType.NONE : BlockType.PARAGRAPH; - root.split(line.previous).type = bt; - root.removeLeadingEmptyLines(); - } else { - bt = (listMode && (line == null || !line.isEmpty) && !wasEmpty) ? BlockType.NONE - : BlockType.PARAGRAPH; - root.split(line == null ? root.lineTail : line).type = bt; - root.removeLeadingEmptyLines(); - } - line = root.lines; - break; - } - case CODE: - while (line != null && (line.isEmpty || line.leading > 3)) { - line = line.next; - } - block = root.split(line != null ? line.previous : root.lineTail); - block.type = BlockType.CODE; - block.removeSurroundingEmptyLines(); - break; - case XML: - if (line.previous != null) { - root.split(line.previous); - } - root.split(line.xmlEndLine).type = BlockType.XML; - root.removeLeadingEmptyLines(); - line = root.lines; - break; - case BQUOTE: - while (line != null) { - if (!line.isEmpty - && (line.prevEmpty && line.leading == 0 && line.getLineType(this.config) != LineType.BQUOTE)) { - break; - } - line = line.next; - } - block = root.split(line != null ? line.previous : root.lineTail); - block.type = BlockType.BLOCKQUOTE; - block.removeSurroundingEmptyLines(); - block.removeBlockQuotePrefix(); - this.recurse(block, false); - line = root.lines; - break; - case HR: - if (line.previous != null) { - root.split(line.previous); - } - root.split(line).type = BlockType.RULER; - root.removeLeadingEmptyLines(); - line = root.lines; - break; - case FENCED_CODE: - line = line.next; - while (line != null) { - if (line.getLineType(this.config) == LineType.FENCED_CODE) { - break; - } - // flag? - line = line.next; - } - if (line != null) { - line = line.next; - } - block = root.split(line != null ? line.previous : root.lineTail); - block.type = BlockType.FENCED_CODE; - block.meta = Utils.getMetaFromFence(block.lines.value); - block.lines.setEmpty(); - if (block.lineTail.getLineType(this.config) == LineType.FENCED_CODE) { - block.lineTail.setEmpty(); - } - block.removeSurroundingEmptyLines(); - break; - case HEADLINE: - case HEADLINE1: - case HEADLINE2: - if (line.previous != null) { - root.split(line.previous); - } - if (type != LineType.HEADLINE) { - line.next.setEmpty(); - } - block = root.split(line); - block.type = BlockType.HEADLINE; - if (type != LineType.HEADLINE) { - block.hlDepth = type == LineType.HEADLINE1 ? 1 : 2; - } - if (this.useExtensions) { - block.id = block.lines.stripID(); - } - block.transfromHeadline(); - root.removeLeadingEmptyLines(); - line = root.lines; - break; - case OLIST: - case ULIST: - while (line != null) { - final LineType t = line.getLineType(this.config); - if (!line.isEmpty - && (line.prevEmpty && line.leading == 0 && !(t == LineType.OLIST || t == LineType.ULIST))) { - break; - } - line = line.next; - } - list = root.split(line != null ? line.previous : root.lineTail); - list.type = type == LineType.OLIST ? BlockType.ORDERED_LIST : BlockType.UNORDERED_LIST; - list.lines.prevEmpty = false; - list.lineTail.nextEmpty = false; - list.removeSurroundingEmptyLines(); - list.lines.prevEmpty = list.lineTail.nextEmpty = false; - this.initListBlock(list); - block = list.blocks; - while (block != null) { - this.recurse(block, true); - block = block.next; - } - list.expandListParagraphs(); - break; - case TABLE: - TableDef table = (TableDef) line.data; - // skip the next line - which is the the table divider line - line = line.next.next; - while (line != null) { - if (line.isEmpty) { - break; - } - if (!table.addRow(line.value)) { - break; - } - line = line.next; - } - block = root.split(line != null ? line.previous : root.lineTail); - block.type = BlockType.TABLE; - line = root.lines; - break; - default: - line = line.next; - break; - } - } - } - - /** - * Does all the processing. - * - * @return The processed String. - * @throws IOException If an IO error occurred. - */ - private String process() throws IOException { - final StringBuilder out = new StringBuilder(); - final Block parent = this.readLines(); - parent.removeSurroundingEmptyLines(); - - this.recurse(parent, false); - Block block = parent.blocks; - while (block != null) { - this.emitter.emit(out, block); - block = block.next; - } - - return out.toString(); - } -} diff --git a/contentstack/src/main/java/com/contentstack/txtmark/Run.java b/contentstack/src/main/java/com/contentstack/txtmark/Run.java deleted file mode 100755 index 16aad6f9..00000000 --- a/contentstack/src/main/java/com/contentstack/txtmark/Run.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2011-2015 René Jeschke - * - * 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.contentstack.txtmark; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; - -/** - * Simple class for processing markdown files on the command line. - * - *

- * Usage: - *

- * - *
- * java -cp txtmark.jar txtmark.Run filename [header_footer_file]
- * 
- * 
- * - *

- * The header_footer_file is an optional UTF-8 encoded file - * containing a header and a footer to output around the generated HTML code. - *

- * - *

- * Example: - *

- * - *
- * <?xml version="1.0" encoding="UTF-8"?>
- * <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- *                       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- * <html xmlns="http://www.w3.org/1999/xhtml">
- * <head>
- * <title>markdown</title>
- * <link type="text/css" href="style.css" rel="stylesheet"/>
- * <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
- * </head>
- * <body>
- * <!-- the following line separates header from footer -->
- * <!-- ### -->
- * </body>
- * </html>
- * 
- * 
- * - * @author René Jeschke <rene_jeschke@yahoo.de> - */ -public class Run { - /** - * Static main. - * - * @param args Program arguments. - * @throws IOException If an IO error occurred. - */ - public static void main(final String[] args) throws IOException { - // This is just a _hack_ ... - BufferedReader reader = null; - if (args.length == 0) { - System.err.println("No input file specified."); - System.exit(-1); - } - if (args.length > 1) { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(args[1]), "UTF-8")); - String line = reader.readLine(); - while (line != null && !line.startsWith("