int encfs_common_streamDecode(encfs_common_custom_salt *cur_salt, unsigned char *buf, int size, uint64_t iv64, unsigned char *key)
{
	unsigned char ivec[ MAX_IVLENGTH ];
	int dstLen=0, tmpLen=0;
	EVP_CIPHER_CTX stream_dec;

	encfs_common_setIVec(cur_salt, ivec, iv64 + 1, key);
	EVP_CIPHER_CTX_init(&stream_dec);
	EVP_DecryptInit_ex( &stream_dec, cur_salt->streamCipher, NULL, NULL, NULL);
	EVP_CIPHER_CTX_set_key_length( &stream_dec, cur_salt->keySize );
	EVP_CIPHER_CTX_set_padding( &stream_dec, 0 );
	EVP_DecryptInit_ex( &stream_dec, NULL, NULL, key, NULL);

	EVP_DecryptInit_ex( &stream_dec, NULL, NULL, NULL, ivec);
	EVP_DecryptUpdate( &stream_dec, buf, &dstLen, buf, size );
	EVP_DecryptFinal_ex( &stream_dec, buf+dstLen, &tmpLen );
	unshuffleBytes( buf, size );
	flipBytes( buf, size );

	encfs_common_setIVec(cur_salt, ivec, iv64, key );
	EVP_DecryptInit_ex( &stream_dec, NULL, NULL, NULL, ivec);
	EVP_DecryptUpdate( &stream_dec, buf, &dstLen, buf, size );
	EVP_DecryptFinal_ex( &stream_dec, buf+dstLen, &tmpLen );
	EVP_CIPHER_CTX_cleanup(&stream_dec);

	unshuffleBytes( buf, size );
	dstLen += tmpLen;
	if(dstLen != size) {
	}

	return 1;
}
EncodedJSValue getData(ExecState* exec)
{
    JSDataView* dataView = jsDynamicCast<JSDataView*>(exec->thisValue());
    if (!dataView)
        return throwVMError(exec, createTypeError(exec, "Receiver of DataView method must be a DataView"));
    
    if (!exec->argumentCount())
        return throwVMError(exec, createTypeError(exec, "Need at least one argument (the byteOffset)"));
    
    unsigned byteOffset = exec->uncheckedArgument(0).toUInt32(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());
    
    bool littleEndian = false;
    unsigned elementSize = sizeof(typename Adaptor::Type);
    if (elementSize > 1 && exec->argumentCount() >= 2) {
        littleEndian = exec->uncheckedArgument(1).toBoolean(exec);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());
    }
    
    unsigned byteLength = dataView->length();
    if (elementSize > byteLength || byteOffset > byteLength - elementSize)
        return throwVMError(exec, createRangeError(exec, "Out of bounds access"));
    
    typename Adaptor::Type value = *reinterpret_cast<typename Adaptor::Type*>(static_cast<uint8_t*>(dataView->vector()) + byteOffset);
    
    if (needToFlipBytesIfLittleEndian(littleEndian))
        value = flipBytes(value);
    
    return JSValue::encode(Adaptor::toJSValue(value));
}
CommonChunk processComm(FILE* file){
	char buff[10];
	CommonChunk comm;
	int count = 0;
	int i;
	comm.chunkSize = 0;
	for(i = 0; i < 4; i++){
		buff[i] = fgetc(file);
		count++;
	}
	flipBytes(buff, 4);
	comm.chunkSize = *((int *)buff);
	for(i = 0; i < 2; i++){
		buff[i] = fgetc(file);
		count++;
	}
	flipBytes(buff, 2);
	comm.numChannels = *((short *)buff);
	for(i = 0; i < 4; i++){
		buff[i] = fgetc(file);
		count++;
	}
	flipBytes(buff, 4);
	comm.numSampleFrames = *((int *)buff);
	for(i = 0; i < 2; i++){
		buff[i] = fgetc(file);
		count++;
	}
	flipBytes(buff, 2);
	comm.sampleSize = *((short *)buff);
	for(i = 0; i < 10; i++){
		buff[i] = fgetc(file);
		count++;
	}
	flipBytes(buff, 10);
	long double sr = *((long double *)buff);
	comm.sampleRate = (int)sr;
	while(count < comm.chunkSize){
		fgetc(file);
		count++;
	}
	return comm;
}
/**

Sets up the initial part of the SSND chuck from the data.
This will calculate the size of the chunk, as well as write the other
parts of the SSND chunk.  When writing to a file this should always be called before writeSamplesAIFF
otherwise the SSND chunk will not be in the correct format

**/
void setupSoundAIFF(FILE* outfile, File_Data data){

	char bytes[4];

	strncpy(bytes, "SSND", 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	int fileSize = data.samples * (data.bitDepth / 8) * data.channels + 8;
	memcpy(bytes, (char*)&fileSize, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	fileSize = 0;
	memcpy(bytes, (char*)&fileSize, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	fileSize = 0;
	memcpy(bytes, (char*)&fileSize, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);
}
/**

Writes the samples from data.sampleData 
in the AIFF format

**/
int writeSamplesAIFF(FILE* outf, File_Data data){
	int i, j, k;
	char bytes[4];
	for(i = 0; i < data.samples; i++){
		for(j = 0; j < data.channels; j++){
			int x = data.sampleData[i][j];
			memcpy(bytes, &x, 4);
			flipBytes(bytes, 4);
			if(data.bitDepth == 8){
				fwrite(&bytes[3], 1, 1, outf);
			} 
			else if(data.bitDepth == 16){
				fwrite(&bytes[2], 2, 1, outf);
			} 
			else if(data.bitDepth == 32){
				fwrite(&bytes, 4, 1, outf);
			}
		}
	}
}
/**

Writes the header of an AIFF file from the given data

**/
void writeHeaderAIFF(FILE* outfile, File_Data data){
	int fileSize = 30 + data.samples * (data.bitDepth/8) * data.channels;

	char bytes[4] = "FORM";
	fwrite(bytes, sizeof(bytes), 1, outfile);

	memcpy(bytes, (char*)&fileSize, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	strncpy(bytes, "AIFF", 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);
	

	strncpy(bytes, "COMM", 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	fileSize = 18;
	memcpy(bytes, (char*)&fileSize, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	memcpy(bytes, (char*)&data.channels, 2);
	flipBytes(bytes, 2);
	fwrite(bytes, sizeof(bytes)/2, 1, outfile);

	memcpy(bytes, (char*)&data.samples, 4);
	flipBytes(bytes, 4);
	fwrite(bytes, sizeof(bytes), 1, outfile);

	memcpy(bytes, (char*)&data.bitDepth, 2);
	flipBytes(bytes, 2);
	fwrite(bytes, sizeof(bytes)/2, 1, outfile);

	char buff[10];
	long double sr = (long double)data.sampleRate;
	memcpy(buff, (char*)&sr, 10);
	flipBytes(buff, 10);
	fwrite(buff, sizeof(buff), 1, outfile);
}
/**

Gets the samples from an AIFF file and stores them in fileData.sampleData

**/
void getSamplesAIFF(char * infilepath, File_Data *fileData){
	
	fileData->sampleData = malloc(fileData->samples*sizeof(int*));
	int i, j, k;	
	for(i = 0; i < fileData->samples; i++){
		fileData->sampleData[i] = malloc(fileData->channels*sizeof(int));
	}

	if(foundSoundData){
		fprintf(stderr, "Sound data chunk was not found.\n");
		return;
	}
	FILE* inf = NULL;
	if(!infilepath){
		inf = stdin;
	}else{
		inf = fopen(infilepath, "r");
	}
	if(fsetpos(inf, &SSNDLocation)){
		fprintf(stderr, "Error reading sound data chunk.\n");
		return;
	}
	SoundDataChunk data;

	char buff[4];

	for (i = 0; i < 4; i++)
	{
		buff[i] = fgetc(inf);
	}
	flipBytes(buff, 4);
	data.chunkSize = *((int*)buff);
	for (i = 0; i < 4; ++i)
	{
		buff[i] = fgetc(inf);
	}
	flipBytes(buff, 4);
	data.offset = *((int*)buff);
	for (i = 0; i < 4; ++i)
	{
		buff[i] = fgetc(inf);
	}
	flipBytes(buff, 4);
	char sample[4];
	data.blockSize = *((int*)buff);
	for (i = 0 ; i < fileData->samples; i++){
		for(k = 0; k < fileData->channels; k++){
			for (j = 0; j < 4; j++){
				sample[j] = 0;
			}	
			for (j = 0; j < fileData->bitDepth / 8; j++){
				sample[j] = getc(inf);
			}
			/** Converts to little endian and then stores it correctly based on the bitDepth **/
			flipBytes(sample, fileData->bitDepth / 8);
			if(fileData->bitDepth == 8){
				fileData->sampleData[i][k] = (int)sample[0];
			}
			else if(fileData->bitDepth == 16){
				fileData->sampleData[i][k] = (int)(*((short*)sample));
			}
			else if(fileData->bitDepth == 32){
				fileData->sampleData[i][k] = (int)(*((int*)sample));
			}
		}
	}
	fclose(inf);
}
/**

Process the AIFF file.  This method will call processCOMM to handle the COMM section.  
It will mark the position of the sound file so processSSND and getSamplesAIFF can perform correctly. 

**/
File_Data processAIFF(FILE *outfile, FILE* infile){
	int foundComm = 0;
	int foundSSND = 0;
	File_Data data;
	CommonChunk comm;
	SoundDataChunk sdc;
	data.samples = -1;
	data.channels = -1;
	data.sampleRate = -1;
	data.bitDepth = -1;
	data.success = 0;

	char buff[4];


	int i, j;
	for(i = 0; i < 4; i++){
		buff[i] = fgetc(infile);
	}
	flipBytes(buff, 4);
	int y = *((int*)buff);

	for(i = 0; i < 4; i++){
		buff[i] = fgetc(infile);
	}
	if(strncmp(buff, "AIFF", 4) != 0){
		data.success = 0;
		return data;
	}else {
		strncpy(data.format, "AIFF\0", 5);
	}
	while(!foundComm || !foundSSND){
		buff[0] = fgetc(infile);
		if(EOF == buff[0]){
			data.success = 0;
			return data;
		}else if(buff[0] != 'C' && buff[0] != 'S' && buff[0] != 'A'){
			continue;
		}

		for(i = 1; i < 4; i++){
			buff[i] = fgetc(infile);
			if(buff[i] == 'C'){
				ungetc(buff[i], infile);
				continue;
			}
		}
		if(strncmp(buff, "COMM", 4) == 0){
			comm = processComm(infile);
			data.samples = comm.numSampleFrames;
			data.channels = comm.numChannels;
			data.sampleRate = comm.sampleRate;
			data.bitDepth = comm.sampleSize;
			strcpy(data.duration, findDuration(data.sampleRate, data.channels, data.samples, data.duration));
			foundComm = 1;
		}
		if(strncmp(buff, "SSND", 4) == 0){
			/*Marks the position of the SSND chunk so it can be processed later*/
			foundSoundData = fgetpos(infile, &SSNDLocation);
			foundSSND = 1;
		}
		if(strncmp(buff, "COMT", 4) == 0 || strncmp(buff, "ANNO", 4) == 0 ){
			/* Runs through comment chunks */
			int chunkSize;
			char sizeBuff[4];
			for(j = 0; j < 4; j++){
				sizeBuff[j] = fgetc(infile);
			}
			flipBytes(sizeBuff, 4);
			chunkSize = *((int *)sizeBuff);
			int count = 0;
			while(count < chunkSize){
				count++;
				fgetc(infile);
			}

		}
	}
	if(foundSSND && foundComm)
		data.success = 1;
	return data;
}