From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- mpeglib/example/yaf/yafcore/Makefile.am | 44 ++++ mpeglib/example/yaf/yafcore/PROTOCOL.v01 | 243 ++++++++++++++++++++++ mpeglib/example/yaf/yafcore/README | 27 +++ mpeglib/example/yaf/yafcore/buffer.cpp | 156 +++++++++++++++ mpeglib/example/yaf/yafcore/buffer.h | 64 ++++++ mpeglib/example/yaf/yafcore/commandLine.cpp | 86 ++++++++ mpeglib/example/yaf/yafcore/commandLine.h | 60 ++++++ mpeglib/example/yaf/yafcore/commandTable.cpp | 256 ++++++++++++++++++++++++ mpeglib/example/yaf/yafcore/commandTable.h | 82 ++++++++ mpeglib/example/yaf/yafcore/commandTableYAF.cpp | 36 ++++ mpeglib/example/yaf/yafcore/commandTableYAF.h | 36 ++++ mpeglib/example/yaf/yafcore/inputDecoder.cpp | 237 ++++++++++++++++++++++ mpeglib/example/yaf/yafcore/inputDecoder.h | 80 ++++++++ mpeglib/example/yaf/yafcore/inputInterface.cpp | 195 ++++++++++++++++++ mpeglib/example/yaf/yafcore/inputInterface.h | 102 ++++++++++ mpeglib/example/yaf/yafcore/lineStack.cpp | 95 +++++++++ mpeglib/example/yaf/yafcore/lineStack.h | 55 +++++ mpeglib/example/yaf/yafcore/multiReader.cpp | 206 +++++++++++++++++++ mpeglib/example/yaf/yafcore/multiReader.h | 88 ++++++++ mpeglib/example/yaf/yafcore/outputDecoder.cpp | 144 +++++++++++++ mpeglib/example/yaf/yafcore/outputDecoder.h | 52 +++++ mpeglib/example/yaf/yafcore/outputInterface.cpp | 85 ++++++++ mpeglib/example/yaf/yafcore/outputInterface.h | 60 ++++++ mpeglib/example/yaf/yafcore/parser.cpp | 152 ++++++++++++++ mpeglib/example/yaf/yafcore/parser.h | 55 +++++ mpeglib/example/yaf/yafcore/runtimeTableYAF.cpp | 34 ++++ mpeglib/example/yaf/yafcore/runtimeTableYAF.h | 35 ++++ mpeglib/example/yaf/yafcore/yafCommand.defs | 89 ++++++++ mpeglib/example/yaf/yafcore/yafRuntime.defs | 67 +++++++ mpeglib/example/yaf/yafcore/yaf_control.cpp | 81 ++++++++ mpeglib/example/yaf/yafcore/yaf_control.h | 26 +++ 31 files changed, 3028 insertions(+) create mode 100644 mpeglib/example/yaf/yafcore/Makefile.am create mode 100644 mpeglib/example/yaf/yafcore/PROTOCOL.v01 create mode 100644 mpeglib/example/yaf/yafcore/README create mode 100644 mpeglib/example/yaf/yafcore/buffer.cpp create mode 100644 mpeglib/example/yaf/yafcore/buffer.h create mode 100644 mpeglib/example/yaf/yafcore/commandLine.cpp create mode 100644 mpeglib/example/yaf/yafcore/commandLine.h create mode 100644 mpeglib/example/yaf/yafcore/commandTable.cpp create mode 100644 mpeglib/example/yaf/yafcore/commandTable.h create mode 100644 mpeglib/example/yaf/yafcore/commandTableYAF.cpp create mode 100644 mpeglib/example/yaf/yafcore/commandTableYAF.h create mode 100644 mpeglib/example/yaf/yafcore/inputDecoder.cpp create mode 100644 mpeglib/example/yaf/yafcore/inputDecoder.h create mode 100644 mpeglib/example/yaf/yafcore/inputInterface.cpp create mode 100644 mpeglib/example/yaf/yafcore/inputInterface.h create mode 100644 mpeglib/example/yaf/yafcore/lineStack.cpp create mode 100644 mpeglib/example/yaf/yafcore/lineStack.h create mode 100644 mpeglib/example/yaf/yafcore/multiReader.cpp create mode 100644 mpeglib/example/yaf/yafcore/multiReader.h create mode 100644 mpeglib/example/yaf/yafcore/outputDecoder.cpp create mode 100644 mpeglib/example/yaf/yafcore/outputDecoder.h create mode 100644 mpeglib/example/yaf/yafcore/outputInterface.cpp create mode 100644 mpeglib/example/yaf/yafcore/outputInterface.h create mode 100644 mpeglib/example/yaf/yafcore/parser.cpp create mode 100644 mpeglib/example/yaf/yafcore/parser.h create mode 100644 mpeglib/example/yaf/yafcore/runtimeTableYAF.cpp create mode 100644 mpeglib/example/yaf/yafcore/runtimeTableYAF.h create mode 100644 mpeglib/example/yaf/yafcore/yafCommand.defs create mode 100644 mpeglib/example/yaf/yafcore/yafRuntime.defs create mode 100644 mpeglib/example/yaf/yafcore/yaf_control.cpp create mode 100644 mpeglib/example/yaf/yafcore/yaf_control.h (limited to 'mpeglib/example/yaf/yafcore') diff --git a/mpeglib/example/yaf/yafcore/Makefile.am b/mpeglib/example/yaf/yafcore/Makefile.am new file mode 100644 index 00000000..95119cb5 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/Makefile.am @@ -0,0 +1,44 @@ +# libyafshared - Makefile.am + +INCLUDES = -I../../include $(all_includes) + +EXTRA_DIST = PROTOCOL.v01 yafCommand.defs yafRuntime.defs + + +lib_LTLIBRARIES = libyafcore.la + +noinst_HEADERS = commandTableYAF.h multiReader.h \ + runtimeTableYAF.h \ + outputDecoder.h \ + commandLine.h \ + commandTable.h lineStack.h \ + parser.h + + +libyafcore_la_SOURCES = buffer.cpp \ + lineStack.cpp \ + commandLine.cpp \ + parser.cpp \ + outputInterface.cpp \ + inputInterface.cpp \ + commandTable.cpp \ + commandTableYAF.cpp \ + runtimeTableYAF.cpp \ + inputDecoder.cpp \ + outputDecoder.cpp \ + yaf_control.cpp \ + multiReader.cpp + +libyafcore_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) \ + -no-undefined -avoid-version + +libyafcore_la_LIBADD = -lkdefakes $(THIS_LIB_LIBS) + + + + +yafcoredir = $(includedir)/$(THIS_LIB_NAME)/util/yaf/yafcore + +yafcore_HEADERS = inputInterface.h outputInterface.h \ + buffer.h inputDecoder.h yaf_control.h + diff --git a/mpeglib/example/yaf/yafcore/PROTOCOL.v01 b/mpeglib/example/yaf/yafcore/PROTOCOL.v01 new file mode 100644 index 00000000..fce6f1c5 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/PROTOCOL.v01 @@ -0,0 +1,243 @@ + +This text describes how the interactive interface for mpg123 works. +****************************************************************** + + +Interaction means, that the user can enters commands during +the mpg123 decoder is running. +For example, he can stops decoding and can jump to a special +framenumber. + +The current frontends (e.g. tk3play) already allow this, but they are +a bit difficult for a user because he must enter +numbers for special command instead of a more +readable command like "open xyz.mp3" + +Then the tk3 interface can't produce return codes for the commands +In this interface every command the user +sends to the decoder produces a return Message. +(for now this messages always defaults to "success") + +Why the return codes? +This allows a controlling GUI (which is a "user" in some way) +to get a notification if e.g. the file cannot be opened +by the decoder (wrong format, etc...) + +How does it work? +**************** +Every command the user enters on stdin (cin) produces a return code. +Thus if the user (or a GUI) sends "open xyz" he gets +a message whether this succeded or not. + + +E.g: + +The user starts mpg123 in interacive mode and enters the first command: + +>open foo.mp3 + +This command and is internally converted to the string: + +"Command:101 Msg:open foo.mp3" + +The control then writes to stdout : +"Command:101 Ret:(file not found) Msg:open foo.mp3" + + +The brackets behind "Ret:" belongs to the protocol +they are delimeters for the return string. + +Or, in the case the command was successfull, the user enters : +play + +is translated to +"Command:102 Msg:play" +return is: +"Command:102 Ret:(ok) Msg:play" + + +For what is the "Command:xyz" string good for? +********************************************** + +This string is the current Command number. If a controlling +GUI sends "Command:x Msg:open foo.mp3" it can search the outout +from mpg123 for a string : "Command:x ........" This +ist the return value of the decoder for the command "open foo.mp3" + +The command-number must be unique >= 40. +All Command < 40 are runtime Commands. +Runtime Commands always have the format : + +Command: Msg: <...> + +Example for runtime Commands: +++++++++++++++++++++++++++++ + +In the output stream of mpg123 there may be different message. +For example mpg123 produces runtime information (time, currentframe or +something like this). + +"Command:0 Msg:info1 p I 2.0 III 22050 Joint-Stereo 2 64 209" +"Command:0 Msg:info1 p I 2.0 III 22050 Joint-Stereo 2 64 209" +"Command:0 Msg:info1 p I 2.0 III 22050 Joint-Stereo 2 64 209" + +The Command number zero means that this output does not belong +to any special input command.(The part after Msg: is decoder specific) + +There are more pre-definied Command Numbers: +Nr Description Example + +0 : Runtime info in general Command:0 Msg:live long and prosper->SIGSEV +1 : Debug info Command:1 Msg:search the bug + +Note: +The debug Command is the only command which has *no* identifer +after Msg: All other Commands < 40 needs a Message-identifer after +Msg. +In the example for Command 0 the Message identifer is "life" +and the "real" Message is "long and prosper->SIGSEV". +This mechanism allows to extend the runtime info sytem only +with identifiers and not with numbers +Why? +Because the protocol should be easy to read. +(One of the ideas behind this protocol) +Eg: + +Command:0 Msg:currentFrame 23 +is more "readable" than an extension with numbers +eg: +Command:0 Msg:2 23 + +In this example "2" mean that the 23 is the currentFrame Number. + + + + +Runtime Commands may be processed by the frontend: ++++++++++++++++++++++++++++++++++++++++++++++++++ + +Maybe there are errors during playing: + +"Command:0 Msg:exception p internal error- ignoring RIFF Header" + +The frontend checks the kind of runtime command: + +Frontend knows that there was an error(exception) but the status says (p) +that the decoder continues playing (p) +and for a more precise description (for the user) +"error- ignoring RIFF Header" + + +Back to the question: +++++++++++++++++++++ +The frontend cannot be sure that the next message by the decoder +is the return message of the previous sended command "open foo.mp3" +This is the reason for the command number. They synchonise the +input (open foo.mp3) with the output. +With a command number the GUI can filter the output for the return code. + + + +Restriction of the proctocol: +**************************** +You cannot send binary data because a "\n" is interpreted as +something like "end of input" +This means that you cannot open a file in the mpg decoder +which has "\n" in its name. +Hm. Is this a restriction? Yes. +An alternative would be to extend the Protocol to something +like : + +Size: Command:... Msg.... + +(Maybe in the future) + + + +How is this implemented? +************************* + + +In the source there are two classes: + +* InputInterface +* OutputInterface + + +First Example +************* + +Let's say we want to write a Command-Line-Frontend for mpg123, +which is included in the mpg123 source. +(see the file: mpg123_control.c) + +What we must do? +The Input for the decoder is the command by the user and +the output is the output by the decoder. + +The user should not have to write the real syntax of the +protocol. Thus he should not write: + +Command:1 Msg:open file.mp3 + +But simply : open file.mp3 + +The Inputinterface must translate the wrong input +(in the view of the protocol) into the right +protocolSyntax. +(here: Command: Msg:open file.mp3) + +This input is then passed to the decoder. +The decoder translates the part after "Msg:" and +trys to open file.mp3, but in this example he cannot find it. +Now he can send the return value with the valid Command number. +Command: Ret:(file not found) Msg:open file.mp3 + +When the decoder returns from the "translations" +we send the return-Msg (stored in the decoder) +to the outputstream. +For this we set in the Outputinterface the current Command number +And then we send the return message and again the command +which produced the return message. + +"Command: Ret:(file not found) Msg:eopn foo.mp3" + +Second Example +************** + +Write a Gui frontend which starts mpg123 as a seperate process +(how kmpg does). +kmpg starts a new mpg123 with the compiled in yaf-interface. +the yaf-interface is a commandline interface, but this is +not what we want. We need another behaviour. +mpg123 must expect protocol data and not "user written" inputs. +Thus kmpg must set the mpg123 frontend in another internal state +which expects protocol data. +The first command which kmpg sends to the mpg123 frontend +is : "protocol" +This sets the InputInterface of mpg123 in a protocol-raw-modus. +A user can type this on the command line as well, but +then he must also generate the right protocol syntax. + +Then kmpg opens a file and send +e.g: +Command:1 Msg:open abc.mp3 + +Then the mpg123 output is sent back: + +Command:1 Ret:(ok) Msg:open abc.mp3 + + +DEBUGGING +********* + +In the file InputInterface and OutputInterface are debug switches. +If they are set the incoming/outgoing +stream is copied to the files +instream.dbg +outstream.dbg + +tail -f instream.dbg outstream.dbg + +monitors the interaction between a frontend and the decoder. + diff --git a/mpeglib/example/yaf/yafcore/README b/mpeglib/example/yaf/yafcore/README new file mode 100644 index 00000000..c3cfd130 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/README @@ -0,0 +1,27 @@ + +yaf - et nother rontend + +yaf is a simple protocol for communication over streams. + +Its purpose is to offer an extensible interface +for the communitcation between the kmpg GUI and the mpg123 decoder. + + +DESCRIPTION + +The basic idea is, that the GUI and the decoder (splay) work +together over their file streams (cin,cout) +This means, that kmpg sends string-messages to "stdout" +and splay receive these messages as "stdin". +The results of splay (runtime Information, error +codes) are send to "stdout" and kmpg receive them as "stdin" + +The protocol is "human readable" just enter "help" +or "help " on the prompt and you will see. +These directory includes classes for dealing with this +text protocol. In normal developement you can completly +ingore these classe. + +For more info look in the file PROTOCOL + + diff --git a/mpeglib/example/yaf/yafcore/buffer.cpp b/mpeglib/example/yaf/yafcore/buffer.cpp new file mode 100644 index 00000000..3c58f0ee --- /dev/null +++ b/mpeglib/example/yaf/yafcore/buffer.cpp @@ -0,0 +1,156 @@ +/* + This class implements a dynamic string buffer + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "buffer.h" + + + +Buffer::Buffer(int size) { + nSize=size; + msg=(char*) malloc(sizeof(char)*(nSize+1)); + msg[nSize]='\0'; + clear(); + +} + + +Buffer::~Buffer() { + free (msg); +} + + +void Buffer::clear() { + msg[0]='\0'; +} + +void Buffer::append(int value) { + Buffer buf(30); + sprintf(buf.getData(),"%d",value); + append(buf.getData()); +} + + + + +void Buffer::append(char* appendMsg) { + char* appendPos=getAppendPos(); + int nlen=strlen(appendMsg); + if (appendPos == NULL) return; + + append(appendMsg,nlen); +} + + +void Buffer::append(const char* appendMsg) { + append((char*)appendMsg); +} + + +void Buffer::append(char* buffer,int buflen) { + int nlen=len(); + int nBedarf; + + if (buflen+nlen <= nSize) { + char* appendPos=getAppendPos(); + strncpy(appendPos,buffer,buflen); + appendPos[buflen]='\0'; + return; + } + nBedarf=(nlen+buflen)-nSize; + grow(nBedarf); + append(buffer,buflen); +} + +char* Buffer::getAppendPos() { + int i; + // this Array has nSize+1 entries! + // and it *is* granted that msg[nSize]=0; (think so) + for (i=0;i<=nSize;i++) { + if (msg[i] == '\0') return &(msg[i]); + } + // should never reach this point + return NULL; +} + + +void Buffer::setData(char* msg) { + if (strlen(msg) == 0) { + clear(); + return; + } + clear(); + append(msg); +} + +char* Buffer::getData() { + return msg; +} + + +int Buffer::len() { + return strlen(msg); +} + +int Buffer::getSize() { + return nSize; +} + +void Buffer::grow(int size) { + int i; + int newSize=nSize+size; + char* tmp=(char*) malloc(sizeof(char)*(newSize+1)); + tmp[newSize]='\0'; + for(i=0;i<=nSize;i++) { + tmp[i]=msg[i]; + } + + nSize=newSize; + free(msg); + msg=tmp; + +} + + +int Buffer::find(char zeichen) { + int i; + int nlen=len(); + for(i=0;i nlen) { + bytes=nlen; + } + i=0; + aktPos=bytes; + while(aktPos <= nlen) { + msg[i]=msg[aktPos]; + i++; + aktPos++; + } +} + + + +void Buffer::print() { + printf("Buffer:%s\n",msg); +} diff --git a/mpeglib/example/yaf/yafcore/buffer.h b/mpeglib/example/yaf/yafcore/buffer.h new file mode 100644 index 00000000..7c1a3d5c --- /dev/null +++ b/mpeglib/example/yaf/yafcore/buffer.h @@ -0,0 +1,64 @@ +/* + This class implements a static string buffer + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __BUFFER_H +#define __BUFFER_H + + +extern "C" { +#include +#include +#include + } +#include + +class KDE_EXPORT Buffer { + + char* msg; + int nSize; + + public: + Buffer(int size); + ~Buffer(); + + void clear(); + void append(int value); // appends values as string + void append(char* msg); + void append(const char* msg); + + void append(char* buffer,int buflen); + + int find(char zeichen); + int len(); + + void setData(char* msg); + char* getData(); + + int getSize(); + void grow(int size); + + void forward(int bytes); + void print(); + private: + char* getAppendPos(); + void read(FILE stream); + +}; + + +#endif + + + diff --git a/mpeglib/example/yaf/yafcore/commandLine.cpp b/mpeglib/example/yaf/yafcore/commandLine.cpp new file mode 100644 index 00000000..e3ae8252 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/commandLine.cpp @@ -0,0 +1,86 @@ +/* + An abstraction of a Command-Line + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "commandLine.h" +#include +using namespace std; + +CommandLine::CommandLine(){ + int i; + for (i=0; i < 10; i++) { + command[i].identifier=new Buffer(20); + command[i].value=new Buffer(100); + } + commandCount=0; + +} + +CommandLine::~CommandLine(){ + + int i; + for (i=0; i < 10; i++) { + delete command[i].value; + delete command[i].identifier; + + } + +} + + +int CommandLine::getCommandCount() { + return commandCount; +} + +void CommandLine::setCommandCount(int commandCount){ + this->commandCount=commandCount; +} + + +char* CommandLine::getIdentifier(int i){ + return (command[i].identifier)->getData(); +} + +void CommandLine::clear() { + int i; + for (i=0; i < 10; i++) { + command[i].identifier->clear(); + command[i].value->clear(); + } + commandCount=0; +} + +char* CommandLine::getValue(int i) { + return (command[i].value)->getData(); +} + +void CommandLine::setIdentifier(int i,char* identifier){ + (command[i].identifier)->setData(identifier); +} + + +void CommandLine::setValue(int i,char* value) { + (command[i].value)->setData(value); +} + +void CommandLine::printCommand() { + int i; + for(i=0;igetData() << "\n"; + cout << "value:" << (command[i].value)->getData() << "\n"; + } +} + + + diff --git a/mpeglib/example/yaf/yafcore/commandLine.h b/mpeglib/example/yaf/yafcore/commandLine.h new file mode 100644 index 00000000..677c1018 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/commandLine.h @@ -0,0 +1,60 @@ +/* + An abstraction of a Command-Line + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + + +#ifndef __BASICMESSAGE_H +#define __BASICMESSAGE_H + + +#include "buffer.h" + + +struct BasicMessageStruct { + + Buffer* identifier; + Buffer* value; + +}; + +typedef struct BasicMessageStruct tBasicMessage; + + +class CommandLine { + + + int commandCount; + tBasicMessage command[40]; + + public: + + CommandLine(); + ~CommandLine(); + + int getCommandCount(); + void setCommandCount(int commandCount); + + char* getIdentifier(int i); + char* getValue(int i); + + void setIdentifier(int i,char* identifier); + void setValue(int i,char* value); + + void printCommand(); + void clear(); +}; + +#endif + + diff --git a/mpeglib/example/yaf/yafcore/commandTable.cpp b/mpeglib/example/yaf/yafcore/commandTable.cpp new file mode 100644 index 00000000..10e36dc3 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/commandTable.cpp @@ -0,0 +1,256 @@ +/* + valid Commands for Input/Output + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "commandTable.h" +#include + +using namespace std; + + +CommandTable::CommandTable(){ + nCommandDesc=0; +} + +CommandTable::~CommandTable(){ +} + + +const char* CommandTable::getCommand(int nr) { + int i; + const char* back=""; + for(i=0;i nlen) && (name[nlen]==' ')) { + return commandDesc[i].longName; + } + } + + if (strlen(commandDesc[i].shortName) > 0) { + nlen=strlen(commandDesc[i].shortName); + comp=strncmp(commandDesc[i].shortName,name,nlen); + + if (comp == 0) { + if (strlen(name) == nlen) { + return commandDesc[i].shortName; + } else if ((strlen(name) > nlen) && (name[nlen]==' ')) { + return commandDesc[i].shortName; + } + } + } + } + return back; +} + + +int CommandTable::getNr(const char* command) { + int i; + int comp; + int back=-1; + unsigned int nlen; + for(i=0;i nlen) && (command[nlen]==' ')) { + return commandDesc[i].number; + } + } + + if (strlen(commandDesc[i].shortName) > 0) { + nlen=strlen(commandDesc[i].shortName); + comp=strncmp(commandDesc[i].shortName,command,nlen); + + if (comp == 0) { + if (strlen(command) == nlen) { + return commandDesc[i].number; + } else if((strlen(command) > nlen) && (command[nlen]==' ')){ + return commandDesc[i].number; + } + } + } + } + return back; +} + + +const char* CommandTable::getArgs(const char* command,const char* wholeLine) { + unsigned int i; + unsigned int n; + const char* back; + back=wholeLine; + n=strlen(command); + if (n==0) return back; + for(i=0;i n) { + back++; + } + return back; +} + + + +void CommandTable::print() { + int i; + cout << "internal Help System V. 0.2\n"; + cout << "known commands are :\n\n"; + for(i=0;igetCommandCounter(); + CommandDescription* cmdDesc; + + for (i=0;igetCommandDescription(i); + insert(cmdDesc); + + } + +} + + + + + + + +void CommandTable::insert(CommandDescription* cmdDesc) { + const char* lNameTest; + const char* sNameTest; + int pos=getPos(cmdDesc->number); + + if (pos != -1) { + cout << "number "<< cmdDesc->number + << " for command "<< cmdDesc->longName << " already defined!" << endl; + } + + lNameTest=getCommand(cmdDesc->longName); + if (strlen(lNameTest) > 0) { + cout << "longName "<< cmdDesc->longName << " already defined." + << "Previous definition has number : " + << getNr(cmdDesc->longName) << endl; + } + + sNameTest=getCommand(cmdDesc->shortName); + if (strlen(sNameTest) > 0) { + cout << "shortName "<< cmdDesc->shortName << " already defined." + << "Previous definition has number : " + << getNr(cmdDesc->shortName) << endl; + + } + + + commandDesc[nCommandDesc].lexternalUse=cmdDesc->lexternalUse; + commandDesc[nCommandDesc].lReturn=cmdDesc->lReturn; + commandDesc[nCommandDesc].longName=cmdDesc->longName; + commandDesc[nCommandDesc].shortName=cmdDesc->shortName; + commandDesc[nCommandDesc].number=cmdDesc->number; + commandDesc[nCommandDesc].help=cmdDesc->help; + nCommandDesc++; +} + + +int CommandTable::getReturnFlag(int cmdNr) { + int i=getPos(cmdNr); + CommandDescription* cmdDesc; + if (i == -1) { + return -1; + } + cmdDesc=getCommandDescription(i); + return cmdDesc->lReturn; +} + + + + + + + + + + diff --git a/mpeglib/example/yaf/yafcore/commandTable.h b/mpeglib/example/yaf/yafcore/commandTable.h new file mode 100644 index 00000000..75dd4325 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/commandTable.h @@ -0,0 +1,82 @@ +/* + valid Commands for Input/Output + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __COMMANDTABLE_H +#define __COMMANDTABLE_H + + +extern"C" { +#include +#include +} + +#include + +#define _CT_START 40 + + + + + + +struct CommandDescriptionStruct { + + int lexternalUse; // written when user enters "help" + + // this field can be used to deliver a delayed return msg + int lReturn; // true generate ret-msg automatically + + const char* longName; + const char* shortName; + int number; + const char* help; +}; + + +typedef struct CommandDescriptionStruct CommandDescription; + + +class KDE_EXPORT CommandTable { + + int nCommandDesc; + CommandDescription commandDesc[50]; + + public: + CommandTable(); + virtual ~CommandTable(); + void insert(CommandDescription* cmdDesc); + + + int getNr(const char* name); + const char* getCommand(const char* name); + const char* getCommand(int nr); + const char* getArgs(const char* command,const char* wholeLine); + + int getReturnFlag(int cmdNr); + void print(); + void print (int i,int lWithHelp); + + int getCommandCounter(); + void join(CommandTable* table); // join two tables (no deep join!) + + private: + CommandDescription* getCommandDescription(int i); + int getPos(int commandNr); +}; + + +#endif + + + diff --git a/mpeglib/example/yaf/yafcore/commandTableYAF.cpp b/mpeglib/example/yaf/yafcore/commandTableYAF.cpp new file mode 100644 index 00000000..d071817b --- /dev/null +++ b/mpeglib/example/yaf/yafcore/commandTableYAF.cpp @@ -0,0 +1,36 @@ +/* + valid Commands for yaf (basic yaf commands) + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#define _USE_YAF_STRUC + +#include "commandTableYAF.h" + + +CommandTableYAF::CommandTableYAF(){ + init(); +} + +CommandTableYAF::~CommandTableYAF(){ +} + +void CommandTableYAF::init() { + + + int i; + for (i=0;i + +using namespace std; + +InputDecoder::InputDecoder() { + commandTable=new CommandTable(); + yafCommands=new CommandTableYAF(); + appendCommandTable(yafCommands); + status=_DECODER_STATUS_IDLE; + lRuntimeInfo=true; + returnBuffer= new Buffer(200); + returnLine= new Buffer(200); + + commandCounter=-1; + commandCounter=-1; + commandId=-1; + commandCounterString=NULL; + +} + + +InputDecoder::~InputDecoder(){ + delete yafCommands; + delete returnBuffer; + delete returnLine; + delete commandTable; +} + + + +void InputDecoder::setRuntimeInfo(int lRuntimeInfo) { + this->lRuntimeInfo=lRuntimeInfo; +} + + +int InputDecoder::getRuntimeInfo() { + return lRuntimeInfo; +} + + +void InputDecoder::appendCommandTable(CommandTable* table){ + commandTable->join(table); +} + + + + +void InputDecoder::processCommandLine(CommandLine* commandLine){ + CommandTable* ct=commandTable; // "ct" is shorter + commandId=-1; + + // The number of the command (unique for every command) + commandCounterString=commandLine->getValue(0); + commandCounter=atoi(commandCounterString); + + // the command (longName or shortName ) + if (commandLine->getCommandCount() == 0) { + clearReturnBuffer(); + appendReturnBuffer("no Msg"); + } + commandMsg=ct->getCommand(commandLine->getValue(1)); + if ((commandMsg == NULL) || (strlen(commandMsg) == 0)) { + clearReturnBuffer(); + appendReturnBuffer("unknown Command"); + commandMsg=commandLine->getValue(1); + + return ; + } + + // the int value of the command (faster for compare) + commandId=ct->getNr(commandMsg); + + // the Arguments of the command + commandArgs=ct->getArgs(commandMsg,(const char*) commandLine->getValue(1)); + + retString=processCommand(commandId,commandArgs); + + if ((retString == NULL) || (strlen(retString) == 0)) { + retString=(char*)"ok"; + } + clearReturnBuffer(); + appendReturnBuffer(retString); +} + + +const char* InputDecoder::processCommand(int command,const char* args){ + + if (command == _YAF_I_HELP) { + if (strlen(args)==0) { + commandTable->print(); + } else { + commandTable->print(commandTable->getNr(args),true); + } + return ""; + } + if (command == _YAF_I_RUNTIME) { + if (strcmp("off",args)==0) { + setRuntimeInfo(false); + return ""; + } + setRuntimeInfo(true); + return ""; + } + if (command == _YAF_I_QUIT) { + ::exit(0); + return ""; + } + if (command == _YAF_I_WHATIS) { + cout << "Yaf et nother rontend" << endl; + cout << endl; + cout << "Yaf is an interactive command line oriented shell for decoders." \ + << endl; + cout << endl; + cout << "Copyright (C) 1998,1999 Martin Vogt "\ + <clear(); +} + + +void InputDecoder::appendReturnBuffer(const char* str) { + returnBuffer->append(str); +} + + + +const char* InputDecoder::getReturnCode() { + // now we send back the return code + + if ((commandId != -1) && (commandTable->getReturnFlag(commandId)==false)) { + return ""; + } + + returnLine->clear(); + returnLine->append("Command:"); + + + // The number of the command (unique for every command) + // 0: the command nr + returnLine->append(commandCounterString); + returnLine->append(" Ret:("); + returnLine->append(returnBuffer->getData()); + returnLine->append(") Msg:"); + + + // now get the part after Msg: (in the inputLine) + + returnLine->append(commandMsg); + returnLine->append(" "); + returnLine->append(commandArgs); + + + + return (const char*)returnLine->getData(); + +} + + + diff --git a/mpeglib/example/yaf/yafcore/inputDecoder.h b/mpeglib/example/yaf/yafcore/inputDecoder.h new file mode 100644 index 00000000..0a5623a0 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/inputDecoder.h @@ -0,0 +1,80 @@ +/* + process Messages on the decoder + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __INPUTDECODER_H +#define __INPUTDECODER_H +#include + +#include "outputInterface.h" +#include +#include + +#define _DECODER_STATUS_IDLE 1 +#define _DECODER_STATUS_WORKING 2 +#define _DECODER_STATUS_EXIT 3 + +class CommandTable; +class CommandTableYAF; +class CommandLine; + +class KDE_EXPORT InputDecoder { + + int status; + CommandTable* commandTable; + CommandTableYAF* yafCommands; + Buffer* returnBuffer; + Buffer* returnLine; + int lRuntimeInfo; + + + + + public: + InputDecoder(); + virtual ~InputDecoder(); + + void processCommandLine(CommandLine*); + virtual const char* processCommand(int command,const char* args); + virtual void doSomething(); + + virtual void setDecoderStatus(int status); + int getDecoderStatus(); + + const char* getReturnCode(); + + void appendCommandTable(CommandTable* table); + + void setRuntimeInfo(int lRuntimeInfo); + int getRuntimeInfo(); + + + private: + + void clearReturnBuffer(); + void appendReturnBuffer(const char* msg); + + + int commandCounter; + int commandId; + const char* commandMsg; + const char* commandArgs; + const char* retString; + char* commandCounterString; + + +}; + +#endif + diff --git a/mpeglib/example/yaf/yafcore/inputInterface.cpp b/mpeglib/example/yaf/yafcore/inputInterface.cpp new file mode 100644 index 00000000..455ddd40 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/inputInterface.cpp @@ -0,0 +1,195 @@ +/* + This class can wait for an input by the user + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#include + +#include "inputInterface.h" +#include "multiReader.h" +#include + +using namespace std; + +InputInterface::InputInterface(){ + + currentLine= new Buffer(300); + rawLine=new Buffer(300); + loopback=new Buffer(300); + protocolSyntax=false; + currentCommandNumber=42; + multiReader=new MultiReader(); + yafInput=new ifstream("yaf.script"); + if (yafInput->fail() == false) { + cout << "Command:0 Msg:comment found yaf.script. Parsing first"<close(); + +} + +InputInterface::~InputInterface(){ + delete yafInput; + delete multiReader; + delete currentLine; + delete rawLine; + delete loopback; +} + + +int InputInterface::addFileDescriptor(int fd) { + int back; + back=multiReader->add(fd); + return back; +} + + +void InputInterface::removeFileDescriptor(int fd) { + multiReader->remove(fd); +} + + +int InputInterface::getCurrentCommandNumber() { + int back=0; + back=currentCommandNumber; + return back; +} + +void InputInterface::increaseCurrentCommandNumber(){ + currentCommandNumber++; +} + +int InputInterface::write(int fd,const char* txt) { + int back=0; + + int len; + loopback->clear(); + if (protocolSyntax == true) { + snprintf(loopback->getData(),300, + "Command:41 Msg:%s",txt); + } else { + strlcpy(loopback->getData(),txt, loopback->getSize()); + } + len =loopback->len(); + back=::write(fd,loopback->getData(),len); + + return back; +} + + + +void InputInterface::waitForLine() { + + while(multiReader->hasLine() == false) { + multiReader->waitForLine(); + } + multiReader->getLine(rawLine); + makeValidLine(rawLine->getData()); + +} + +void InputInterface::setProtocolSyntax (int proto) { + protocolSyntax=proto; +} + + + +void InputInterface::makeValidLine(char* line) { + + int len; + len=strlen(line); + if (len >= 1) { + if (line[len-1] == '\n') { + line[len-1]='\0'; + } + } + if (strncmp("noprotocol",line,10) == 0){ + setProtocolSyntax(false); + clearLine(); + increaseCurrentCommandNumber(); + snprintf(currentLine->getData(),300, + "Command:%d Msg:%s",currentCommandNumber,line); + return; + } + if (strncmp("protocol",line,8) == 0 ){ + setProtocolSyntax(true); + clearLine(); + increaseCurrentCommandNumber(); + snprintf(currentLine->getData(),300, + "Command:%d Msg:%s",currentCommandNumber,line); + return; + } + + // Now the part if we do _not_ bypass the protocol-state + + if (protocolSyntax == false) { + clearLine(); + increaseCurrentCommandNumber(); + snprintf(currentLine->getData(),300, + "Command:%d Msg:%s",currentCommandNumber,line); + } else { + increaseCurrentCommandNumber(); + strlcpy(currentLine->getData(),line, currentLine->getSize()); + } + + return; +} + + +void InputInterface::addInputLine(struct Buffer* buffer) { + multiReader->add(buffer); +} + + +void InputInterface::insertYafScript(ifstream* stream) { + char bst; + int nBytes=0; + Buffer yafScriptBuffer(300); + + if (stream->fail()) return; + while (stream->eof()==false) { + stream->get(bst); + if (stream->eof()) break; + + yafScriptBuffer.append(&bst,1); + } + nBytes=(yafScriptBuffer.len()-1); // EOF is a character we dont want + + addInputLine(&yafScriptBuffer); +} + + + +int InputInterface::hasLine() { + if (currentLine->len() == 0) return 0; + return 1; +} + +void InputInterface::clearLine() { + currentLine->clear(); +} + + +char* InputInterface::getLine() { + char* back=NULL; + + back=currentLine->getData(); +#ifdef _DEBUG_INPUT + ofstream infile("instream.dbg",ios::app); + infile << back < +#include + +extern "C" { +#include +#include +#include +#include +#include +#include +} + +// uncomment this for debugging the input stream +// (written to file instream.dbg) +//#define _DEBUG_INPUT + +#define _TIMEOUT_MS 2000 + +class MultiReader; + +class KDE_EXPORT InputInterface { + + int currentCommandNumber; + + int protocolSyntax; + Buffer* currentLine; + Buffer* rawLine; + MultiReader* multiReader; + Buffer* loopback; + Buffer* yafScript; + std::ifstream* yafInput; + + + public: + + InputInterface(); + ~InputInterface(); + + int addFileDescriptor(int fd); + void removeFileDescriptor(int fd); + int write(int fd,const char* txt); + + /** + waits until a complete Line is entered + */ + void waitForLine(); + + /** + returns true if a complete new InputLine is avaiable + */ + + int hasLine(); + + int getCurrentCommandNumber(); + + void increaseCurrentCommandNumber(); + + /** + clears the input Line + */ + void clearLine(); + + + /** + returns the new Line + */ + char* getLine(); + + + void setProtocolSyntax(int proto); + void addInputLine(struct Buffer* buffer); + + private: + void makeValidLine(char* line); + void insertYafScript(std::ifstream* stream); + + +}; + +#endif + + + diff --git a/mpeglib/example/yaf/yafcore/lineStack.cpp b/mpeglib/example/yaf/yafcore/lineStack.cpp new file mode 100644 index 00000000..871665ed --- /dev/null +++ b/mpeglib/example/yaf/yafcore/lineStack.cpp @@ -0,0 +1,95 @@ +/* + a class which scans a string and converts it into commandLines + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "lineStack.h" +#include + +using namespace std; + + +LineStack::LineStack() { + stack=new Buffer(1); +} + + +LineStack::~LineStack() { + delete stack; +} + + +int LineStack::hasLine() { + int nPos; + nPos=stack->find('\n'); + if (nPos == -1) return false; + return true; + +} + + + +void LineStack::nextLine(Buffer* nextLine) { + int nPos; + char* retPos; + int restLen; + char* data=stack->getData(); + int nSize=stack->getSize(); + + nPos=stack->find('\n'); + if (nPos == -1) { + nextLine->clear(); + return; + } + retPos=&(data[nPos]); + (*retPos)='\0'; + nextLine->clear(); + nextLine->setData(data); + retPos++; + restLen=nSize+1-(nPos+1); + if (strlen(retPos) > 0) { + strncpy(data,retPos,restLen); + } else{ + stack->clear(); + } +} + + +void LineStack::appendBottom(char* buffer) { + int n=strlen(buffer); + appendBottom(buffer,n); +} + + + +void LineStack::appendBottom(char* buffer, int buflen) { + + stack->append(buffer,buflen); + +} + +void LineStack::appendBottom(LineStack* lStack) { + char* data; + int len; + data=lStack->stack->getData(); + len=lStack->stack->len(); + appendBottom(data,len); +} + + + +void LineStack::print(char* name) { + cout << "LineStack:"<print(); +} + + diff --git a/mpeglib/example/yaf/yafcore/lineStack.h b/mpeglib/example/yaf/yafcore/lineStack.h new file mode 100644 index 00000000..aea1f686 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/lineStack.h @@ -0,0 +1,55 @@ +/* + a class which scans a string and converts it into commandLines + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + + +#ifndef __LINESTACK_H +#define __LINESTACK_H + + +#include "buffer.h" + +/* + This class is a hack because I have problems with + the io-streams. Why these stupid things cannot buffer + a whole line? + They behave strange, I hate them. +*/ + + + +class LineStack { + + public: + LineStack(); + ~LineStack(); + + void appendBottom(char* buffer); + void appendBottom(char* buffer,int buflen); + void appendBottom(LineStack* stack); + + int hasLine(); + void nextLine(Buffer* nextLine); + + void print(char* name); + private: + char* getReturnPos(); + + Buffer* stack; +}; + + +#endif + + diff --git a/mpeglib/example/yaf/yafcore/multiReader.cpp b/mpeglib/example/yaf/yafcore/multiReader.cpp new file mode 100644 index 00000000..41a62263 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/multiReader.cpp @@ -0,0 +1,206 @@ +/* + This class can waits for input on different istreams + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "multiReader.h" + + + +MultiReader::MultiReader() { + int i; + + buffer=new Buffer(201); + for(i=0;i<_MAX_INPUT;i++) { + lineInputArray[i]=new LineInput; + lineInputArray[i]->tmpLineStack=new LineStack(); + lineInputArray[i]->empty=true; + } + script=new LineStack(); +} + + + +MultiReader::~MultiReader() { + int i; + for(i=0;i<_MAX_INPUT;i++) { + delete lineInputArray[i]->tmpLineStack; + delete lineInputArray[i]; + } + delete script; +} + + + +int MultiReader::add(int fd) { + int nPos; + nPos=getEmptySlot(); + + if (nPos == -1) { + return -1; + } + lineInputArray[nPos]->fd=fd; + lineInputArray[nPos]->empty=false; + return nPos; +} + +void MultiReader::add(LineStack* aScript) { + script->appendBottom(aScript); +} + + +void MultiReader::add(Buffer* aScript) { + script->appendBottom(aScript->getData(),aScript->len()); +} + + + + +void MultiReader::remove (int fd) { + int nPos; + nPos=getSlot(fd); + + if (nPos == -1) { + return ; + } + lineInputArray[nPos]->empty=true; +} + + + +void MultiReader::waitForLine() { + while(hasLine() == false) { + doSelect(NULL); + } +} + + +void MultiReader::poll(struct timeval* timeout) { + doSelect(timeout); +} + + + +void MultiReader::doSelect(struct timeval* timeout) { + int i; + int ret; + fd_set readfds; + int nBytes; + int maxFd=0; + + FD_ZERO(&readfds); + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == false) { + FD_SET(lineInputArray[i]->fd,&readfds); + if (lineInputArray[i]->fd > maxFd) { + maxFd=lineInputArray[i]->fd; + } + } + } + ret=select(maxFd+1,&readfds,NULL,NULL,timeout); + if (ret < 0) { + if (errno < 0) { + perror("nach select multireader:"); + exit(0); + } + } + if (ret == 0) return; + + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == false) { + if (FD_ISSET(lineInputArray[i]->fd,&readfds)) { + nBytes=read(lineInputArray[i]->fd,buffer->getData(),200); + if (nBytes == 0) { + perror("MultiReader:read error!"); + exit(-1); + } + (buffer->getData())[nBytes]='\0'; + + lineInputArray[i]->tmpLineStack->appendBottom(buffer->getData(), + nBytes); + FD_CLR(lineInputArray[i]->fd,&readfds); + } + } + } +} + + + +int MultiReader::hasLine() { + int i; + LineStack* lineStack; // owned by class + + if (script->hasLine() == true) { + return true; + } + + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == false) { + lineStack=lineInputArray[i]->tmpLineStack; + if (lineStack->hasLine()) { + return true; + } + } + } + return false; +} + + +void MultiReader::getLine(Buffer* buffer) { + int i; + LineStack* lineStack; // owned by class + buffer->clear(); + + if (script->hasLine()==true) { + script->nextLine(buffer); + } else { + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == false) { + lineStack=lineInputArray[i]->tmpLineStack; + + if (lineStack->hasLine()) { + lineStack->nextLine(buffer); + return; + } + } + } + } + buffer->append("\n"); +} + + + + +int MultiReader::getEmptySlot() { + int i; + + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == true) { + return i; + } + } + return -1; +} + + +int MultiReader::getSlot(int fd) { + int i; + + for(i=0;i<_MAX_INPUT;i++) { + if (lineInputArray[i]->empty == false) { + if (lineInputArray[i]->fd == fd) { + return i; + } + } + } + return -1; +} diff --git a/mpeglib/example/yaf/yafcore/multiReader.h b/mpeglib/example/yaf/yafcore/multiReader.h new file mode 100644 index 00000000..79f7dd8b --- /dev/null +++ b/mpeglib/example/yaf/yafcore/multiReader.h @@ -0,0 +1,88 @@ +/* + This class can waits for input on different istreams + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __MULTIREADER_H +#define __MULTIREADER_H + +#include "lineStack.h" +#include "buffer.h" + +extern "C" { +#include +#include +#include +#include +#include +#include + } + +/** + The purpose of this class is to have a thread safe input method + for yaf command. +

+ Sometime the decoder thread must send data to the control thread. + E.g. the Stream has ended. The decoder thread must inform the + control thread that the player should go into the "off" state. + A direct call is not thread safe and this is why the decoder + thread must use this class. For the control thread it looks + like the user has typed "off". + +*/ + +#define _MAX_INPUT 5 + +typedef struct { + LineStack* tmpLineStack; // owned by class + int fd; // filedescriptor for input + int empty; +} LineInput; + + +class MultiReader { + + Buffer* buffer; + LineInput* lineInputArray[_MAX_INPUT]; + LineStack* script; + + public: + MultiReader(); + ~MultiReader(); + + int add(int fd); + void add(LineStack* aScript); + void add(Buffer* aScript); + void remove (int fd); + + void waitForLine(); + void poll(struct timeval* timeout); + + int hasLine(); + void getLine(Buffer* buffer); + + private: + + void doSelect(struct timeval *timeout); + + int getEmptySlot(); + int getSlot(int fd); + + +}; + + + + + +#endif diff --git a/mpeglib/example/yaf/yafcore/outputDecoder.cpp b/mpeglib/example/yaf/yafcore/outputDecoder.cpp new file mode 100644 index 00000000..0993add0 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/outputDecoder.cpp @@ -0,0 +1,144 @@ +/* + Default output decoder + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#include "outputDecoder.h" +#include + +using namespace std; + +#define DEBUG cout << "Command:1 Msg:" + + +OutputDecoder::OutputDecoder() { + yafCommands=new CommandTableYAF(); + yafRuntime=new RuntimeTableYAF(); + + appendCommandTable(yafCommands); + appendRuntimeTable(yafRuntime); + +} + + + +OutputDecoder::~OutputDecoder() { + delete yafCommands; + delete yafRuntime; +} + + + +void OutputDecoder::appendCommandTable(CommandTable* table) { + commandTable.join(table); +} + + +void OutputDecoder::appendRuntimeTable(CommandTable* table) { + runtimeTable.join(table); +} + + + +CommandTable* OutputDecoder::getCommandTable() { + return &commandTable; +} + + +CommandTable* OutputDecoder::getRuntimeTable() { + return &runtimeTable; +} + + + + +void OutputDecoder::processCommandLine(CommandLine* commandLine){ + CommandTable* ct=&commandTable; // ct , rt are shorter.. + CommandTable* rt=&runtimeTable; + + + int command; + int commandNr; + const char* commandStr; + const char* retString; + const char* args; + + + // The number of the command (unique for every command) + commandNr=atoi(commandLine->getValue(0)); + + // if commandNr is greater zero then we have a return command from decoder + if (commandNr >= 40) { + + // the command (longName or shortName ) + commandStr=ct->getCommand(commandLine->getValue(2)); + // the int value of the command (faster for compare) + command=ct->getNr(commandStr); + + // the Arguments of the command + args=ct->getArgs(commandStr,commandLine->getValue(2)); + retString=commandLine->getValue(1); + + processReturnCommand(commandNr,command,retString,args); + return; + } + + // if commandNr < 40 then we have a runtime command from decoder + + if (commandNr < 40) { + // the command (longName or shortName ) + commandStr=rt->getCommand(commandLine->getValue(1)); + // the int value of the command (faster for compare) + command=rt->getNr(commandStr); + + // here I make a hack because it cannot be expected + // that during debugging every debug-info has its clean + // installed debug-identifer. + // hack: + // if the commandNr==1 (debug) and we have NO defined + // debug identifier then we do not send -1 (as in all other case) + // but the number 1 itsself. + + if ((commandNr == 1) && (command == -1)) { + args=rt->getArgs(commandStr,commandLine->getValue(1)); + processRuntimeCommand(1,args); + return; + } + + // in *all* other cases the developer should + // implement a clean protokoll with identifiers + // (this leads to well defined interfaces :-) + + // the Arguments of the command + args=rt->getArgs(commandStr,commandLine->getValue(1)); + + processRuntimeCommand(command,args); + return; + } + + +} + + + +int OutputDecoder::processRuntimeCommand(int command,const char* args){ + cout << command <<" * "<< args <<" * "<< endl; + return false; +} + +int OutputDecoder::processReturnCommand(int cmdNr,int cmdId, + const char* ret,const char* args){ + cout << cmdNr <<" * "<< cmdId<<" * "<< ret<<" * " << args << endl; + return false; +} + + + + diff --git a/mpeglib/example/yaf/yafcore/outputDecoder.h b/mpeglib/example/yaf/yafcore/outputDecoder.h new file mode 100644 index 00000000..1448258b --- /dev/null +++ b/mpeglib/example/yaf/yafcore/outputDecoder.h @@ -0,0 +1,52 @@ +/* + Default output decoder + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __OUTPUTDECODER_H +#define __OUTPUTDECODER_H + +#include "commandLine.h" + +#include "runtimeTableYAF.h" +#include "commandTableYAF.h" + + +class OutputDecoder { + + public: + OutputDecoder(); + virtual ~OutputDecoder(); + + void processCommandLine(CommandLine*); + virtual int processRuntimeCommand(int command,const char* args); + virtual int processReturnCommand(int cmdNr,int cmdId, + const char* ret,const char* args); + + void appendCommandTable(CommandTable* table); + void appendRuntimeTable(CommandTable* table); + + CommandTable* getRuntimeTable(); + CommandTable* getCommandTable(); + + private: + CommandTable* yafCommands; + CommandTable* yafRuntime; + + CommandTable commandTable; + CommandTable runtimeTable; + + +}; + + +#endif diff --git a/mpeglib/example/yaf/yafcore/outputInterface.cpp b/mpeglib/example/yaf/yafcore/outputInterface.cpp new file mode 100644 index 00000000..b57563fd --- /dev/null +++ b/mpeglib/example/yaf/yafcore/outputInterface.cpp @@ -0,0 +1,85 @@ +/* + This class sends an output to the outputstream + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "outputInterface.h" +#include + +using namespace std; + +OutputInterface::OutputInterface(ostream* out) { + protocolSyntax=false; + this->out=out; + outBuffer=new Buffer(250); + setlinebuf(stdout); + pthread_mutex_init(&writeOutMut,NULL); +} + + +OutputInterface::~OutputInterface() { + delete outBuffer; +} + +void OutputInterface::flushBuffer() { + if (protocolSyntax) { + (*out) << outBuffer->getData() << endl; +#ifdef _DEBUG_OUTPUT + ofstream outfile("outstream.dbg",ios::app); + outfile << outBuffer->getData() << endl; + outfile.flush(); + outfile.close(); +#endif + return; + } else { + (*out) << "Command:" << nr << " Msg:" << outBuffer->getData() << endl; +#ifdef _DEBUG_OUTPUT + ofstream outfile("outstream.dbg",ios::app); + outfile << "Command:" << nr << " Msg:" << outBuffer->getData() << endl; + outfile.flush(); + outfile.close(); +#endif + } + fflush(NULL); +} + + + +void OutputInterface::setProtocolSyntax(int proto) { + protocolSyntax=proto; +} + + +void OutputInterface::setNr(int nr) { + this->nr=nr; +} + +void OutputInterface::clearBuffer() { + outBuffer->clear(); +} + + +void OutputInterface::appendBuffer(const char* msg) { + outBuffer->append(msg); +} + + + +void OutputInterface::lock() { + pthread_mutex_lock(&writeOutMut); +} + + +void OutputInterface::unlock() { + pthread_mutex_unlock(&writeOutMut); +} + diff --git a/mpeglib/example/yaf/yafcore/outputInterface.h b/mpeglib/example/yaf/yafcore/outputInterface.h new file mode 100644 index 00000000..0a24fd92 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/outputInterface.h @@ -0,0 +1,60 @@ +/* + This class sends an output to the outputstream + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + + + +#ifndef __OUTPUTINTERFACE_H +#define __OUTPUTINTERFACE_H + +#include +#include +#include "buffer.h" +#include + +// uncomment this for debugging the output stream +// (written to file outstream.dbg) +//#define _DEBUG_OUTPUT + + +class KDE_EXPORT OutputInterface { + + int protocolSyntax; + int nr; + Buffer* outBuffer; + std::ostream* out; + pthread_mutex_t writeOutMut; + + + public: + + OutputInterface(std::ostream* out); + ~OutputInterface(); + + + void flushBuffer(); + void setProtocolSyntax(int proto); + void setNr(int nr); + void clearBuffer(); + void appendBuffer(const char* msg); + + // make this interface threadsafe + void lock(); + void unlock(); + +}; + + + +#endif diff --git a/mpeglib/example/yaf/yafcore/parser.cpp b/mpeglib/example/yaf/yafcore/parser.cpp new file mode 100644 index 00000000..21b27c6b --- /dev/null +++ b/mpeglib/example/yaf/yafcore/parser.cpp @@ -0,0 +1,152 @@ +/* + Checks if a valid Command Line is avaiable + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "parser.h" + + +Parser::Parser() { + commandLine=new CommandLine(); + parseString=new Buffer(200); +} + + +Parser::~Parser() { + delete commandLine; + delete parseString; +} + +void Parser::setParseString(char* parseString){ + (this->parseString)->setData(parseString); + // clear everything in commandline + commandLine->clear(); +} + +void Parser::parse() { + int commandCounter=0; + + parse(parseString->getData(),&commandCounter); + commandLine->setCommandCount(commandCounter); +} + + +void Parser::parse(char* strStart,int* nCommand){ + char* doppelPkt; + char* current; + char* space; + + if (strlen(strStart) == 0) return; + + doppelPkt=strchr(strStart,':'); + if (doppelPkt == NULL) return; + (*doppelPkt)='\0'; + commandLine->setIdentifier(*nCommand,strStart); + strStart=++doppelPkt; + current=strStart; + + // Now two possibilities: + // a command with Msg : means the rest ist the value + // a command different from Msg means: further processing + + if (strcmp("Msg",commandLine->getIdentifier(*nCommand)) == 0) { + commandLine->setValue((*nCommand),current); + (*nCommand)++; + return; + } + + // Now two possibilities: + // a command with "Ret:" means string until the the ")" is the value + // a command different from "Ret:" means: the string until the first space + // ist the value + if (strcmp("Ret",commandLine->getIdentifier(*nCommand)) == 0) { + char* seperator; + seperator=strchr(current,')'); + if (seperator == NULL) { + commandLine->setValue((*nCommand),current); + (*nCommand)++; + return; + } else { + (*seperator)='\0'; + current++; + commandLine->setValue((*nCommand),current); + (*nCommand)++; + seperator++; + if (strlen(seperator) == 0) return; + parse(++seperator,&(*nCommand)); + return; + } + } + + space=strchr(current,' '); + if (space == NULL) { + commandLine->setValue((*nCommand),current); + (*nCommand)++; + return; + } + (*space)='\0'; + commandLine->setValue((*nCommand),current); + parse(++space,&(++(*nCommand))); +} + + + + +int Parser::isOK(){ + // a Commandline ist valid when it contains : + + // * 2 * (identifer/value) + // * first identifier ist "Command" + // * second identifier is "Msg" + + + // or: + // 3 identifier + // first: "Command" + // second "Ret" + // third: "Msg" + + if (commandLine->getCommandCount() == 2){ + if (strcmp("Command",commandLine->getIdentifier(0)) != 0) return 0; + if (strcmp("Msg",commandLine->getIdentifier(1)) != 0) return 0; + return 1; + } + + if (commandLine->getCommandCount() == 3){ + if (strcmp("Command",commandLine->getIdentifier(0)) != 0) return 0; + if (strcmp("Ret",commandLine->getIdentifier(1)) != 0) return 0; + if (strcmp("Msg",commandLine->getIdentifier(2)) != 0) return 0; + return 1; + } + + return 0; +} + +CommandLine* Parser::getCommandLine(){ + return commandLine; +} + + + + + + + + + + + + + + + + + diff --git a/mpeglib/example/yaf/yafcore/parser.h b/mpeglib/example/yaf/yafcore/parser.h new file mode 100644 index 00000000..d9c46211 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/parser.h @@ -0,0 +1,55 @@ +/* + Checks if a valid Command Line is avaiable + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + + +#ifndef __PARSER_H +#define __PARSER_H + +#include "buffer.h" +#include "commandLine.h" + +extern "C" { +#include + } + +class Parser { + + + Buffer* parseString; + CommandLine* commandLine; + + public: + + Parser(); + ~Parser(); + + void setParseString(char* parseString); + void parse(); + int isOK(); + CommandLine* getCommandLine(); + + + private: + void parse(char* currentPos,int* nCommand); + +}; + + +#endif + + + + + diff --git a/mpeglib/example/yaf/yafcore/runtimeTableYAF.cpp b/mpeglib/example/yaf/yafcore/runtimeTableYAF.cpp new file mode 100644 index 00000000..987c10ae --- /dev/null +++ b/mpeglib/example/yaf/yafcore/runtimeTableYAF.cpp @@ -0,0 +1,34 @@ +/* + basic runtime command (fits for every decoder) + Copyright (C) 1998 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#define _USE_RUNTIME_YAF_STRUC + +#include "runtimeTableYAF.h" + + +RuntimeTableYAF::RuntimeTableYAF(){ + init(); +} + +RuntimeTableYAF::~RuntimeTableYAF(){ +} + +void RuntimeTableYAF::init() { + + int i; + for (i=0;i + +using namespace std; + + +void yaf_control(InputInterface* input, + OutputInterface* output, + InputDecoder* decoder) { + + Parser parser; + CommandLine* commandLine; + struct timeval timeout; + const char* retCode; + int status; + + timeout.tv_sec=0; + timeout.tv_usec=0; + + output->setProtocolSyntax(true); // we send "raw" protocol data + input->addFileDescriptor(0); + + while(1) { + + status=decoder->getDecoderStatus(); + + if (status == _DECODER_STATUS_EXIT) { + break; + } + input->waitForLine(); + + if (input->hasLine()) { + parser.setParseString(input->getLine()); + parser.parse(); + + if (parser.isOK()){ + + + commandLine=parser.getCommandLine(); + + decoder->processCommandLine(commandLine); + retCode=decoder->getReturnCode(); + + // now get the part after Msg: (in the inputLine) + + output->lock(); + output->clearBuffer(); + output->appendBuffer(retCode); + output->flushBuffer(); + output->unlock(); + } else { + cout << "Error parsing input:"<getLine()<clearLine(); + } else { + cout << "no line"<removeFileDescriptor(0); + +} + + + + diff --git a/mpeglib/example/yaf/yafcore/yaf_control.h b/mpeglib/example/yaf/yafcore/yaf_control.h new file mode 100644 index 00000000..890a1bb8 --- /dev/null +++ b/mpeglib/example/yaf/yafcore/yaf_control.h @@ -0,0 +1,26 @@ + + +#ifndef __YAF_CONTROL_H +#define __YAF_CONTROL_H + + + +#include "inputInterface.h" +#include "outputInterface.h" +#include "inputDecoder.h" + +#include +#include +#include +#include +#include + + +// prototypes + +//extern "C" void control_xplayer(); +KDE_EXPORT void yaf_control(InputInterface* input, + OutputInterface* output, + InputDecoder* decoder); + +#endif -- cgit v1.2.1