Read callbacks needed by AudioFileInitializeWithCallbacks? Apple AudioFile API - c

I am trying to write a lowish level audio writer with the AudioFile & ExtAudioFile APIs. I am creating a new audio file with AudioFileInitializeWithCallbacks but it appears that this needs read & get size callbacks implemented. Why can't this just accept a single write callback and trust that the data has been written sucessfully.
What if I am writing to a stream which I can not seek into such as a CD or a network socket?
Surely this should just continually push data to the write callback and it is my responsibility to write this data where needed returning an error code if the operation didn't succeed.
The docs for AudioFile_SetSizeProc and AudioFile_WriteProc appear to be incorrect as they both talk about read operations "inPosition An offset into the data from which to read.", "#result The callback should return the size of the data.".
At the moment I have got past this by only writing to a file but I get a kExtAudioFileError_InvalidOperationOrder after the first write procedure. What does this mean? There are no comments in the docs about it.
Any pointers or help would be much appriciated.

Apple documentation is wrong here. Check header file AudioFile.h:
/*!
#typedef AudioFile_SetSizeProc
#abstract A callback for setting the size of the file data. used with AudioFileOpenWithCallbacks or AudioFileInitializeWithCallbacks.
#discussion a function that will be called when AudioFile needs to set the size of the file data. This size is for all of the
data in the file, not just the audio data. This will only be called if the file is written to.
#param inClientData A pointer to the client data as set in the inClientData parameter to AudioFileXXXWithCallbacks.
#result The callback should return the size of the data.
*/
typedef OSStatus (*AudioFile_SetSizeProc)(
void * inClientData,
SInt64 inSize);

Related

what callback do we get when file is cleared (i.e. Made empty) and saved in Minifilter?

I am Working on a minifilter to detect files write by some process in the PreWrite callback of IRP_MJ_WRITE. It works great when some files content is modified. But not getting PreWrite callback when the file content is modified and made to zero sizes. i.e select all then clear out the content and finally save the file. it is also kind of writing so why not getting a PreWrite callback?
How to prevent File writing(clear all content & save the file)?
or what callback do we get when file content is cleared(i.e becomes empty) and the file is saved?
As a beginner in minifilter, am I missing something or unaware of some concept?
Please guide/help me.
I will be very thankful to the Stackoverflow community.
exist 2 ways (how i know) for empty file (set it size to 0)
call NtSetInformationFile with
FileEndOfFileInformation
in this case IRP_MJ_SET_INFORMATION callback will be invoked. you need check that
Data->Iopb->Parameters.SetFileInformation.FileInformationClass == FileEndOfFileInformation. in this case InfoBuffer will point to FILE_END_OF_FILE_INFORMATION where new EndOfFile value
call NtCreateFile or IoCreateFile
with CreateDisposition equal to
FILE_OVERWRITE or FILE_OVERWRITE_IF or FILE_SUPERSEDE (in this case file will be deleted and new empty file created with same name). the IRP_MJ_CREATE callback will be invoked. you need check:
PFLT_PARAMETERS Parameters = &Data->Iopb->Parameters;
ULONG Options = Parameters->Create.Options;
ULONG CreateDisposition = Options >> 24;
Options &= 0x00ffffff;
CreateDisposition value for FILE_OVERWRITE or FILE_OVERWRITE_IF or FILE_SUPERSEDE

Spring Batch FlatFileItemWriter does not write data to a file

I am new to Spring Batch application. I am trying to use FlatFileItemWriter to write the data into a file. Challenge is application is creating the file on a given path, but, now writing the actual content into it.
Following are details related to code:
List<String> dataFileList : This list contains the data that I want to write to a file
FlatFileItemWriter<String> writer = new FlatFileItemWriter<>();
writer.setResource(new FileSystemResource("C:\\Desktop\\test"));
writer.open(new ExecutionContext());
writer.setLineAggregator(new PassThroughLineAggregator<>());
writer.setAppendAllowed(true);
writer.write(dataFileList);
writer.close();
This is just generating the file at proper place but contents are not getting written into the file.
Am I missing something? Help is highly appreciated.
Thanks!
This is not a proper way to use Spring Batch Writer and writer data. You need to declare bean of Writer first.
Define Job Bean
Define Step Bean
Use your Writer bean in Step
Have a look at following examples:
https://github.com/pkainulainen/spring-batch-examples/blob/master/spring-boot/src/main/java/net/petrikainulainen/springbatch/csv/in/CsvFileToDatabaseJobConfig.java
https://spring.io/guides/gs/batch-processing/
You probably need to force a sync to disk. From the docs at https://docs.spring.io/spring-batch/trunk/apidocs/org/springframework/batch/item/file/FlatFileItemWriter.html,
setForceSync
public void setForceSync(boolean forceSync)
Flag to indicate that changes should be force-synced to disk on flush. Defaults to false, which means that even with a local disk changes could be lost if the OS crashes in between a write and a cache flush. Setting to true may result in slower performance for usage patterns involving many frequent writes.
Parameters:
forceSync - the flag value to set

Akka stream each element to ftp sink

I want to write each element in an Akka stream to a (different) FTP file. Using Alpakka I can write each element to the same file using an FTP sink. However I can not seem to figure out how to write each element to a different file.
source.map(el -> /* to byte string */).to(Ftp.toPath("/file.xml", settings));
So every el should end up in a different file.
If you want to use the Alpakka FTP sink, you have to do something along the lines of
def sink(n: String): Sink[String, NotUsed] = Ftp.toPath(s"$n.txt", settings)
source.runForeach(s ⇒ Source.single(s).runWith(sink(s)))
otherwise, you'll need to create your own sink that establishes an FTP connection and writes the data as part of the input handler. You'll need to create your own graph stage to do it. More info about this can be found in the docs.

How to send/receive binary data over TCP using NodeMCU?

I've been trying to mount a custom protocol over the TCP module on the NodeMCU platform. However, the protocol I try to embed inside the TCP data segment is binary, not ASCII-based(like HTTP for example), so sometimes it contains a NULL char (byte 0x00) ending the C string inside the TCP module implementation, causing that part of the message inside the packet get lost.
-- server listens on 80, if data received, print data to console and send "hello world" back to caller
-- 30s time out for a inactive client
sv = net.createServer(net.TCP, 30)
function receiver(sck, data)
print(data)
sck:close()
end
if sv then
sv:listen(80, function(conn)
conn:on("receive", receiver)
conn:send("hello world")
end)
end
*This is a simple example which, as you can see, the 'receiver' variable is a callback function which prints the data from the TCP segment retrieved by the listener.
How can this be fixed? is there a way to circumvent this using the NodeMCU library? Or do I have to implement another TCP module or modify the current one's implementation to support arrays or tables as a return value instead of using strings?
Any suggestion is appreciated.
The data you receive in the callback should not be truncated. You can check this for yourself by altering the code as follows:
function receiver(sck, data)
print("Len: " .. #data)
print(data)
sck:close()
end
You will observe, that, while the data is indeed only printed up to the first zero byte (by the print()-function), the whole data is present in the LUA-String data and you can process it properly with 8-bit-safe (and zerobyte-safe) methods.
While it should be easy to modify the print()-function to also be zerobyte-safe, I do not consider this as a bug, since the print function is meant for texts. If you want to write binary data to serial, use uart.write(), i.e.
uart.write(0, data)

Download File (using Thread class)

Ok, I understand that maybe very stupid question, but i never did it before, so i ask this question. How can i download file (let's say, from the internet) using Thread class?
What do you mean with "using Thread class"? I guess you want to download a file threaded so it does not block your UI or some other part of your program.
Ill assume that your using C++ and WINAPI.
First create a thread. This tutorial provides good information about WIN32 threads.
This thread will be responsible for downloading the file. To do this you simply connect to the webserver on port 80 and send a HTTP GET request for the file you want. It could look similar to this (note the newline characters):
GET /path/to/your/file.jpg HTTP/1.1\r\n
Host: www.host.com\r\n
Connection: close\r\n
\r\n
\r\n
The server will then answer with a HTTP response containing the file with a preceding header. Parse this header and read the contents.
More information on HTTP can be found here.
If would suggest that you do not use threads for downloading files. It's better to use asynchronous constructs that are more targeted towards I/O, since they will incur a lower overhead than threads. I don't know what version of the .NET Framework you are working with, but in 4.5, something like this should work:
private static Task DownloadFileAsync(string uri, string localPath)
{
// Get the http request
HttpWebRequest webRequest = WebRequest.CreateHttp(uri);
// Get the http response asynchronously
return webRequest.GetResponseAsync()
.ContinueWith(task =>
{
// When the GetResponseAsync task is finished, we will come
// into this contiuation (which is an anonymous method).
// Check if the GetResponseAsync task failed.
if (task.IsFaulted)
{
Console.WriteLine(task.Exception);
return null;
}
// Get the web response.
WebResponse response = task.Result;
// Open a file stream for the local file.
FileStream localStream = File.OpenWrite(localPath);
// Copy the contents from the response stream to the
// local file stream asynchronously.
return response.GetResponseStream().CopyToAsync(localStream)
.ContinueWith(streamTask =>
{
// When the CopyToAsync task is finished, we come
// to this continuation (which is also an anonymous
// method).
// Flush and dispose the local file stream. There
// is a FlushAsync method that will flush
// asychronously, returning yet another task, but
// for the sake of brevity I use the synchronous
// method here.
localStream.Flush();
localStream.Dispose();
// Don't forget to check if the previous task
// failed or not.
// All Task exceptions must be observed.
if (streamTask.IsFaulted)
{
Console.WriteLine(streamTask.Exception);
}
});
// since we end up with a task returning a task we should
// call Unwrap to return a single task representing the
// entire operation
}).Unwrap();
}
You would want to elaborate a bit on the error handling. What this code does is in short:
See the code comments for more detailed explanations of how it works.

Resources