read multiple files with quite similar names c++ - c++-cli

I am reading a file from current directory
ifstream myfile;
myfile.open("version1.1.hex");
Now a situation is arising that if user updates version then there will be version1.2.hex or version1.3.hex ..so on in the current directory, but one file at a time will be present. I want to write a code now which will cater this future need of reading different file.
I'm writing this code in C++/CLI.

Since file listings are a bit environment-dependant I am not sure if this is helpful to you,
but here is an example how to achieve your goal under the mircosoft regime.
What is needed is the FindFirstFile / FindNextFile calls which query all files matching the fileSearchKey. Then you can use the cFileName part of WIN32_FIND_DATAA as parameter to your open command
string fileSearchKey = "version*";
WIN32_FIND_DATAA fd;
bool bFirstRun = true;
bool bFinishedRun = false;
HANDLE h = INVALID_HANDLE_VALUE;
while (!bFinishedRun)
{
if (bFirstRun)
{
h = FindFirstFileA(fileSearchKey.c_str(), &fd);
bFirstRun = false;
} else
{
if (FindNextFileA(h, &fd) != FALSE)
{
// Abort with error because it has more than one file or decide for the most recent version
} else
{
bFinishedRun = true;
}
}
}
// Load file
ifstream myfile;
myfile.open(fd.cFileName);

This code will look in the directory and take the first file, then quit.
WARNING : this will work only on linux
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <cstring>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
int main ()
{
char n[20];
unsigned char isFolder = 0x4;
unsigned char isFile = 0x8;
DIR *dir;
struct dirent *ent;
dir = opendir ("./");
if (dir != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
//folder sign
if(ent->d_type != isFolder && string(ent->d_name).find("version") != string::npos)
{
cout <<ent->d_name <<"\n";
// Your code
break;
}
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return 0;
}
cout << "=========" << endl;
}

In C++/CLI you should use the .net framework libraries for this. For instance you can use Directory::GetFiles.
using namespace System;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
array<String^>^dirs = Directory::GetFiles(".", "version1.*.hex");
Collections::IEnumerator^ myEnum = dirs->GetEnumerator();
while (myEnum->MoveNext())
{
Console::WriteLine(myEnum->Current);
}
return 0;
}

Related

Simple parsing to a tuple fails

Why does this not compile? The marked line gives me: "static assertion failed: The parser expects tuple-like attribute type". I would think that an std::tuple were the essence of "tuple-like"?
#include <string>
#include <tuple>
#include <boost/spirit/home/x3.hpp>
void parseInteger(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
int result;
x3::parse(iter, end_iter, x3::int_, result);
}
void parseIntegerAndDouble(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
std::tuple<int, double> result;
x3::parse(iter, end_iter, x3::int_ >> ' ' >> x3::double_, result); //Compile error!
}
int main(int, char **)
{
parseInteger("567");
parseIntegerAndDouble("321 3.1412");
return 0;
}
The trick is to include two additional header files:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/std_tuple.hpp>
This is a bit more magical than I like, but I've got a feeling I really don't want to know how this works!

How can I stop the program inside the a parent or a child process?

I have this piece of code that I developed just to address a problem that I have in another large program that I am developing.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <limits.h>
#include <string>
#include <iostream>
using namespace std;
void processLine (char []);
void readLine(char []);
const int LIMIT = 512;
int main(int argc, char *argv[])
{
char oneLine[LINE_MAX];
readLine(oneLine);
return 0;
}
void readLine(char line[])
{
processLine(line);
//Otherstuff
------------
}
void processLine(char line[])
{
pid_t process;
int child_status;
string input;
cout << "Input: ";
cin >> input;
process = fork();
if(process == 0)
{ // do nothing
}
else
{
//parent
if(input == "quit")
{
printf("Quit command found ! \nExiting ");
for(int i = 0;i < 3;i++)
{
printf(".");
fflush(stdout);
sleep(1);
}
printf("\n");
exit(0);
}
else
{
wait(&child_status);
}
}
}
My goal is simple, When the user enter quit.
I will just display
Quit command found
Exiting ...
And there is a delay of one second between each of these three dots.
However the output that I get is
Quit command found
Exiting . other stuff ..
However, what seems to happen is that the parent process returns and then executes other stuff from the calling function before it continues to print the other two dots. How would I avoid the parent process from doing that ?
Use waitpid() like this:
pid_t childPid;
childPid = fork();
...
int returnStatus;
waitpid(childPid, &returnStatus, 0); // Parent process waits here for child to terminate.
Use it here
if(childPid == 0) // fork succeeded
{
// Do something
exit(0);
}
else // Main (parent) process after fork succeeds
{
int returnStatus;
waitpid(childPid, &returnStatus, 0);
}

Is it possible to get list of files in directory using apache portable runtime?

I need to get list of files in directory using APR. How can I do it?
I was looking for answer in documentation, but found nothing.
Thanks!
The function you want is apr_dir_open. I found the header files to be the best documentation for APR
http://apr.apache.org/docs/apr/1.4/group_apr_dir.html
Here is an example for reading "." and reporting errors if any were encountered
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <apr.h>
#include <apr_errno.h>
#include <apr_pools.h>
#include <apr_file_info.h>
static void apr_fatal(apr_status_t rv);
int main(void)
{
apr_pool_t *pool;
apr_status_t rv;
// Initialize APR and pool
apr_initialize();
if ((rv = apr_pool_create(&pool, NULL)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Open the directory
apr_dir_t *dir;
if ((rv = apr_dir_open(&dir, ".", pool)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Read the directory
apr_finfo_t finfo;
apr_int32_t wanted = APR_FINFO_NAME | APR_FINFO_SIZE;
while ((rv = apr_dir_read(&finfo, wanted, dir)) == APR_SUCCESS) {
printf("%s\t%10"PRIu64"\n", finfo.name, (uint64_t)finfo.size);
}
if (!APR_STATUS_IS_ENOENT(rv)) {
apr_fatal(rv);
}
// Clean up
apr_dir_close(dir);
apr_pool_destroy(pool);
apr_terminate();
return 0;
}
static void apr_fatal(apr_status_t rv)
{
const int bufsize = 1000;
char buf[bufsize+1];
printf("APR Error %d: %s\n", rv, apr_strerror(rv, buf, bufsize));
exit(1);
}

How can i make that in the List codec's it will also show me the type of each codec?

The type of each codec or the type of the codec's
In the List i have in the end about 500 codec's i want that for example in the List in the beginning it will show for example:
Audio
mpeha
mpegv
.....
Video
xvid
divx
And so on.
The first two functions to get the List of codec's are in C:
const char* Encoder_GetNextCodecName()
{
current_codec = av_codec_next(current_codec);
while (current_codec != NULL)
{
return current_codec->name;
}
return "";
}
const char* Encoder_GetFirstCodecName()
{
current_codec = NULL;
return Encoder_GetNextCodecName();
}
Then i have header file:
const char* Encoder_GetNextCodecName();
const char* Encoder_GetFirstCodecName();
Then another C++ header file where i create the List:
List<String^> ^GetCodecs()
{
List<String^> ^l = gcnew List<String^>;
String ^s = gcnew String(Encoder_GetFirstCodecName());
while (!String::IsNullOrEmpty(s))
{
l->Add(s);
s = gcnew String(Encoder_GetNextCodecName());
}
return l;
}
Then when i'm doing in CSHARP this:
List<string> l = new List<string>(f.GetCodecs());
I see that the variable l containing 506 codec's .
The codec's are of ffmpeg !!!
Now in the C file there is also something like:
current_codec->type
Which have many properties.
And there is also something like this in the C file:
AVMediaType::
Which give me a 7 categories of types of the codec's.
The problem is how do i make in the C++ header file when i create the List that the List will be with the types of each codec or of each group of codec's like : Audio,Video,Data.... ?
EDIT
This is another header file i have that is connecting between the C functions and the CLI:
I have another header file where i first call the functions from C:
ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
bool Encoder_MoveToNextCodec();
bool Encoder_MoveToFirstCodec();
const char* Encoder_GetCurrentCodecName();
int Encoder_GetCurrentCodecType();
#ifdef __cplusplus
} // extern "C"
#endif
This is my CLI code:
#pragma once
// FFMPEG_WRAPPER.cpp : Defines the exported functions for the DLL application.
//
#include "ENCODER.h"
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
#include <vcclr.h>
#include <cstdlib>
#include <Windows.h>
using namespace System;
using namespace System::Drawing;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
using namespace System::Drawing::Imaging;
using namespace msclr::interop;
namespace MyVideo
{
public ref class FFMPEGWrapper
{
public:
FFMPEGWrapper(void)
{
Encoder_init();
}
ref class CodecInfo
{
public:
String^ CodecName;
int CodecType;
};
List<CodecInfo^> ^GetCodecs()
{
List<CodecInfo^> ^l = gcnew List<CodecInfo^>;
bool KeepLooping = Encoder_MoveToFirstCodec();
while (KeepLooping)
{
CodecInfo ^codec = gcnew CodecInfo();
codec->CodecName = gcnew String(Encoder_GetCurrentCodecName());
codec->CodecType = Encoder_GetCurrentCodecType();
l->Add(codec);
KeepLooping = Encoder_MoveToNextCodec();
}
return l;
}
Then in CSHARP i did:
List<f.CodecInfo> l = f.GetCodecs();
But CodecInfo is not exist and i'm getting an error on the GetCodecs()
Error 1 Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List'
Error 2 'ScreenVideoRecorder.Form1.f' is a 'field' but is used like a 'type'
The problems the errors are in CSHARP.
You need to expand your C code to expose the extra details you want, eg:
__declspec(thread) AVCodec* current_codec = NULL;
bool Encoder_MoveToNextCodec()
{
current_codec = av_codec_next(current_codec);
return (current_codec != NULL);
}
bool Encoder_MoveToFirstCodec()
{
current_codec = NULL;
return Encoder_MoveToNextCodec();
}
const char* Encoder_GetCurrentCodecName()
{
if (current_codec != NULL)
return current_codec->name;
return "";
}
int Encoder_GetCurrentCodecType()
{
if (current_codec != NULL)
return (int) current_codec->type;
return AVMEDIA_TYPE_UNKNOWN;
}
Then expand your CLI code to store that info:
ref class CodecInfo
{
public:
String^ CodecName;
int CodecType;
...
};
List<CodecInfo^> ^GetCodecs()
{
List<CodecInfo^> ^l = gcnew List<CodecInfo^>;
bool KeepLooping = Encoder_MoveToFirstCodec();
while (KeepLooping)
{
CodecInfo ^codec = gcnew CodecInfo();
codec->CodecName = gcnew String(Encoder_GetCurrentCodecName());
codec->CodecType = Encoder_GetCurrentCodecType();
...
l->Add(codec);
KeepLooping = Encoder_MoveToNextCodec();
}
return l;
}
Then lastly, use the new info as needed:
List<CodecInfo> l = f.GetCodecs();
foreach(CodecInfo codec in l)
{
// use codec.CodecName, codec.CodecType, ... as needed
}

simple linux device driver open call crash

I am trying to learn how to write a device driver in linux, following some reference from google and ldd3. i am able to insert the module below but when i tried to open the device in an application the kernel crashed.
The code and build steps followed as below :
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <linux/fs.h>
/* =============== Constant Definitions ============ */
#define SERIAL_IRQ 4
/* =============== Variable Definitions ============ */
static int SER_MAJOR = 0;
int ser_open(struct inode *inode, struct file *filp);
int ser_release(struct inode *inode, struct file *filp);
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var)
{
printk("\n\n ------- INTR raised -----------\n\n");
return 0;
}
int ser_open(struct inode *inode, struct file *filp)
{
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL))
{
printk("\n interrupt req failed\n");
}
else
{
enable_irq(SERIAL_IRQ);
printk("\n!!!! ..obtained the requested interrupt and enabled\n");
}
}
int ser_release(struct inode *inode, struct file *filp)
{
disable_irq(SERIAL_IRQ);
free_irq(SERIAL_IRQ,NULL) ;
}
static struct file_operations ser_fops = {
open: ser_open,
release: ser_release
};
void *p = NULL;
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *);
static int __init hello_start(void)
{
int ret_val=-1;
int result;
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops);
if(result < 0)
{
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR);
return result;
}
if(SER_MAJOR == 0)
{
SER_MAJOR = result;
printk("SER DEV Major Number : %d",SER_MAJOR );
}
return 0;
}
static void __exit hello_end(void)
{
// free_irq(SERIAL_IRQ,NULL);
//release_region(0x0031,1);
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile for module :
obj-m := hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The application used for accesing is as follows :
#include <stdio.h> /* test.c */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int dev;
int main(void)
{
char buff[40];
dev = open("/dev/my_ser_dev",O_RDONLY);
if(dev < 0)
{
printf( "Device Open ERROR!\n");
exit(1);
}
printf("Please push the GPIO_16 port!\n");
//read(dev,buff,40);
// scanf("%s",buff);
printf("%s\n",buff);
close(dev);
return 0;
}
insmod gave
[ 3837.312140] Loading hello module...
[ 3837.312147] Hello world
[ 3837.312218] SER DEV Major Number : 251
Then I created the special file using mknod /dev/my_ser_dev c 251 0
Executing the application caused kernel crash. I am using UBUNTU 3.2.0-23-generic-pae.
The function you are registering as your IRQ handler has the wrong prototype - it should be like
irqreturn_t irq_handler(int, void *);
Maybe you are referring to old documentation.