text:
package com.greenlemonmobile.app.ebook.books.views;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PointF;
import android.graphics.RectF;
import android.opengl.GLUtils;

/**
 * Class implementing actual curl/page rendering.
 *
 * @author harism
 */
public class FlipAnimationMesh {

	// Flag for rendering some lines used for developing. Shows
	// curl position and one for the direction from the
	// position given. Comes handy once playing around with different
	// ways for following pointer.
	private static final boolean DRAW_CURL_POSITION = false;
	// Flag for drawing polygon outlines. Using this flag crashes on emulator
	// due to reason unknown to me. Leaving it here anyway as seeing polygon
	// outlines gives good insight how original rectangle is divided.
	private static final boolean DRAW_POLYGON_OUTLINES = false;
	// Flag for enabling shadow rendering.
	private static final boolean DRAW_SHADOW = true;
	// Flag for texture rendering. While this is likely something you
	// don't want to do it's been used for development purposes as texture
	// rendering is rather slow on emulator.
	private static final boolean DRAW_TEXTURE = true;

	// Colors for shadow. Inner one is the color drawn next to surface where
	// shadowed area starts and outer one is color shadow ends to.
	private static final float[] SHADOW_INNER_COLOR = { 0f, 0f, 0f, .5f };
	private static final float[] SHADOW_OUTER_COLOR = { 0f, 0f, 0f, .0f };

	// Let's avoid using 'new' as much as possible. Meaning we introduce arrays
	// once here and reuse them on runtime. Doesn't really have very much effect
	// but avoids some garbage collections from happening.
	private Array<ShadowVertex> mArrDropShadowVertices;
	private Array<Vertex> mArrIntersections;
	private Array<Vertex> mArrOutputVertices;
	private Array<Vertex> mArrRotatedVertices;
	private Array<Double> mArrScanLines;
	private Array<ShadowVertex> mArrSelfShadowVertices;
	private Array<ShadowVertex> mArrTempShadowVertices;
	private Array<Vertex> mArrTempVertices;

	// Buffers for feeding rasterizer.
	private FloatBuffer mBufColors;
	private FloatBuffer mBufCurlPositionLines;
	private FloatBuffer mBufShadowColors;
	private FloatBuffer mBufShadowVertices;
	private FloatBuffer mBufTexCoords;
	private FloatBuffer mBufVertices;

	private int mCurlPositionLinesCount;
	private int mDropShadowCount;

	// Boolean for 'flipping' texture sideways.
	private boolean mFlipTexture = false;
	// Maximum number of split lines used for creating a curl.
	private int mMaxCurlSplits;

	// Bounding rectangle for this mesh. mRectagle[0] = top-left corner,
	// mRectangle[1] = bottom-left, mRectangle[2] = top-right and mRectangle[3]
	// bottom-right.
	private final Vertex[] mRectangle = new Vertex[4];
	private int mSelfShadowCount;

	private boolean mTextureBack = false;
	// Texture ids and other variables.
	private int[] mTextureIds = null;
	private final FlipAnimationPage mTexturePage = new FlipAnimationPage();
	private final RectF mTextureRectBack = new RectF();
	private final RectF mTextureRectFront = new RectF();

	private int mVerticesCountBack;
	private int mVerticesCountFront;

	/**
	 * Constructor for mesh object.
	 *
	 * @param maxCurlSplits
	 *            Maximum number curl can be divided into. The bigger the value
	 *            the smoother curl will be. With the cost of having more
	 *            polygons for drawing.
	 */
	public FlipAnimationMesh(int maxCurlSplits) {
		// There really is no use for 0 splits.
		mMaxCurlSplits = maxCurlSplits < 1 ? 1 : maxCurlSplits;

		mArrScanLines = new Array<Double>(maxCurlSplits + 2);
		mArrOutputVertices = new Array<Vertex>(7);
		mArrRotatedVertices = new Array<Vertex>(4);
		mArrIntersections = new Array<Vertex>(2);
		mArrTempVertices = new Array<Vertex>(7 + 4);
		for (int i = 0; i < 7 + 4; ++i) {
			mArrTempVertices.add(new Vertex());
		}

		if (DRAW_SHADOW) {
			mArrSelfShadowVertices = new Array<ShadowVertex>(
					(mMaxCurlSplits + 2) * 2);
			mArrDropShadowVertices = new Array<ShadowVertex>(
					(mMaxCurlSplits + 2) * 2);
			mArrTempShadowVertices = new Array<ShadowVertex>(
					(mMaxCurlSplits + 2) * 2);
			for (int i = 0; i < (mMaxCurlSplits + 2) * 2; ++i) {
				mArrTempShadowVertices.add(new ShadowVertex());
			}
		}

		// Rectangle consists of 4 vertices. Index 0 = top-left, index 1 =
		// bottom-left, index 2 = top-right and index 3 = bottom-right.
		for (int i = 0; i < 4; ++i) {
			mRectangle[i] = new Vertex();
		}
		// Set up shadow penumbra direction to each vertex. We do fake 'self
		// shadow' calculations based on this information.
		mRectangle[0].mPenumbraX = mRectangle[1].mPenumbraX = mRectangle[1].mPenumbraY = mRectangle[3].mPenumbraY = -1;
		mRectangle[0].mPenumbraY = mRectangle[2].mPenumbraX = mRectangle[2].mPenumbraY = mRectangle[3].mPenumbraX = 1;

		if (DRAW_CURL_POSITION) {
			mCurlPositionLinesCount = 3;
			ByteBuffer hvbb = ByteBuffer
					.allocateDirect(mCurlPositionLinesCount * 2 * 2 * 4);
			hvbb.order(ByteOrder.nativeOrder());
			mBufCurlPositionLines = hvbb.asFloatBuffer();
			mBufCurlPositionLines.position(0);
		}

		// There are 4 vertices from bounding rect, max 2 from adding split line
		// to two corners and curl consists of max mMaxCurlSplits lines each
		// outputting 2 vertices.
		int maxVerticesCount = 4 + 2 + (2 * mMaxCurlSplits);
		ByteBuffer vbb = ByteBuffer.allocateDirect(maxVerticesCount * 3 * 4);
		vbb.order(ByteOrder.nativeOrder());
		mBufVertices = vbb.asFloatBuffer();
		mBufVertices.position(0);

		if (DRAW_TEXTURE) {
			ByteBuffer tbb = ByteBuffer
					.allocateDirect(maxVerticesCount * 2 * 4);
			tbb.order(ByteOrder.nativeOrder());
			mBufTexCoords = tbb.asFloatBuffer();
			mBufTexCoords.position(0);
		}

		ByteBuffer cbb = ByteBuffer.allocateDirect(maxVerticesCount * 4 * 4);
		cbb.order(ByteOrder.nativeOrder());
		mBufColors = cbb.asFloatBuffer();
		mBufColors.position(0);

		if (DRAW_SHADOW) {
			int maxShadowVerticesCount = (mMaxCurlSplits + 2) * 2 * 2;
			ByteBuffer scbb = ByteBuffer
					.allocateDirect(maxShadowVerticesCount * 4 * 4);
			scbb.order(ByteOrder.nativeOrder());
			mBufShadowColors = scbb.asFloatBuffer();
			mBufShadowColors.position(0);

			ByteBuffer sibb = ByteBuffer
					.allocateDirect(maxShadowVerticesCount * 3 * 4);
			sibb.order(ByteOrder.nativeOrder());
			mBufShadowVertices = sibb.asFloatBuffer();
			mBufShadowVertices.position(0);

			mDropShadowCount = mSelfShadowCount = 0;
		}
	}

	/**
	 * Adds vertex to buffers.
	 */
	private void addVertex(Vertex vertex) {
		mBufVertices.put((float) vertex.mPosX);
		mBufVertices.put((float) vertex.mPosY);
		mBufVertices.put((float) vertex.mPosZ);
		mBufColors.put(vertex.mColorFactor * Color.red(vertex.mColor) / 255f);
		mBufColors.put(vertex.mColorFactor * Color.green(vertex.mColor) / 255f);
		mBufColors.put(vertex.mColorFactor * Color.blue(vertex.mColor) / 255f);
		mBufColors.put(Color.alpha(vertex.mColor) / 255f);
		if (DRAW_TEXTURE) {
			mBufTexCoords.put((float) vertex.mTexX);
			mBufTexCoords.put((float) vertex.mTexY);
		}
	}

	/**
	 * Sets curl for this mesh.
	 *
	 * @param curlPos
	 *            Position for curl 'center'. Can be any point on line collinear
	 *            to curl.
	 * @param curlDir
	 *            Curl direction, should be normalized.
	 * @param radius
	 *            Radius of curl.
	 */
	public synchronized void curl(PointF curlPos, PointF curlDir, double radius) {

		// First add some 'helper' lines used for development.
		if (DRAW_CURL_POSITION) {
			mBufCurlPositionLines.position(0);

			mBufCurlPositionLines.put(curlPos.x);
			mBufCurlPositionLines.put(curlPos.y - 1.0f);
			mBufCurlPositionLines.put(curlPos.x);
			mBufCurlPositionLines.put(curlPos.y + 1.0f);
			mBufCurlPositionLines.put(curlPos.x - 1.0f);
			mBufCurlPositionLines.put(curlPos.y);
			mBufCurlPositionLines.put(curlPos.x + 1.0f);
			mBufCurlPositionLines.put(curlPos.y);

			mBufCurlPositionLines.put(curlPos.x);
			mBufCurlPositionLines.put(curlPos.y);
			mBufCurlPositionLines.put(curlPos.x + curlDir.x * 2);
			mBufCurlPositionLines.put(curlPos.y + curlDir.y * 2);

			mBufCurlPositionLines.position(0);
		}

		// Actual 'curl' implementation starts here.
		mBufVertices.position(0);
		mBufColors.position(0);
		if (DRAW_TEXTURE) {
			mBufTexCoords.position(0);
		}

		// Calculate curl angle from direction.
		double curlAngle = Math.acos(curlDir.x);
		curlAngle = curlDir.y > 0 ? -curlAngle : curlAngle;

		// Initiate rotated rectangle which's is translated to curlPos and
		// rotated so that curl direction heads to right (1,0). Vertices are
		// ordered in ascending order based on x -coordinate at the same time.
		// And using y -coordinate in very rare case in which two vertices have
		// same x -coordinate.
		mArrTempVertices.addAll(mArrRotatedVertices);
		mArrRotatedVertices.clear();
		for (int i = 0; i < 4; ++i) {
			Vertex v = mArrTempVertices.remove(0);
			v.set(mRectangle[i]);
			v.translate(-curlPos.x, -curlPos.y);
			v.rotateZ(-curlAngle);
			int j = 0;
			for (; j < mArrRotatedVertices.size(); ++j) {
				Vertex v2 = mArrRotatedVertices.get(j);
				if (v.mPosX > v2.mPosX) {
					break;
				}
				if (v.mPosX == v2.mPosX && v.mPosY > v2.mPosY) {
					break;
				}
			}
			mArrRotatedVertices.add(j, v);
		}

		// Rotated rectangle lines/vertex indices. We need to find bounding
		// lines for rotated rectangle. After sorting vertices according to
		// their x -coordinate we don't have to worry about vertices at indices
		// 0 and 1. But due to inaccuracy it's possible vertex 3 is not the
		// opposing corner from vertex 0. So we are calculating distance from
		// vertex 0 to vertices 2 and 3 - and altering line indices if needed.
		// Also vertices/lines are given in an order first one has x -coordinate
		// at least the latter one. This property is used in getIntersections to
		// see if there is an intersection.
		int lines[][] = { { 0, 1 }, { 0, 2 }, { 1, 3 }, { 2, 3 } };
		{
			// TODO: There really has to be more 'easier' way of doing this -
			// not including extensive use of sqrt.
			Vertex v0 = mArrRotatedVertices.get(0);
			Vertex v2 = mArrRotatedVertices.get(2);
			Vertex v3 = mArrRotatedVertices.get(3);
			double dist2 = Math.sqrt((v0.mPosX - v2.mPosX)
					* (v0.mPosX - v2.mPosX) + (v0.mPosY - v2.mPosY)
					* (v0.mPosY - v2.mPosY));
			double dist3 = Math.sqrt((v0.mPosX - v3.mPosX)
					* (v0.mPosX - v3.mPosX) + (v0.mPosY - v3.mPosY)
					* (v0.mPosY - v3.mPosY));
			if (dist2 > dist3) {
				lines[1][1] = 3;
				lines[2][1] = 2;
			}
		}

		mVerticesCountFront = mVerticesCountBack = 0;

		if (DRAW_SHADOW) {
			mArrTempShadowVertices.addAll(mArrDropShadowVertices);
			mArrTempShadowVertices.addAll(mArrSelfShadowVertices);
			mArrDropShadowVertices.clear();
			mArrSelfShadowVertices.clear();
		}

		// Length of 'curl' curve.
		double curlLength = Math.PI * radius;
		// Calculate scan lines.
		// TODO: Revisit this code one day. There is room for optimization here.
		mArrScanLines.clear();
		if (mMaxCurlSplits > 0) {
			mArrScanLines.add((double) 0);
		}
		for (int i = 1; i < mMaxCurlSplits; ++i) {
			mArrScanLines.add((-curlLength * i) / (mMaxCurlSplits - 1));
		}
		// As mRotatedVertices is ordered regarding x -coordinate, adding
		// this scan line produces scan area picking up vertices which are
		// rotated completely. One could say 'until infinity'.
		mArrScanLines.add(mArrRotatedVertices.get(3).mPosX - 1);

		// Start from right most vertex. Pretty much the same as first scan area
		// is starting from 'infinity'.
		double scanXmax = mArrRotatedVertices.get(0).mPosX + 1;

		for (int i = 0; i < mArrScanLines.size(); ++i) {
			// Once we have scanXmin and scanXmax we have a scan area to start
			// working with.
			double scanXmin = mArrScanLines.get(i);
			// First iterate 'original' rectangle vertices within scan area.
			for (int j = 0; j < mArrRotatedVertices.size(); ++j) {
				Vertex v = mArrRotatedVertices.get(j);
				// Test if vertex lies within this scan area.
				// TODO: Frankly speaking, can't remember why equality check was
				// added to both ends. Guessing it was somehow related to case
				// where radius=0f, which, given current implementation, could
				// be handled much more effectively anyway.
				if (v.mPosX >= scanXmin && v.mPosX <= scanXmax) {
					// Pop out a vertex from temp vertices.
					Vertex n = mArrTempVertices.remove(0);
					n.set(v);
					// This is done solely for triangulation reasons. Given a
					// rotated rectangle it has max 2 vertices having
					// intersection.
					Array<Vertex> intersections = getIntersections(
							mArrRotatedVertices, lines, n.mPosX);
					// In a sense one could say we're adding vertices always in
					// two, positioned at the ends of intersecting line. And for
					// triangulation to work properly they are added based on y
					// -coordinate. And this if-else is doing it for us.
					if (intersections.size() == 1
							&& intersections.get(0).mPosY > v.mPosY) {
						// In case intersecting vertex is higher add it first.
						mArrOutputVertices.addAll(intersections);
						mArrOutputVertices.add(n);
					} else if (intersections.size() <= 1) {
						// Otherwise add original vertex first.
						mArrOutputVertices.add(n);
						mArrOutputVertices.addAll(intersections);
					} else {
						// There should never be more than 1 intersecting
						// vertex. But if it happens as a fallback simply skip
						// everything.
						mArrTempVertices.add(n);
						mArrTempVertices.addAll(intersections);
					}
				}
			}

			// Search for scan line intersections.
			Array<Vertex> intersections = getIntersections(mArrRotatedVertices,
					lines, scanXmin);

			// We expect to get 0 or 2 vertices. In rare cases there's only one
			// but in general given a scan line intersecting rectangle there
			// should be 2 intersecting vertices.
			if (intersections.size() == 2) {
				// There were two intersections, add them based on y
				// -coordinate, higher first, lower last.
				Vertex v1 = intersections.get(0);
				Vertex v2 = intersections.get(1);
				if (v1.mPosY < v2.mPosY) {
					mArrOutputVertices.add(v2);
					mArrOutputVertices.add(v1);
				} else {
					mArrOutputVertices.addAll(intersections);
				}
			} else if (intersections.size() != 0) {
				// This happens in a case in which there is a original vertex
				// exactly at scan line or something went very much wrong if
				// there are 3+ vertices. What ever the reason just return the
				// vertices to temp vertices for later use. In former case it
				// was handled already earlier once iterating through
				// mRotatedVertices, in latter case it's better to avoid doing
				// anything with them.
				mArrTempVertices.addAll(intersections);
			}

			// Add vertices found during this iteration to vertex etc buffers.
			while (mArrOutputVertices.size() > 0) {
				Vertex v = mArrOutputVertices.remove(0);
				mArrTempVertices.add(v);

				// Local texture front-facing flag.
				boolean textureFront;

				// Untouched vertices.
				if (i == 0) {
					textureFront = true;
					mVerticesCountFront++;
				}
				// 'Completely' rotated vertices.
				else if (i == mArrScanLines.size() - 1 || curlLength == 0) {
					v.mPosX = -(curlLength + v.mPosX);
					v.mPosZ = 2 * radius;
					v.mPenumbraX = -v.mPenumbraX;

					textureFront = false;
					mVerticesCountBack++;
				}
				// Vertex lies within 'curl'.
				else {
					// Even though it's not obvious from the if-else clause,
					// here v.mPosX is between [-curlLength, 0]. And we can do
					// calculations around a half cylinder.
					double rotY = Math.PI * (v.mPosX / curlLength);
					v.mPosX = radius * Math.sin(rotY);
					v.mPosZ = radius - (radius * Math.cos(rotY));
					v.mPenumbraX *= Math.cos(rotY);
					// Map color multiplier to [.1f, 1f] range.
					v.mColorFactor = (float) (.1f + .9f * Math.sqrt(Math
							.sin(rotY) + 1));

					if (v.mPosZ >= radius) {
						textureFront = false;
						mVerticesCountBack++;
					} else {
						textureFront = true;
						mVerticesCountFront++;
					}
				}

				// We use local textureFront for flipping backside texture
				// locally. Plus additionally if mesh is in flip texture mode,
				// we'll make the procedure "backwards". Also, until this point,
				// texture coordinates are within [0, 1] range so we'll adjust
				// them to final texture coordinates too.
				if (textureFront != mFlipTexture) {
					v.mTexX *= mTextureRectFront.right;
					v.mTexY *= mTextureRectFront.bottom;
					v.mColor = mTexturePage.getColor(FlipAnimationPage.SIDE_FRONT);
				} else {
					v.mTexX *= mTextureRectBack.right;
					v.mTexY *= mTextureRectBack.bottom;
					v.mColor = mTexturePage.getColor(FlipAnimationPage.SIDE_BACK);
				}

				// Move vertex back to 'world' coordinates.
				v.rotateZ(curlAngle);
				v.translate(curlPos.x, curlPos.y);
				addVertex(v);

				// Drop shadow is cast 'behind' the curl.
				if (DRAW_SHADOW && v.mPosZ > 0 && v.mPosZ <= radius) {
					ShadowVertex sv = mArrTempShadowVertices.remove(0);
					sv.mPosX = v.mPosX;
					sv.mPosY = v.mPosY;
					sv.mPosZ = v.mPosZ;
					sv.mPenumbraX = (v.mPosZ / 2) * -curlDir.x;
					sv.mPenumbraY = (v.mPosZ / 2) * -curlDir.y;
					sv.mPenumbraColor = v.mPosZ / radius;
					int idx = (mArrDropShadowVertices.size() + 1) / 2;
					mArrDropShadowVertices.add(idx, sv);
				}
				// Self shadow is cast partly over mesh.
				if (DRAW_SHADOW && v.mPosZ > radius) {
					ShadowVertex sv = mArrTempShadowVertices.remove(0);
					sv.mPosX = v.mPosX;
					sv.mPosY = v.mPosY;
					sv.mPosZ = v.mPosZ;
					sv.mPenumbraX = ((v.mPosZ - radius) / 3) * v.mPenumbraX;
					sv.mPenumbraY = ((v.mPosZ - radius) / 3) * v.mPenumbraY;
					sv.mPenumbraColor = (v.mPosZ - radius) / (2 * radius);
					int idx = (mArrSelfShadowVertices.size() + 1) / 2;
					mArrSelfShadowVertices.add(idx, sv);
				}
			}

			// Switch scanXmin as scanXmax for next iteration.
			scanXmax = scanXmin;
		}

		mBufVertices.position(0);
		mBufColors.position(0);
		if (DRAW_TEXTURE) {
			mBufTexCoords.position(0);
		}

		// Add shadow Vertices.
		if (DRAW_SHADOW) {
			mBufShadowColors.position(0);
			mBufShadowVertices.position(0);
			mDropShadowCount = 0;

			for (int i = 0; i < mArrDropShadowVertices.size(); ++i) {
				ShadowVertex sv = mArrDropShadowVertices.get(i);
				mBufShadowVertices.put((float) sv.mPosX);
				mBufShadowVertices.put((float) sv.mPosY);
				mBufShadowVertices.put((float) sv.mPosZ);
				mBufShadowVertices.put((float) (sv.mPosX + sv.mPenumbraX));
				mBufShadowVertices.put((float) (sv.mPosY + sv.mPenumbraY));
				mBufShadowVertices.put((float) sv.mPosZ);
				for (int j = 0; j < 4; ++j) {
					double color = SHADOW_OUTER_COLOR[j]
							+ (SHADOW_INNER_COLOR[j] - SHADOW_OUTER_COLOR[j])
							* sv.mPenumbraColor;
					mBufShadowColors.put((float) color);
				}
				mBufShadowColors.put(SHADOW_OUTER_COLOR);
				mDropShadowCount += 2;
			}
			mSelfShadowCount = 0;
			for (int i = 0; i < mArrSelfShadowVertices.size(); ++i) {
				ShadowVertex sv = mArrSelfShadowVertices.get(i);
				mBufShadowVertices.put((float) sv.mPosX);
				mBufShadowVertices.put((float) sv.mPosY);
				mBufShadowVertices.put((float) sv.mPosZ);
				mBufShadowVertices.put((float) (sv.mPosX + sv.mPenumbraX));
				mBufShadowVertices.put((float) (sv.mPosY + sv.mPenumbraY));
				mBufShadowVertices.put((float) sv.mPosZ);
				for (int j = 0; j < 4; ++j) {
					double color = SHADOW_OUTER_COLOR[j]
							+ (SHADOW_INNER_COLOR[j] - SHADOW_OUTER_COLOR[j])
							* sv.mPenumbraColor;
					mBufShadowColors.put((float) color);
				}
				mBufShadowColors.put(SHADOW_OUTER_COLOR);
				mSelfShadowCount += 2;
			}
			mBufShadowColors.position(0);
			mBufShadowVertices.position(0);
		}
	}

	/**
	 * Calculates intersections for given scan line.
	 */
	private Array<Vertex> getIntersections(Array<Vertex> vertices,
			int[][] lineIndices, double scanX) {
		mArrIntersections.clear();
		// Iterate through rectangle lines each re-presented as a pair of
		// vertices.
		for (int j = 0; j < lineIndices.length; j++) {
			Vertex v1 = vertices.get(lineIndices[j][0]);
			Vertex v2 = vertices.get(lineIndices[j][1]);
			// Here we expect that v1.mPosX >= v2.mPosX and wont do intersection
			// test the opposite way.
			if (v1.mPosX > scanX && v2.mPosX < scanX) {
				// There is an intersection, calculate coefficient telling 'how
				// far' scanX is from v2.
				double c = (scanX - v2.mPosX) / (v1.mPosX - v2.mPosX);
				Vertex n = mArrTempVertices.remove(0);
				n.set(v2);
				n.mPosX = scanX;
				n.mPosY += (v1.mPosY - v2.mPosY) * c;
				if (DRAW_TEXTURE) {
					n.mTexX += (v1.mTexX - v2.mTexX) * c;
					n.mTexY += (v1.mTexY - v2.mTexY) * c;
				}
				if (DRAW_SHADOW) {
					n.mPenumbraX += (v1.mPenumbraX - v2.mPenumbraX) * c;
					n.mPenumbraY += (v1.mPenumbraY - v2.mPenumbraY) * c;
				}
				mArrIntersections.add(n);
			}
		}
		return mArrIntersections;
	}

	/**
	 * Getter for textures page for this mesh.
	 */
	public synchronized FlipAnimationPage getTexturePage() {
		return mTexturePage;
	}

	/**
	 * Renders our page curl mesh.
	 */
	public synchronized void onDrawFrame(GL10 gl) {
		// First allocate texture if there is not one yet.
		if (DRAW_TEXTURE && mTextureIds == null) {
			// Generate texture.
			mTextureIds = new int[2];
			gl.glGenTextures(2, mTextureIds, 0);
			for (int textureId : mTextureIds) {
				// Set texture attributes.
				gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
				gl.glTexParameterf(GL10.GL_TEXTURE_2D,
						GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
				gl.glTexParameterf(GL10.GL_TEXTURE_2D,
						GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
				gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
						GL10.GL_CLAMP_TO_EDGE);
				gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
						GL10.GL_CLAMP_TO_EDGE);
			}
		}

		if (DRAW_TEXTURE && mTexturePage.getTexturesChanged()) {
			gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]);
			Bitmap texture = mTexturePage.getTexture(mTextureRectFront,
					FlipAnimationPage.SIDE_FRONT);
			GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
			texture.recycle();

			mTextureBack = mTexturePage.hasBackTexture();
			if (mTextureBack) {
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]);
				texture = mTexturePage.getTexture(mTextureRectBack,
						FlipAnimationPage.SIDE_BACK);
				GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
				texture.recycle();
			} else {
				mTextureRectBack.set(mTextureRectFront);
			}

			mTexturePage.recycle();
			reset();
		}

		// Some 'global' settings.
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

		// TODO: Drop shadow drawing is done temporarily here to hide some
		// problems with its calculation.
		if (DRAW_SHADOW) {
			gl.glDisable(GL10.GL_TEXTURE_2D);
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufShadowColors);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufShadowVertices);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mDropShadowCount);
			gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
			gl.glDisable(GL10.GL_BLEND);
		}

		if (DRAW_TEXTURE) {
			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mBufTexCoords);
		}
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufVertices);
		// Enable color array.
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufColors);

		// Draw front facing blank vertices.
		gl.glDisable(GL10.GL_TEXTURE_2D);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVerticesCountFront);

		// Draw front facing texture.
		if (DRAW_TEXTURE) {
			gl.glEnable(GL10.GL_BLEND);
			gl.glEnable(GL10.GL_TEXTURE_2D);

			if (!mFlipTexture || !mTextureBack) {
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]);
			} else {
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]);
			}

			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, mVerticesCountFront);

			gl.glDisable(GL10.GL_BLEND);
			gl.glDisable(GL10.GL_TEXTURE_2D);
		}

		int backStartIdx = Math.max(0, mVerticesCountFront - 2);
		int backCount = mVerticesCountFront + mVerticesCountBack - backStartIdx;

		// Draw back facing blank vertices.
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, backStartIdx, backCount);

		// Draw back facing texture.
		if (DRAW_TEXTURE) {
			gl.glEnable(GL10.GL_BLEND);
			gl.glEnable(GL10.GL_TEXTURE_2D);

			if (mFlipTexture || !mTextureBack) {
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[0]);
			} else {
				gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureIds[1]);
			}

			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, backStartIdx, backCount);

			gl.glDisable(GL10.GL_BLEND);
			gl.glDisable(GL10.GL_TEXTURE_2D);
		}

		// Disable textures and color array.
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

		if (DRAW_POLYGON_OUTLINES) {
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glLineWidth(1.0f);
			gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufVertices);
			gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, mVerticesCountFront);
			gl.glDisable(GL10.GL_BLEND);
		}

		if (DRAW_CURL_POSITION) {
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glLineWidth(1.0f);
			gl.glColor4f(1.0f, 0.5f, 0.5f, 1.0f);
			gl.glVertexPointer(2, GL10.GL_FLOAT, 0, mBufCurlPositionLines);
			gl.glDrawArrays(GL10.GL_LINES, 0, mCurlPositionLinesCount * 2);
			gl.glDisable(GL10.GL_BLEND);
		}

		if (DRAW_SHADOW) {
			gl.glEnable(GL10.GL_BLEND);
			gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
			gl.glColorPointer(4, GL10.GL_FLOAT, 0, mBufShadowColors);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBufShadowVertices);
			gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, mDropShadowCount,
					mSelfShadowCount);
			gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
			gl.glDisable(GL10.GL_BLEND);
		}

		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	}

	/**
	 * Resets mesh to 'initial' state. Meaning this mesh will draw a plain
	 * textured rectangle after call to this method.
	 */
	public synchronized void reset() {
		mBufVertices.position(0);
		mBufColors.position(0);
		if (DRAW_TEXTURE) {
			mBufTexCoords.position(0);
		}
		for (int i = 0; i < 4; ++i) {
			Vertex tmp = mArrTempVertices.get(0);
			tmp.set(mRectangle[i]);

			if (mFlipTexture) {
				tmp.mTexX *= mTextureRectBack.right;
				tmp.mTexY *= mTextureRectBack.bottom;
				tmp.mColor = mTexturePage.getColor(FlipAnimationPage.SIDE_BACK);
			} else {
				tmp.mTexX *= mTextureRectFront.right;
				tmp.mTexY *= mTextureRectFront.bottom;
				tmp.mColor = mTexturePage.getColor(FlipAnimationPage.SIDE_FRONT);
			}

			addVertex(tmp);
		}
		mVerticesCountFront = 4;
		mVerticesCountBack = 0;
		mBufVertices.position(0);
		mBufColors.position(0);
		if (DRAW_TEXTURE) {
			mBufTexCoords.position(0);
		}

		mDropShadowCount = mSelfShadowCount = 0;
	}

	/**
	 * Resets allocated texture id forcing creation of new one. After calling
	 * this method you most likely want to set bitmap too as it's lost. This
	 * method should be called only once e.g GL context is re-created as this
	 * method does not release previous texture id, only makes sure new one is
	 * requested on next render.
	 */
	public synchronized void resetTexture() {
		mTextureIds = null;
	}

	/**
	 * If true, flips texture sideways.
	 */
	public synchronized void setFlipTexture(boolean flipTexture) {
		mFlipTexture = flipTexture;
		if (flipTexture) {
			setTexCoords(1f, 0f, 0f, 1f);
		} else {
			setTexCoords(0f, 0f, 1f, 1f);
		}
	}

	/**
	 * Update mesh bounds.
	 */
	public void setRect(RectF r) {
		mRectangle[0].mPosX = r.left;
		mRectangle[0].mPosY = r.top;
		mRectangle[1].mPosX = r.left;
		mRectangle[1].mPosY = r.bottom;
		mRectangle[2].mPosX = r.right;
		mRectangle[2].mPosY = r.top;
		mRectangle[3].mPosX = r.right;
		mRectangle[3].mPosY = r.bottom;
	}

	/**
	 * Sets texture coordinates to mRectangle vertices.
	 */
	private synchronized void setTexCoords(float left, float top, float right,
			float bottom) {
		mRectangle[0].mTexX = left;
		mRectangle[0].mTexY = top;
		mRectangle[1].mTexX = left;
		mRectangle[1].mTexY = bottom;
		mRectangle[2].mTexX = right;
		mRectangle[2].mTexY = top;
		mRectangle[3].mTexX = right;
		mRectangle[3].mTexY = bottom;
	}

	/**
	 * Simple fixed size array implementation.
	 */
	private class Array<T> {
		private Object[] mArray;
		private int mCapacity;
		private int mSize;

		public Array(int capacity) {
			mCapacity = capacity;
			mArray = new Object[capacity];
		}

		public void add(int index, T item) {
			if (index < 0 || index > mSize || mSize >= mCapacity) {
				throw new IndexOutOfBoundsException();
			}
			for (int i = mSize; i > index; --i) {
				mArray[i] = mArray[i - 1];
			}
			mArray[index] = item;
			++mSize;
		}

		public void add(T item) {
			if (mSize >= mCapacity) {
				throw new IndexOutOfBoundsException();
			}
			mArray[mSize++] = item;
		}

		public void addAll(Array<T> array) {
			if (mSize + array.size() > mCapacity) {
				throw new IndexOutOfBoundsException();
			}
			for (int i = 0; i < array.size(); ++i) {
				mArray[mSize++] = array.get(i);
			}
		}

		public void clear() {
			mSize = 0;
		}

		@SuppressWarnings("unchecked")
		public T get(int index) {
			if (index < 0 || index >= mSize) {
				throw new IndexOutOfBoundsException();
			}
			return (T) mArray[index];
		}

		@SuppressWarnings("unchecked")
		public T remove(int index) {
			if (index < 0 || index >= mSize) {
				throw new IndexOutOfBoundsException();
			}
			T item = (T) mArray[index];
			for (int i = index; i < mSize - 1; ++i) {
				mArray[i] = mArray[i + 1];
			}
			--mSize;
			return item;
		}

		public int size() {
			return mSize;
		}

	}

	/**
	 * Holder for shadow vertex information.
	 */
	private class ShadowVertex {
		public double mPenumbraColor;
		public double mPenumbraX;
		public double mPenumbraY;
		public double mPosX;
		public double mPosY;
		public double mPosZ;
	}

	/**
	 * Holder for vertex information.
	 */
	private class Vertex {
		public int mColor;
		public float mColorFactor;
		public double mPenumbraX;
		public double mPenumbraY;
		public double mPosX;
		public double mPosY;
		public double mPosZ;
		public double mTexX;
		public double mTexY;

		public Vertex() {
			mPosX = mPosY = mPosZ = mTexX = mTexY = 0;
			mColorFactor = 1.0f;
		}

		public void rotateZ(double theta) {
			double cos = Math.cos(theta);
			double sin = Math.sin(theta);
			double x = mPosX * cos + mPosY * sin;
			double y = mPosX * -sin + mPosY * cos;
			mPosX = x;
			mPosY = y;
			double px = mPenumbraX * cos + mPenumbraY * sin;
			double py = mPenumbraX * -sin + mPenumbraY * cos;
			mPenumbraX = px;
			mPenumbraY = py;
		}

		public void set(Vertex vertex) {
			mPosX = vertex.mPosX;
			mPosY = vertex.mPosY;
			mPosZ = vertex.mPosZ;
			mTexX = vertex.mTexX;
			mTexY = vertex.mTexY;
			mPenumbraX = vertex.mPenumbraX;
			mPenumbraY = vertex.mPenumbraY;
			mColor = vertex.mColor;
			mColorFactor = vertex.mColorFactor;
		}

		public void translate(double dx, double dy) {
			mPosX += dx;
			mPosY += dy;
		}
	}
}


text:
#include "SSLListenerPoolTest.h"
#include "RequestListener.h"
#include "TestSuite.h"
#include "SSLSocket.h"
#include "SSLModule.h"
#include "AnyIterators.h"

//---- SSLListenerPoolTest ----------------------------------------------------------------
SSLListenerPoolTest::SSLListenerPoolTest(TString tname) : ListenerPoolTest(tname)
{
	StartTrace(SSLListenerPoolTest.Ctor);
}

SSLListenerPoolTest::~SSLListenerPoolTest()
{
	StartTrace(SSLListenerPoolTest.Dtor);
}

void SSLListenerPoolTest::PoolTest()
{
	StartTrace(SSLListenerPoolTest.PoolTest);
	Anything config;
	config.Append("TCP5010");
	config.Append("TCP5011");
	config.Append("TCP5012");
	config.Append("TCP5013");
	config.Append("TCP5014");
	config.Append("TCP5015");
	config.Append("TCP5016");
	config.Append("TCP5017");
	config.Append("TCP5018");
	config.Append("TCP5019");
	config.Append("TCP5020");
	config.Append("TCP5021");
	config.Append("TCP5022");
	config.Append("TCP5023");

	TestCallBackFactory *tcbf = new TestCallBackFactory;
	ListenerPool lpToTest(tcbf);

	if ( t_assertm( lpToTest.Init(config.GetSize(), config), "Init should work") && t_assertm(lpToTest.Start(false, 0, 0) == 0, "Start should work")) {
		DoTestConnect();
		if (t_assertm(lpToTest.Terminate(1, 10) == 0, "Terminate failed")) {
			t_assertm(lpToTest.Join() == 0, "Join failed");
			Anything result = tcbf->GetResult();
			t_assert(result.Contains("5010_timeout_0"));
			t_assert(result.Contains("5011_timeout_0"));
			t_assert(result.Contains("5012_timeout_0"));
			t_assert(result.Contains("5013_timeout_0"));
			t_assert(result.Contains("5014_timeout_0"));
			t_assert(result.Contains("5010_timeout_1000"));
			t_assert(result.Contains("5011_timeout_1000"));
			t_assert(result.Contains("5012_timeout_1000"));
			t_assert(result.Contains("5012_timeout_2000"));
			t_assert(result.Contains("5011_timeout_2000"));
			t_assert(result.Contains("5016_timeout_1000"));
			t_assert(result.Contains("5017_timeout_1000"));
			t_assert(result.Contains("5020_timeout_0"));
			t_assert(result.Contains("5021_timeout_1000"));
		}
	}
	Anything failures = tcbf->GetFailures();
	t_assertm(failures.GetSize() == 0, "Receivers encountered a least one error");
	if (failures.GetSize()) {
		TraceAny(failures, "EYECATCHER Receivers encountered the following errors");
	}
}

void SSLListenerPoolTest::DoTestConnect()
{
	StartTrace(SSLListenerPoolTest.DoTestConnect);
	ROAnything cConfig;
	AnyExtensions::Iterator<ROAnything> aEntryIterator(GetConfig()["SSLListenerPoolTest"]);
	while ( aEntryIterator.Next(cConfig) ) {
		TraceAny(cConfig, "cConfig");
		Trace(cConfig["SSLConnector"].AsLong(1));
		Anything data = cConfig["Data"].DeepClone();
		long connectsToDo = cConfig["NumberOfConnects"].AsLong(1L);
		for ( long l = 0; l < connectsToDo; l++ ) {
			Trace("At connect Nr.: " << l);
			if ( ((connectsToDo - 1) == l) && data.IsDefined("LastChecksToDo") ) {
				data["ChecksToDo"] = data["LastChecksToDo"];
			}
			if ( cConfig["SSLConnector"].AsLong(1) == 1 ) {
				if ( cConfig["ConnectorToUse"].AsString() != "" ) {
					// deep clone, no side effect when adding Timeout
					Anything connectorConfig = GetTestCaseConfig()[cConfig["ConnectorToUse"].AsString()].DeepClone();
					if ( cConfig.IsDefined("TimeoutToUse") ) {
						connectorConfig["Timeout"] = cConfig["TimeoutToUse"].AsLong(0L);
					}
					if ( cConfig.IsDefined("UseThreadLocalMemory") ) {
						connectorConfig["UseThreadLocalMemory"] = cConfig["UseThreadLocalMemory"].AsLong(0L);
					}
					SSLConnector sc(connectorConfig);
					if ( cConfig["DoSendReceiveWithFailure"].AsLong(0) ) {
						DoSendReceiveWithFailure(&sc, data,
												 cConfig["IOSGoodAfterSend"].AsLong(0),
												 cConfig["IOSGoodBeforeSend"].AsLong(1));
					} else {
						DoSendReceive(&sc, data);
					}
				} else {
					SSLConnector sc("localhost", cConfig["PortToUse"].AsLong(0), cConfig["TimeoutToUse"].AsLong(0),
									(SSL_CTX *) NULL, (const char *) NULL, 0L, cConfig["UseThreadLocalMemory"].AsBool(0));

					if ( cConfig["DoSendReceiveWithFailure"].AsLong(0) ) {
						DoSendReceiveWithFailure(&sc, data,
												 cConfig["IOSGoodAfterSend"].AsLong(0),
												 cConfig["IOSGoodBeforeSend"].AsLong(1));
					} else {
						DoSendReceive(&sc, data);
					}
				}
			} else {
				Trace("Using configured NON SSL connector");
				Connector c("localhost", cConfig["PortToUse"].AsLong(0L), cConfig["TimeoutToUse"].AsLong(0L), String(), 0L, cConfig["UseThreadLocalMemory"].AsBool(0));
				if ( cConfig["DoSendReceiveWithFailure"].AsLong(0) ) {
					DoSendReceiveWithFailure(&c, data,
											 cConfig["IOSGoodAfterSend"].AsLong(0),
											 cConfig["IOSGoodBeforeSend"].AsLong(1));
				} else {
					DoSendReceive(&c, data);
				}
			}
		}
	}
}

// builds up a suite of testcases, add a line for each testmethod
Test *SSLListenerPoolTest::suite ()
{
	StartTrace(SSLListenerPoolTest.suite);
	TestSuite *testSuite = new TestSuite;
	ADD_CASE(testSuite, SSLListenerPoolTest, PoolTest);
	ADD_CASE(testSuite, SSLListenerPoolTest, NullCallBackFactoryTest);
	ADD_CASE(testSuite, SSLListenerPoolTest, InitFailureNullAcceptorTest);
	return testSuite;
}

redpajama_set_name: RedPajamaGithub


text:
namespace fsspool {

absl::string_view PathSeparator();
bool IsAbsolutePath(absl::string_view path);
bool IsDirectory(const std::string& d);
int Close(int fd);
int Open(const char* filename, int flags, mode_t mode);
int MkDir(const char* path, mode_t mode);
bool StatIsDir(mode_t mode);
bool StatIsReg(mode_t mode);
int Unlink(const char* pathname);
int Write(int fd, absl::string_view buf);

absl::Status IterateDirectory(const std::string& dir,
                              std::function<void(const std::string&)> callback);

}  // namespace fsspool

#endif  // SANTA__SANTAD__LOGS_ENDPOINTSECURITY_WRITERS_FSSPOOL_FSSPOOLPLATFORMSPECIFIC_H


text:
require_relative '../../spec_helper'
require_relative '../enumerable/shared/enumeratorized'

describe "ENV.reject!" do
  it "rejects entries based on key" do
    ENV["foo"] = "bar"
    ENV.reject! { |k, v| k == "foo" }
    ENV["foo"].should == nil
  end

  it "rejects entries based on value" do
    ENV["foo"] = "bar"
    ENV.reject! { |k, v| v == "bar" }
    ENV["foo"].should == nil
  end

  it "returns itself or nil" do
    ENV.reject! { false }.should == nil
    ENV["foo"] = "bar"
    ENV.reject! { |k, v| k == "foo" }.should == ENV
    ENV["foo"].should == nil
  end

  it "returns an Enumerator if called without a block" do
    ENV.reject!.should be_an_instance_of(Enumerator)
  end

  it "doesn't raise if empty" do
    orig = ENV.to_hash
    begin
      ENV.clear
      lambda { ENV.reject! }.should_not raise_error(LocalJumpError)
    ensure
      ENV.replace orig
    end
  end

  it_behaves_like :enumeratorized_with_origin_size, :reject!, ENV
end

describe "ENV.reject" do
  it "rejects entries based on key" do
    ENV["foo"] = "bar"
    e = ENV.reject { |k, v| k == "foo" }
    e["foo"].should == nil
    ENV["foo"].should == "bar"
    ENV["foo"] = nil
  end

  it "rejects entries based on value" do
    ENV["foo"] = "bar"
    e = ENV.reject { |k, v| v == "bar" }
    e["foo"].should == nil
    ENV["foo"].should == "bar"
    ENV["foo"] = nil
  end

  it "returns a Hash" do
    ENV.reject { false }.should be_kind_of(Hash)
  end

  it "returns an Enumerator if called without a block" do
    ENV.reject.should be_an_instance_of(Enumerator)
  end

  it "doesn't raise if empty" do
    orig = ENV.to_hash
    begin
      ENV.clear
      lambda { ENV.reject }.should_not raise_error(LocalJumpError)
    ensure
      ENV.replace orig
    end
  end

  it_behaves_like :enumeratorized_with_origin_size, :reject, ENV
end


text:
layout: kanji-remain
v4: 2644
kanji: 笈
keyword: backpack
strokes: 9
on-yomi: キュウ
permalink: /rtk/笈/
---

## Koohii stories:

1) [Katsuo] 15-10-2007(40): I see a panda wearing a backpack, and every so often something inside the backpack reaches out and grabs bamboo. (it's acutally a baby panda reaching out to grab bamboo to eat).

2) [Neobeo] 23-1-2009(3): With Kung Fu Panda being all the craze recently, I wasn't very surprised to see a schoolkid with a Kung Fu Panda backpack. But imagine my shock when he reached out into his backpack and pulled out some bamboo.

3) [Megaqwerty] 22-6-2007(1): When I encountered an ravenous panda, I just reached back to my backpack and pulled out two bamboo katanas.

4) [lisbet] 21-10-2012(): People used to carry the bamboo they'd cut in backpacks with straps they had to reach out and pull forward to hoist the bag up onto their backs.

5) [CasualTatsumaki] 24-1-2012(): My backpack is just bamboo slats so the homeless guy reach out and takes the can of coke from inside it.


text:
package org.databene.commons.converter;

import static junit.framework.Assert.assertEquals;

import java.util.Locale;

import org.databene.commons.LocaleUtil;
import org.junit.Test;

/**
 * Tests the {@link NumberParser}.
 * Created: 26.02.2010 08:52:12
 * @since 0.5.0
 * @author Volker Bergmann
 */
public class NumberParserTest extends AbstractConverterTest {

	public NumberParserTest() {
	    super(NumberParser.class);
    }

	@Test
	public void testEmpty() {
		NumberParser converter = new NumberParser();
		assertEquals(null, converter.convert(""));
		assertEquals(null, converter.convert(null));
	}

	@Test
	public void testIntegral() {
		NumberParser converter = new NumberParser();
		assertEquals(0, converter.convert("0").intValue());
		assertEquals(1000, converter.convert("1000").intValue());
	}

	@Test
	public void testConvert_US() {
		LocaleUtil.runInLocale(Locale.US, new Runnable() {
			@Override
			public void run() {
				checkConversion();
			}
		});
	}

	@Test
	public void testConvert_DE() {
		LocaleUtil.runInLocale(Locale.GERMANY, new Runnable() {
			@Override
			public void run() {
				checkConversion();
			}
		});
	}

	void checkConversion() {
        NumberParser converter = new NumberParser();
		// default
		assertEquals(-1., converter.convert("-1.0").doubleValue());
		assertEquals(0., converter.convert("0.0").doubleValue());
		assertEquals(1000., converter.convert("1000.0").doubleValue());
		// pattern
		converter.setPattern("0.00");
		assertEquals(0., converter.convert("0.00").doubleValue());
		// decimal separator
		converter.setDecimalSeparator(',');
		assertEquals(0., converter.convert("0,00").doubleValue());
		// grouping
		converter.setGroupingSeparator('.');
		converter.setPattern("#,##0");
		assertEquals(1000, converter.convert("1.000").intValue());
		// grouping and decimal separator
		converter.setPattern("#,##0.00");
		assertEquals(1000., converter.convert("1.000,00").doubleValue());
    }

}


text:
using namespace flink;
using namespace eeros::hal;
using namespace eeros;

AnalogIn::AnalogIn(std::string id, void* libHandle, std::string device, uint32_t subDeviceNumber, uint32_t channel,
		   double scale, double offset, double rangeMin, double rangeMax, std::string unit, bool twosComplement) :
		   ScalableInput<double>(id, libHandle, scale, offset, rangeMin, rangeMax, unit), channel(channel), bitMask(0) {

	FlinkDevice *dev = FlinkDevice::getDevice(device);
	this->subdeviceHandle = flink_get_subdevice_by_id(dev->getDeviceHandle(), subDeviceNumber);
	uint16_t function = flink_subdevice_get_function(subdeviceHandle);
	if (function != ANALOG_INPUT_INTERFACE_ID) throw Fault("flink invalid subdevice number " + std::to_string(subDeviceNumber) + ", not a ADC subdevice");
	if (channel < 0 || channel >= flink_subdevice_get_nofchannels(subdeviceHandle)) throw Fault("flink ADC subdevice, invalid channel number " + std::to_string(channel));

	flink_analog_in_get_resolution(subdeviceHandle, &resolution);
	bitMask = (1 << resolution) - 1;

	this->scale = scale;
	this->offset = offset;
	this->minIn = rangeMin;
	this->maxIn = rangeMax;
	this->unit = unit;
	this->twosComplement = twosComplement;
}

double AnalogIn::get() {
	uint32_t data;
	flink_analog_in_get_value(subdeviceHandle, channel, &data);
	data &= bitMask;
	return (data - offset) / scale;
}

extern "C"{
	eeros::hal::ScalableInput<double> *createAnalogIn(std::string id, void* libHandle, std::string device, uint32_t subDeviceNumber, uint32_t channel,
							 double scale, double offset, double rangeMin, double rangeMax, std::string unit, bool twosComplement){
		return new flink::AnalogIn(id, libHandle, device, subDeviceNumber, channel, scale, offset, rangeMin, rangeMax, unit, twosComplement);
	}
}


text:
HyperCouch
==========

Full text indexing for [CouchDB][couchdb]. (I really mean it this time.)

Requriements
------------

There are a couple dependancies that should hopefully be easy to overcome. I have things working on OS X 10.4 so Linux should be a breeze. Windows installation is left as an exercise to the reader.

1. [CouchDB][couchdb] - Obviously
1. [HyperEstraier][hyper] - Full text indexing goodness
1. [Spidermonkey][spider] - Requirement of CouchDB as well **Might require Spidermonkey 1.7**
1. [hypy][hypy] - Python bindings to HyperEstraier
1. [python-spidermonkey][pyspider] - **My version on github**
1. [hypercouch][hypercouch] - This project?

OpenBSD:
    $ pkg_add -iv py-simplejson
    $ pkg_add -iv py-httplib2
    $ pkg_add -iv py-nose

OS X python modules:

    $ sudo port install py25-simplejson
    $ sudo port install py25-httplib2
    $ sudo port install py25-nose

Ubuntu:

    $ sudo apt-get install simplejson
    $ sudo apt-get isntall httplib2
    $ sudo apt-get install python-nose

And couchdb-python:

    $ svn checkout http://couchdb-python.googlecode.com/svn/trunk/ couchdb-python
    $ cd couchdb-python
    $ sudo python setup.py install

For the moment I haven't performed this installation on Linux. Tomorrow I'll sit down and install on one of my severs but for now I'll just go over the OS X procedure and hope the Linux equivalent isn't too far off.

Installation
------------

I won't go over installing CouchDB because it's pretty well covered on the [wiki][wiki]. If you need help with it check there or hop onto the IRC channel (#couchdb on irc.freenode.net) and ask questions.

Linux People
------------

Make sure you have the python dev stuff installed for building extensions:

    $ sudo apt-get install python2.5-dev

HyperEstraier
-------------

HyperEstraier should probably be in your package manager. On OS X it's merely:

    $ sudo port install libestraier-dev libqdbm-dev

Ubuntu:

    $ sudo apt-get install libestraier-dev

Openbsd:

Install Hyperestraier from sources:

    $ pkg_add -iv qdbm
    $ ftp http://hyperestraier.sourceforge.net/hyperestraier-1.4.13.tar.gz
    $ tar xvzf hyperestraier-1.4.13.tar.gz
    $ cd hyperestraier-1.4.13
    $ ./configure && gmake && gmake install

Spidermonkey
------------

Spidermonkey is similar

    $ sudo port install spidermonkey

Ubuntu:

    $ sudo apt-get install libmozjs-dev

OpenBSD:

    $ pkg_add -iv spidermonkey

Activation Errors
-----------------

If either of your port commands fails due to activation conflicts, you can just deactivate and then rerun the install to get things right:

    $ sudo port deactivate [package]
    $ sudo port install [package]

Hopefully that was the hard part. The rest of the stuff is just about getting the python bindings installed.

HyPy
----

Get the source here: [http://hypy-source.goonmill.org/archive/tip.tar.gz][hypy-download]

For me hypy was easy to install with the caveat that I had to make a minor tweak to `setup.py` to help it find HyperEstraier installed by `ports`. We just need to add `/opt/local/include` to the list of include directories:

From: (About line 10 in Hypy's setup.py)

    ext = Extension("_estraiernative",
                    ["estraiernative.c"],
                    libraries=["estraier"],
                    include_dirs=["/usr/include/estraier", "/usr/include/qdbm"],
                    )

To:

    ext = Extension("_estraiernative",
                    ["estraiernative.c"],
                    libraries=["estraier"],
                    library_dirs=["/usr/local/lib", "/usr/lib"],
                    include_dirs=["/usr/local/include", "/usr/include/estraier", "/usr/include/qdbm", "/opt/local/include/"],
                    )

Hopefully that builds just dandy for you.

python-spidermonkey
-------------------

I actually had to download and patch this project to allow the execution of JavaScript functions from Python. I'm very unsure of the build stability but hopefully it works without too much effort. For the time being you can either `git clone` it or download the tarball to install. At some point in the near future I'm going to give it a more thorough re-working to make it a real project.

Using git:

    $ git clone git://github.com/davisp/python-spidermonkey.git
    $ cd python-spidermonkey

No git:

    $ wget http://github.com/davisp/python-spidermonkey/tarball/master
    $ tar -xvzf davisp-python-spidermonkey-${HASH}.tar.gz
    $ cd davisp-python-spidermonkey-${HASH}

Installing:

    $ python setup.py build
    $ sudo python setup.py isntall

HyperCouch
----------

Installing HyperCouch should be relatively straight forward. Just `git clone` or download the tarball and install.

Using git:

    $ git clone git://github.com/davisp/hypercouch.git
    $ cd hypercouch

No git:

    $ wget http://github.com/davisp/hypercouch/tarball/master
    $ tar -xvzf davisp-hypercouch-${HASH}.tar.gz
    $ cd davisp-hypercouch-${HASH}

Installing:

    $ sudo python setup.py install

Configuring CouchDB
-------------------

You'll need to edit your `local.ini` or alternatively your `local_dev.ini` if you're a fan of `make dev` like I am.

    [external]
    hyper = /path/to/python -m hypercouch

    [httpd_db_handlers]
    _fti = {couch_httpd_external, handle_external_req, <<"hyper">>}

Alternatively, in your `[external]` section you can use `/path/to/hypercouch/dev.sh` without installing to make dev work easier for when you start submitting bug reports and patches. (This avoids the constant `sudo python setup.py install` running when you change `hypercouch` sources.)

Using HyperCouch
----------------

To use `hypercouch` all you need to do is add a JavaScript function to your `_design/doc`'s in the `ft_index` member. This function has two special JavaScript functions you can call to add indexing info for your document.

1. `index(data)` - adds `data` to the full text index
1. `property(name, value)` - adds properties to the document for use in sorting and limiting results

Example `_design/document`:

    {
        "_id": "_design/foo",
        "_rev": "32498230012",
        "ft_index": "function(doc) {if(doc.body) index(doc.body); if(doc.foo) property("foo", doc.foo);}"
    }

Example URL's:

    $ curl http://127.0.0.1:5984/db_name/_fti?q=term1+term2
    $ curl http://127.0.0.1:5984/db_name/_fti?q=term1+AND+term2

Caveat:

It may take a few seconds before the indexed results become available. There's no guarantee that a document has been indexed as soon as you commit it to the database.

Supports
--------

1. `q` - Requests with arbitrary AND/OR type of boolean logic.
1. `limit` and `skip` parameters - For paging type stuff (Beware when not using a specified sort)
1. `matching` - Specify a HyperEstraier parsing method
1. `order` - Order results by an arbitrary propert. Syntax: `prop_name [STRA|STRD|NUMA|NUMD]`
1. `highlight` - Retrieve a highlighted snipped. Currently only supports an html format via `highlight=html`
1. Other attribute limiting via `attr_name=METHOD param` See [Search Conditions][hypersearching] for specifics.

[couchdb]:http://couchdb.apache.org "CouchDB"
[hyper]:http://hyperestraier.sourceforge.net/ "Hyper Estraier"
[spider]:http://www.mozilla.org/js/spidermonkey/ "Spidermonkey"
[hypy]:http://www.goonmill.org/hypy/ "Hypy"
[hypy-download]:http://hypy-source.goonmill.org/archive/tip.tar.gz "Download Hypy"
[pyspider]:http://github.com/davisp/python-spidermonkey/tree/master "Python Spidermonkey"
[hypercouch]:http://github.com/davisp/python-spidermonkey/tree/master "HyperCouch"
[hypersearching]:http://hyperestraier.sourceforge.net/uguide-en.html#searchcond "Hyper Estraier Searching"


text: dump go object as go format


text:
package org.apache.shardingsphere.elasticjob.tracing.api;

/**
 * Tracing storage configuration.
 *
 * @param <T> storage type
 */
public interface TracingStorageConfiguration<T> {

    /**
     * Create storage.
     *
     * @return storage
     */
    T getStorage();
}


text:
{{ 'menu.title' | translate }}

<ion-content class="has-header">
	<ion-list>

			{{ 'menu.places' | translate }}

			{{ 'menu.list' | translate }}

			{{ 'menu.map' | translate }}

			{{ 'menu.events' | translate }}

			{{ 'menu.list' | translate }}

			{{ 'menu.map' | translate }}

			{{ 'menu.animals' | translate }}

			{{ 'menu.listAll' | translate }}

			{{ 'menu.fromSheltersAndCo' | translate }}

			{{ 'menu.privateAdoption' | translate }}

			{{ 'menu.lost' | translate }}

			{{ 'menu.found' | translate }}

			{{ 'menu.posts' | translate }}

		Seznam

			{{ 'menu.membersArea' | translate }}

			{{ 'menu.chat' | translate }}

			{{ 'menu.login' | translate }}

			{{ 'menu.register' | translate }}

			{{ 'menu.profile' | translate }}

			{{ 'menu.profileSettings' | translate }}

			{{ 'menu.myPets' | translate }}

			{{ 'menu.logout' | translate }}

			{{ 'menu.more' | translate }}

			{{ 'menu.intro' | translate }}

			{{ 'menu.helpAnimals' | translate }}

			{{ 'menu.information' | translate }}

			{{ 'menu.settings' | translate }}

			{{ 'menu.faq' | translate }}

			{{ 'menu.contact' | translate }}

	</ion-list>
</ion-content>


text:
namespace net {
class URLFetcher;
}  // namespace net

class Profile;

namespace chrome {

// Asynchrounously fetches an image from the given URL and returns the
// decoded Bitmap to the provided BitmapFetcherDelegate.
class BitmapFetcher : public net::URLFetcherDelegate,
                      public ImageDecoder::Delegate {
 public:
  BitmapFetcher(const GURL& url, BitmapFetcherDelegate* delegate);
  virtual ~BitmapFetcher();

  const GURL& url() const { return url_; }

  // Start fetching the URL with the fetcher. The delegate is notified
  // asynchronously when done.
  void Start(Profile* profile);

  // Methods inherited from URLFetcherDelegate

  // This will be called when the URL has been fetched, successfully or not.
  // Use accessor methods on |source| to get the results.
  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;

  // This will be called when some part of the response is read. |current|
  // denotes the number of bytes received up to the call, and |total| is the
  // expected total size of the response (or -1 if not determined).
  virtual void OnURLFetchDownloadProgress(const net::URLFetcher* source,
                                          int64 current,
                                          int64 total) OVERRIDE;

  // Methods inherited from ImageDecoder::Delegate

  // Called when image is decoded. |decoder| is used to identify the image in
  // case of decoding several images simultaneously.  This will not be called
  // on the UI thread.
  virtual void OnImageDecoded(const ImageDecoder* decoder,
                              const SkBitmap& decoded_image) OVERRIDE;

  // Called when decoding image failed.
  virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE;

 private:
  // Alerts the delegate that a failure occurred.
  void ReportFailure();

  scoped_ptr<net::URLFetcher> url_fetcher_;
  scoped_refptr<ImageDecoder> image_decoder_;
  const GURL url_;
  BitmapFetcherDelegate* const delegate_;

  DISALLOW_COPY_AND_ASSIGN(BitmapFetcher);
};

}  // namespace chrome

#endif  // CHROME_BROWSER_BITMAP_FETCHER_H_


text:
package templatescompiler_test

import (
	. "github.com/cloudfoundry/bosh-init/templatescompiler"

	"bytes"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"os"
	"path/filepath"

	bireljob "github.com/cloudfoundry/bosh-init/release/job"
	boshcmd "github.com/cloudfoundry/bosh-utils/fileutil"
	fakeboshcmd "github.com/cloudfoundry/bosh-utils/fileutil/fakes"
	boshlog "github.com/cloudfoundry/bosh-utils/logger"
	boshsys "github.com/cloudfoundry/bosh-utils/system"
	fakeboshsys "github.com/cloudfoundry/bosh-utils/system/fakes"

	fakebicrypto "github.com/cloudfoundry/bosh-init/crypto/fakes"
)

var _ = Describe("RenderedJobListCompressor", func() {
	var (
		outBuffer *bytes.Buffer
		errBuffer *bytes.Buffer
		logger    boshlog.Logger

		fakeSHA1Calculator *fakebicrypto.FakeSha1Calculator

		renderedJobList RenderedJobList

		renderedJobListCompressor RenderedJobListCompressor
	)

	BeforeEach(func() {
		outBuffer = bytes.NewBufferString("")
		errBuffer = bytes.NewBufferString("")
		logger = boshlog.NewWriterLogger(boshlog.LevelDebug, outBuffer, errBuffer)

		fakeSHA1Calculator = fakebicrypto.NewFakeSha1Calculator()

		renderedJobList = NewRenderedJobList()
	})

	Describe("Compress", func() {

		Context("with a real fs & compressor", func() {
			var (
				fs         boshsys.FileSystem
				cmdRunner  boshsys.CmdRunner
				compressor boshcmd.Compressor
			)

			BeforeEach(func() {
				fs = boshsys.NewOsFileSystem(logger)

				cmdRunner = boshsys.NewExecCmdRunner(logger)
				compressor = boshcmd.NewTarballCompressor(cmdRunner, fs)

				renderedJobListCompressor = NewRenderedJobListCompressor(fs, compressor, fakeSHA1Calculator, logger)
			})

			It("copies rendered jobs into a new temp dir, compresses the temp dir, and wraps it in a RenderedJobListArchive", func() {
				// create rendered job with 2 rendered scripts
				renderedJobDir0, err := fs.TempDir("RenderedJobListCompressorTest")
				Expect(err).ToNot(HaveOccurred())
				renderedJob0 := NewRenderedJob(bireljob.Job{Name: "fake-job-name-0"}, renderedJobDir0, fs, logger)
				defer func() { err := renderedJob0.Delete(); Expect(err).ToNot(HaveOccurred()) }()
				err = fs.WriteFileString(filepath.Join(renderedJobDir0, "script-0"), "fake-rendered-job-0-script-0-content")
				Expect(err).ToNot(HaveOccurred())
				err = fs.WriteFileString(filepath.Join(renderedJobDir0, "script-1"), "fake-rendered-job-0-script-1-content")
				Expect(err).ToNot(HaveOccurred())
				renderedJobList.Add(renderedJob0)

				// create another rendered job with 1 rendered script
				renderedJobDir1, err := fs.TempDir("RenderedJobListCompressorTest")
				Expect(err).ToNot(HaveOccurred())
				renderedJob1 := NewRenderedJob(bireljob.Job{Name: "fake-job-name-1"}, renderedJobDir1, fs, logger)
				defer func() { err := renderedJob1.Delete(); Expect(err).ToNot(HaveOccurred()) }()
				err = fs.WriteFileString(filepath.Join(renderedJobDir1, "script-0"), "fake-rendered-job-1-script-0-content")
				Expect(err).ToNot(HaveOccurred())
				renderedJobList.Add(renderedJob1)

				// compress
				archive, err := renderedJobListCompressor.Compress(renderedJobList)
				Expect(err).ToNot(HaveOccurred())
				defer func() { err := archive.Delete(); Expect(err).ToNot(HaveOccurred()) }()

				// decompress
				renderedJobListDir, err := fs.TempDir("RenderedJobListCompressorTest")
				Expect(err).ToNot(HaveOccurred())
				defer func() { err := fs.RemoveAll(renderedJobListDir); Expect(err).ToNot(HaveOccurred()) }()
				err = compressor.DecompressFileToDir(archive.Path(), renderedJobListDir, boshcmd.CompressorOptions{})
				Expect(err).ToNot(HaveOccurred())

				// verify that archive contained rendered scripts from job 0
				content, err := fs.ReadFileString(filepath.Join(renderedJobListDir, "fake-job-name-0", "script-0"))
				Expect(err).ToNot(HaveOccurred())
				Expect(content).To(Equal("fake-rendered-job-0-script-0-content"))
				content, err = fs.ReadFileString(filepath.Join(renderedJobListDir, "fake-job-name-0", "script-1"))
				Expect(err).ToNot(HaveOccurred())
				Expect(content).To(Equal("fake-rendered-job-0-script-1-content"))

				// verify that archive contained rendered scripts from job 1
				content, err = fs.ReadFileString(filepath.Join(renderedJobListDir, "fake-job-name-1", "script-0"))
				Expect(err).ToNot(HaveOccurred())
				Expect(content).To(Equal("fake-rendered-job-1-script-0-content"))
			})
		})

		Context("with a fake fs & compressor", func() {
			var (
				fakeFS         *fakeboshsys.FakeFileSystem
				fakeCompressor *fakeboshcmd.FakeCompressor
			)

			BeforeEach(func() {
				fakeFS = fakeboshsys.NewFakeFileSystem()

				fakeCompressor = fakeboshcmd.NewFakeCompressor()

				renderedJobListCompressor = NewRenderedJobListCompressor(fakeFS, fakeCompressor, fakeSHA1Calculator, logger)
			})

			It("calculates the fingerprint of the rendered", func() {
				fakeFS.TempDirDir = "fake-rendered-job-list-path"

				fakeSHA1Calculator.SetCalculateBehavior(map[string]fakebicrypto.CalculateInput{
					"fake-rendered-job-list-path": fakebicrypto.CalculateInput{Sha1: "fake-sha1"},
				})

				archive, err := renderedJobListCompressor.Compress(renderedJobList)
				Expect(err).ToNot(HaveOccurred())

				Expect(archive.Fingerprint()).To(Equal("fake-sha1"))
			})

			It("calculates the SHA1 of the archive", func() {
				fakeCompressor.CompressFilesInDirTarballPath = "fake-archive-path"

				fakeSHA1Calculator.SetCalculateBehavior(map[string]fakebicrypto.CalculateInput{
					"fake-archive-path": fakebicrypto.CalculateInput{Sha1: "fake-sha1"},
				})

				archive, err := renderedJobListCompressor.Compress(renderedJobList)
				Expect(err).ToNot(HaveOccurred())

				Expect(archive.SHA1()).To(Equal("fake-sha1"))
			})

			It("deletes the temp dir compressed into the archive", func() {
				fakeFS.TempDirDir = "fake-rendered-job-list-path"
				err := fakeFS.MkdirAll("fake-rendered-job-list-path", os.ModePerm)
				Expect(err).ToNot(HaveOccurred())

				_, err = renderedJobListCompressor.Compress(renderedJobList)
				Expect(err).ToNot(HaveOccurred())

				Expect(fakeFS.FileExists("fake-rendered-job-list-path")).To(BeFalse())
			})
		})
	})
})


text:
require 'formula'

class Pakchois < Formula
  desc "PKCS #11 wrapper library"
  homepage 'http://www.manyfish.co.uk/pakchois/'
  url 'http://www.manyfish.co.uk/pakchois/pakchois-0.4.tar.gz'
  sha1 'dea8a9a50ec06595b498bdefd1daacdb86e9ceda'

  def install
    system "./configure", "--disable-dependency-tracking",
                          "--prefix=#{prefix}"
    system "make install"
  end
end


text:
{% extends "base.html" %}
{% block content %}

					{% for article in articles_page.object_list %}

{{ article.title }}

 {{ article.locale_date }}

					{% endfor %}

{% endblock content %}