how to read a huge array of bytes in chunks - pj_strset - ios

I am working on an iOS project
I have to read a huge file in chunks of 4KB
Here is what I have so far:
NSData *fileData= [self getBytesFromInput];
pj_str_t text;
int chunkSize = 4*1024;
int fileSize = [fileData length];
while (fileSize>0){
if (fileSize<=chunkSize) {
chunkSize = fileSize;
fileSize=0;
}
else fileSize = fileSize-chunkSize;
pj_strset(&text, (char*)[fileData bytes], MIN([fileData length], chunkSize); //takes the first chunk
//BUT HOW TO TAKE THE NEXT CHUNK OF DATA?
//do something with the &text ....
}

i would refactor the code so you are also loading the files in chunks, but you can access the later chunks by adding an offset to your byte-pointer:
int currentOffset = 0;
while (fileSize>0) {
...
char* bytePointer = (char*)[fileData bytes];
pj_strset(&text, bytePointer+currentOffset, MIN([fileData length], chunkSize);
currentOffset += chunkSize;
}
EDIT:
This should do the same thing but reading the file chunk for chunk:
NSString *yourFilePath;
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:yourFilePath];
int chunksize = 4*1024;
pj_str_t text;
NSData *data;
while ((data = [fileHandle readDataOfLength:chunksize]) && [data length] > 0) {
pj_strset(&text, (char*)[data bytes], [data length]);
}

Related

We are facing problem while creating compressed file of transferred socket data in hex string to converting to .tgz file in iOS App

We are facing problem while creating compressed file at iOS Device Document Directory, .tgz file is in Hex string transferring from pin-pad device to iPad iOS App at TCP socket layer. We used below HexToString function to convert that hex string and make file with .tgz. but at the end file is corrupted.
Can anyone please help us here, how to create compress file at iOS level with below hex string ? Please suggest us any code changes.
Note :- we had tried multiple NSStringEncoding technique, like ASCII, Unicode, Utf8, etc.
HEX String:-
1F8B08003058A8620203EDCA3B0A80301045D1594A5660265FB7E036065422A8453282CB57B4B2B112419CD3DCE2BD6966DD8F54925E4A975B62D22551EE741A2A5E199E80BBE8F1681DFDA5270BC6DB60D1398735A0092E0650082F580A53566A6F36F7BFFBFDA39A01841042FCD0062C8057FA00080000
we are using Xcode Version:13.1 and IOS Version 15.1 and above.
//Below function we used for creating .tgz file
//fileName here is abc.tgz which is compress file type
//content here is hex string mention aboved
+ (void)writeToLogFile:(NSString*)content fileName:(NSString*)fileNameString{
content = [NSString stringWithFormat:#"%#",content];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *fileName = [documentsDirectory stringByAppendingPathComponent:fileNameString];
NSData *fileOriginalString = [self HextoString:content];
NSData *fileData = [fileOriginalString dataUsingEncoding:NSASCIIStringEncoding];
***//In alternative we also tried direct hex string to NSData type by calling below commentented method but it still failing
//NSData *fileData = [self dataFromHexString:content];***
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSError *error = nil;
[fileData writeToFile:fileName options:NSDataWritingAtomic error:&error];
NSLog(#"Write returned error: %#", [error localizedDescription]);
});
}
//Below function we used for Hex to String conversion
+(NSString*)HextoString:(NSString*)string{
#try{
NSMutableString * StrResult = [[NSMutableString alloc] init];
int i = 0;
while (i < [string length]){
NSString * hexChar = [string substringWithRange: NSMakeRange(i, 2)];
int value = 0;
sscanf([hexChar cStringUsingEncoding:NSASCIIStringEncoding], "%x", &value);
[StrResult appendFormat:#"%c", (char)value];
i+=2;
}
return StrResult;
}
#catch (NSException *exception){
[AELoggerManager info:[NSString stringWithFormat:#" %s EXCEPTION ::%#",__FUNCTION__,exception]];
}
}
+ (NSData *)dataFromHexString:(NSString *) string {
if([string length] % 2 == 1){
string = [#"0"stringByAppendingString:string];
}
const char *chars = [string UTF8String];
int i = 0, len = (int)[string length];
NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
char byteChars[3] = {'\0','\0','\0'};
unsigned long wholeByte;
while (i < len) {
byteChars[0] = chars[i++];
byteChars[1] = chars[i++];
wholeByte = strtoul(byteChars, NULL, 16);
[data appendBytes:&wholeByte length:2];
}
return data;
}

Write NSData in half bytes

I need to write a hex string to NSData but I am getting an extra zero appended to the end and it is causing me some issues. Is there a way to write half bytes to NSData?
For example I am converting 100010002 and I am getting 1000100020 (extra zero).
This is what I am using to convert the hex string to NSData. Thanks.
+ (NSData *)dataFromHexString:(NSString*)stringToConvert {
    const char *chars = [stringToConvert UTF8String];
    int i = 0;
    int len = (int)[stringToConvert length];
    
    NSMutableData *data = [NSMutableData dataWithCapacity:len / 2];
    char byteChars[3] = {'\0','\0','\0'};
    unsigned long wholeByte;
    
    while (i < len) {
        byteChars[0] = chars[i++];
        byteChars[1] = chars[i++];
        wholeByte = strtoul(byteChars, NULL, 16);
        [data appendBytes:&wholeByte length:1];
    }
    
    return data;
}

Convert NSData to CMSampleBufferRef

Is there any way to create CMSampleBufferRef from NSData? NSData object has also be constructed from CMSampleBufferRef formerly. I need that conversion because I want to save the CMSampleBufferRef frames (as NSData) that are taken from live camera using AVFoundation, then be able to use the CMSampleBufferRef frames (by converting NSData objects to CMSampleBufferRef) to construct a video.
Thanks in advance...
-(AudioBufferList *) getBufferListFromData: (NSData *) data
{
if (data.length > 0)
{
NSUInteger len = [data length];
//I guess you can use Byte*, void* or Float32*. I am not sure if that makes any difference.
Byte * byteData = (Byte*) malloc (len);
memcpy (byteData, [data bytes], len);
if (byteData)
{
AudioBufferList * theDataBuffer =(AudioBufferList*)malloc(sizeof(AudioBufferList) * 1);
theDataBuffer->mNumberBuffers = 1;
theDataBuffer->mBuffers[0].mDataByteSize = len;
theDataBuffer->mBuffers[0].mNumberChannels = 1;
theDataBuffer->mBuffers[0].mData = byteData;
// Read the data into an AudioBufferList
return theDataBuffer;
}
}
return nil;
}

Read integer from file IOS

I have a file that contains in the very first byte of data a number. In this case that number is 32. I have used a hex editor to confirm that (in hex) the value is "20" which equals 32 in decimal.
Can someone point me in the right direction of how to read it out of the file. I have tried about 6 different ways all of which have failed.
Lots of different ways. Here's one:
NSData *data = [NSData dataWithContentsOfFile:filename];
if ([data length] > 0)
{
const uint8_t *bytes = (const uint8_t *)[data bytes];
uint8_t byte = bytes[0];
NSLog(#"%d", byte);
}
or another:
NSInputStream *stream = [NSInputStream inputStreamWithFileAtPath:filename];
[stream open];
NSInteger bufferLen = 1;
uint8_t buffer[bufferLen];
NSInteger count = [stream read:buffer maxLength:bufferLen];
[stream close];
if (count > 0)
{
NSLog(#"%d", buffer[0]);
}

Web service to Xcode encryption

I am trying encrypt data on an iPhone and send up the encrypted text to a web service for them to decrypt it. If the decryption works then it returns the First name in the xml as a confirmation things worked. Here is my Xcode
Note: The 'key' is the same in both xcode and web service
The information I want encrypted:
NSString *fnameencrypted = [[NSString alloc] AES256EncryptWithKey:f_name.text withKey:key]];
NSString *lnameencrypted = [[NSString alloc] AES256EncryptWithKey:l_name.text withKey:key]];
The NSString method
-(NSString *)AES256EncryptWithKey:(NSString *)plaintext withKey:(NSString *)key{
NSData *plainData = [plaintext dataUsingEncoding:NSASCIIStringEncoding];
NSData *encryptedData = [plainData AES256EncryptWithKey:key];
NSString *encryptedString = [encryptedData base64Encoding];
return encryptedString;
}
EDIT
The encryption method
-(NSData *)AES256EncryptWithKey:(NSString *)key{
char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSASCIIStringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionECBMode + kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if(cryptStatus == kCCSuccess){
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer
return nil;
}
Here is my web service code
private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize)
{
RijndealManaged aesEncryption = new RijndealManaged();
aesEncryption.KeySize = keySize; //keySize is 256
aesEncryption.BlockSize = 128;
aesEncryption.Mode = CipherMode.ECB;
aesEncryption.Padding = PaddingMode.PKCS7;
aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.ACSII.GetString(Convert.FromBase64String(completeEncodedString)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.ACSII.GetString(Convert.FromBase64String(completeEncodedString)).Split(',')[1]);
ICryptoTransform decrypto = aesEncryption.CreateDecryptor();
byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length);
return ASCIIEncoding.ASCII.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);
}
This code does not work because it returns
<response><return>0</return></response>

Resources