I don't write code often and my knowledge is still low-level. I need help for something that I can't figure out
public static void SearchScriptEnd()
{
int counter = 0;
string line;
Report.Log(ReportLevel.Info, "Read Log", "Starting to find: Test Suite Ended");
var text = "Test Suite Ended";
if (File.Exists(ConfigController.Home + TestSuite.Current.Parameters["LogPath"]))
{
StreamReader file =
new StreamReader(ConfigController.Home + TestSuite.Current.Parameters["LogPath"]);
}else{
StreamReader file =
new StreamReader(TestSuite.Current.Parameters["LogPath"]);
}
while ((line = file.ReadLine()) != null)
{
if (line.Contains(text))
{
Report.Log(ReportLevel.Info, "Read Log", "[Success] Script End String has been found");
Report.Log(ReportLevel.Info, "Read Log", string.Format("Line number: '{0}'", counter));
return;
}
counter++;
}
Report.Log(ReportLevel.Failure, "Read Log", "[Missing] Anvil Script End String NOT found");
file.Close();
}
At first, the while was in both statement and was working well, but I want to use the While outside of that statement, but I'm getting The name 'file' does not exist in the current context (CS0103) and I don't know how to get the value of file out of my If statement.
You need to get the variable out of the if-scope. Try this:
StreamReader file;
if (File.Exists(ConfigController.Home + TestSuite.Current.Parameters["LogPath"]))
{
file = new StreamReader(ConfigController.Home + TestSuite.Current.Parameters["LogPath"]);
}else{
file = new StreamReader(TestSuite.Current.Parameters["LogPath"]);
}
That way you have a value in file for sure. Happy coding.
pplx::task<void> RestInterface::Getsxxxx()
{
utility::stringstream_t ss;
pplx::cancellation_token_source cts;
pplx::cancellation_token ct = cts.get_token();
ss<<"http://"<<URL<<":"<<PORT<<PATH<<ZALL;
http_client client(U(ss.str()));
///here were using the jSON function for URI to request the REST API
///else the name of the API can be passed to stream also.
http_request requestJson(methods::GET);
requestJson.headers().set_content_type(U("application/json"));
///you must perform the request
///against a server that provides JSON data.
return client.request(requestJson, ct).then([=](http_response response) -> pplx::task<web::json::value>
{
///If the status is OK extract the body of the response into a JSON value
if(!getCancelledSate())
{
if (response.status_code() == status_codes::OK)
{
return response.extract_json();
}
else
{
// return an empty JSON value
isConnected = false;
return pplx::task_from_result(web::json::value());
}
}
else
{
//try{
cts.cancel();
//}
//catch(http_exception const & e)
//{
// std::cout<<__FILE__<<"["<<__LINE__<<"]"<<"Exception:"<< e.what() << std::endl;
//}
}
}, ct).then([=](pplx::task<web::json::value> previousTask)
{
try{
std::cout <<" before previousTask.wait()"<< std::endl;
///Get the JSON value from the task and call the traversal method
if(previousTask.wait() == pplx::task_status::canceled){
//Do nothing
std::cout <<" after previousTask.wait()"<< std::endl;
}else{
web::json::value const & dataValue = previousTask.get();
m_dataJson = dataValue;
///clear string streambuffer
m_Buffer.str("");
m_Buffer.clear();
m_Buffer << m_dataJson.serialize();
utility::string_t streamJson = m_Buffer.str();
if((strxxxxcmp(streamJson, APP_ACTIVE) < 0)){
isConnected = false;
//......So work
}else{
//......So work
}
}
}
catch(http_exception const & e)
{
isConnected = false;
std::cout<<__FILE__<<"["<<__LINE__<<"]"<<"Exception:"<< e.what() << std::endl;
}
});
}
void RestInterface::xxxxz()
{
try
{
isConnected = true;
Getsxxxx().wait();
}
catch(const std::exception &e)
{
std::cout<<__FILE__<<"["<<__LINE__<<"]"<<"Exception:"<< e.what() << std::endl;
//printf("Error exception:%s\n", e.what());
}
}
Now i have a problem. we have a scenario where we have to cancel the Task when a signal is generated like for e.g. when SIGINT is generated...
when user gives SIGINT using Ctrl+C Sometimes i can see the below message.
**/build/casablanca-FHxOgj/casablanca-2.8.0/Release/include/pplx/pplxtasks.h:1835: pplx::task_status pplx::details::_Task_impl_base::_Wait(): Assertion `_IsCompleted()' failed.
Aborted**
i think that some task is throwing an exception that is not handled, but i am not entirely sure which one and about the reason. Can anybody share some thoughts on it.
any help will be great
I'm trying to make a program for parsing text protocol.
(I selected text protocol cause I heard that binary packet parsing is more difficult).
Currently, there are really few command and parameters.
each packet can be splited by delimiter(';')
[packet1];[packet2];
Let's break packet1 down.
[Action],[Param1],[Param2],...;
Action : [SET]
Params : [DELAY]
if you send "SET,DELAY,300;" to server,
server will change 'delay' parameter and send "SET,DELAY,300;" to client.
Action : [GET]
Params : [DELAY] [MODE]
if you send "GET,DELAY,MODE;" to server,
server will send "GET,DELAY,300,MODE,2;" to client.
Any way I suceed to make it.
(The code is here. because it is long, I couldn't add it here)
But even if there are only few params and actions, the code is very long and complicated.
I used 'boost::algorithm::split' to split packets.
And I only used 'if','else if','else' to invoke right task corresponding 'action' and 'parameter'.
But I will add more actions and parameters.
But at this rate, I cannot debug or modify code because the comlexity of the code will be more severe.
Is it wrong way to make protocol translation program?
If you know better way, please share with me.
Yes. The better way is to make a grammar, write a parser for it and parse into an AST (abstract syntax tree, or simply strong typed representation of the packets).
A Spirit grammar for this looks like:
I always start out with the AST types:
namespace ast {
struct nil {
friend std::ostream& operator<<(std::ostream& os, nil) { return os << "<nil>"; }
};
using value = boost::variant<nil, double, std::string>;
struct parameter {
std::string _key;
value _val;
};
enum class action {
get,
set,
};
using parameters = std::vector<parameter>;
struct packet {
action _action;
parameters _params;
};
using packets = std::vector<packet>;
}
For simplicity I've
assumed parameters (mode/delay) will have numeric or string values.
used the same packet definition for GET and SET requests (GET requests will just us nil values for the parameters listed)
Next we define a grammar using Boost Spirit Qi:
template <typename It, typename Skipper=qi::space_type>
struct grammar : qi::grammar<It, ast::packets(), Skipper> {
grammar():grammar::base_type(start) {
using qi::raw;
using qi::no_case;
param_key_.add
("delay")
("mode");
start = *(packet_ >> ';');
packet_ =
(no_case["get"] >> qi::attr(ast::action::get) >> *(',' >> get_param_))
| (no_case["set"] >> qi::attr(ast::action::set) >> *(',' >> set_param_))
;
get_param_ = raw[no_case[param_key_]] >> qi::attr(ast::nil());
set_param_ = raw[no_case[param_key_]] >> "," >> value_;
value_ = qi::double_ | string_;
string_ = '"' >> *~qi::char_('"') >> '"';
BOOST_SPIRIT_DEBUG_NODES((start)(packet_)(get_param_)(set_param_)(value_)(string_))
}
// ... field declarations
};
There's a little bit of a learning curve here, but the key point to observe is that it it's possible to create maintainable code that is also debuggable (see here for BOOST_SPIRIT_DEBUG enabled output).
Finally, because the AST is simple we can make a fake request processor that uses a request context (in this case a map to contain the current values of the parameters) to actually process the requests:
struct request_context {
std::map<std::string, ast::value> properties;
request_context()
: properties { { "MODE", 2 }, { "DELAY", 300 } } // defaults
{
}
boost::optional<ast::packet> process_request(ast::packet packet) {
switch (packet._action) {
case ast::action::get:
for(auto& param : packet._params) {
param._val = properties[param._key];
}
return packet;
case ast::action::set:
for(auto& param : packet._params) {
std::cout << "DEBUG: setting property '" << param._key << "' to value '" << param._val << "'\n";
properties[param._key] = param._val;
}
return boost::none;
default:
throw std::runtime_error("bad packet"); // TODO proper exception type
};
}
};
Imagine who much messier this was if you had it mixed with the parsing code, or everything stringly typed
Live On Coliru
//#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <map>
namespace qi = boost::spirit::qi;
namespace ast {
struct nil {
friend std::ostream& operator<<(std::ostream& os, nil) { return os << "<nil>"; }
};
using value = boost::variant<nil, double, std::string>;
struct parameter {
std::string _key;
value _val;
};
enum class action {
get,
set,
};
using parameters = std::vector<parameter>;
struct packet {
action _action;
parameters _params;
};
using packets = std::vector<packet>;
static std::ostream& operator<<(std::ostream& os, action a) {
switch(a) {
case action::get: return os << "GET";
case action::set: return os << "SET";
}
return os << "(other)";
}
}
BOOST_FUSION_ADAPT_STRUCT(ast::parameter,(std::string,_key)(ast::value,_val))
BOOST_FUSION_ADAPT_STRUCT(ast::packet,(ast::action,_action)(ast::parameters,_params))
template <typename It, typename Skipper=qi::space_type>
struct grammar : qi::grammar<It, ast::packets(), Skipper> {
grammar():grammar::base_type(start) {
using qi::raw;
using qi::no_case;
param_key_.add
("delay")
("mode");
start = *(packet_ >> ';');
packet_ =
(no_case["get"] >> qi::attr(ast::action::get) >> *(',' >> get_param_))
| (no_case["set"] >> qi::attr(ast::action::set) >> *(',' >> set_param_))
;
get_param_ = raw[no_case[param_key_]] >> qi::attr(ast::nil());
set_param_ = raw[no_case[param_key_]] >> "," >> value_;
value_ = qi::double_ | string_;
string_ = '"' >> *~qi::char_('"') >> '"';
BOOST_SPIRIT_DEBUG_NODES((start)(packet_)(get_param_)(set_param_)(value_)(string_))
}
private:
qi::symbols<char, std::string> param_key_;
qi::rule<It, ast::parameter(), Skipper> set_param_, get_param_;
qi::rule<It, ast::packets(), Skipper> start;
qi::rule<It, ast::packet(), Skipper> packet_;
qi::rule<It, ast::value(), Skipper> value_;
qi::rule<It, std::string()> string_;
};
struct request_context {
std::map<std::string, ast::value> properties;
request_context()
: properties { { "MODE", 2 }, { "DELAY", 300 } } // defaults
{
}
boost::optional<ast::packet> process_request(ast::packet packet) {
switch (packet._action) {
case ast::action::get:
for(auto& param : packet._params) {
param._val = properties[param._key];
}
return packet;
case ast::action::set:
for(auto& param : packet._params) {
std::cout << "DEBUG: setting property '" << param._key << "' to value '" << param._val << "'\n";
properties[param._key] = param._val;
}
return boost::none;
default:
throw std::runtime_error("bad packet"); // TODO proper exception type
};
}
};
int main()
{
std::string const input =
"GET,DELAY,MODE;"
"SET,DELAY,0,MODE,\"we can have string values too\";GET,MODE;SET,MODE,42;GET,MODE,DELAY;";
using It = std::string::const_iterator;
It f(input.begin()), l(input.end());
grammar<It> p;
ast::packets parsed;
bool ok = qi::phrase_parse(f,l,p,qi::space,parsed);
if (ok) {
std::cout << parsed.size() << " packets successfully parsed\n";
request_context ctx;
for(auto& packet : parsed)
{
auto response = ctx.process_request(packet);
if (response) {
std::cout << "response: " << response->_action;
for(auto& kv : packet._params) {
std::cout << "," << kv._key << "," << kv._val;
}
std::cout << ";\n";
}
}
} else {
std::cout << "Parse error\n";
}
if (f!=l)
std::cout << "Remaining unparsed input: '" << std::string(f,l) << "'\n";
}
Prints:
5 packets successfully parsed
response: GET,DELAY,300,MODE,2;
DEBUG: setting property 'DELAY' to value '0'
DEBUG: setting property 'MODE' to value 'we can have string values too'
response: GET,MODE,we can have string values too;
DEBUG: setting property 'MODE' to value '42'
response: GET,MODE,42,DELAY,0;
I need to write a Java method in order to send postscript files to a printer in one job. In other words, I need to reproduce the effect of the following Unix command:
lp -d printer file1.ps file2.ps file3.ps
First I thought I could just concatenate the PS files (using classes like ConcatInputStream and PrintJobWatcher). But the resulting merged PS file is not always valid.
If it helps, here is my current code (I have been asked to do it in Groovy):
/**
* Prints the {#code files} {#code copyCount} times using
* {#code printService}.
* <p>
* Exceptions may be thrown.
* #param printService Print service
* #param files Groovy array of {#code File} objects
* #param copyCount Number of copies to print
*/
private static void printJob(
PrintService printService,
def files,
int copyCount) {
// No multiple copy support for PS file, must do it manually
copyCount.times { i ->
InputStream inputStream = null
try {
log.debug("Create stream for copy #${i}")
inputStream = new ConcatInputStream()
for (def file in files) {
if (file != null) {
log.debug("Add '${file.absolutePath}' to the stream")
((ConcatInputStream)inputStream).addInputStream(
new FileInputStream(file))
}
}
log.debug("Create document")
Doc doc = new SimpleDoc(
inputStream, DocFlavor.INPUT_STREAM.AUTOSENSE, null)
log.debug("Create print job")
DocPrintJob docPrintJob = printService.createPrintJob()
log.debug("Create watcher")
PrintJobWatcher watcher = new PrintJobWatcher(docPrintJob)
log.debug("Print copy #${i}")
docPrintJob.print(doc, null)
log.debug("Wait for completion")
watcher.waitForDone()
} finally {
if (inputStream) log.debug("Close the stream")
inputStream?.close()
}
}
}
I’m not allowed to convert the PS into PDF.
I read here that I could insert false 0 startjob pop between the PS files. But then would there be only one job?
I may be confusing the concept of "jobs"...
I didn’t find a post on the topic (sending multiple PS files to the printer in one job). The solution may be so obvious that it blinded me, that why I posted this question.
My next attempt will be to execute lp from the class, even if it looks dirty I know I can make it work that way... If you know a simpler way, please tell me.
Edit:
Executing lp (as below) works well:
/**
* Prints the {#code files} {#code copyCount} times using an executable.
* <p>
* Exceptions may be thrown.
* #param config ConfigObject containing closures for building the
* command line to the printing executable, and to analyze the
* return code. Example of config file:
*
* print {
* commandClosure = { printerName, files ->
* [
* 'lp',
* '-d', printerName,
* files.collect{ it.absolutePath }
* ].flatten()
* }
* errorClosure = { returnCode, stdout, stderr -> returnCode != 0 }
* warnClosure = { returnCode, stdout, stderr ->
* !stderr?.isAllWhitespace() }
* }
*
* #param printerName Printer name
* #param files Groovy array of {#code File} objects
* #param copyCount Number of copies to print
*/
private static void printJob(
ConfigObject config,
String printerName,
def files,
int copyCount) {
files.removeAll([null])
Integer copyCount = job.copyCountString.toInteger()
copyCount.times { i ->
def command = config.print.commandClosure(printerName, files)
log.debug("Command: `" + command.join(' ') + "`")
def proc = command.execute()
proc.waitFor()
def returnCode = proc.exitValue()
def stdout = proc.in.text
def stderr = proc.err.text
def debugString = "`" + command.join(' ') +
"`\nReturn code: " + returnCode +
"\nSTDOUT:\n" + stdout + "\nSTDERR:\n" + stderr
if (config.print.errorClosure(returnCode, stdout, stderr)) {
log.error("Error while calling ${debugString}")
throw new PrintException("Error while calling ${debugString}")
} else if (config.print.warnClosure(returnCode, stdout, stderr)) {
log.warn("Warnings while calling ${debugString}")
} else {
log.debug("Command successful ${debugString}")
}
}
}
Even if I would prefer not to use an external executable... This issue is not anymore critical for me. I will accept an answer if it does not require the call to an external executable.
Actually, can't you just loop through the files inside your loop for the number of copies?
ie:
private static void printJob( PrintService printService, def files, int copyCount) {
// No multiple copy support for PS file, must do it manually
copyCount.times { i ->
log.debug( "Printing Copy $i" )
files.each { file ->
log.debug( "Printing $file" )
file.withInputStream { fis ->
Doc doc = new SimpleDoc( fis, DocFlavor.INPUT_STREAM.AUTOSENSE, null )
DocPrintJob docPrintJob = printService.createPrintJob()
PrintJobWatcher watcher = new PrintJobWatcher( docPrintJob )
docPrintJob.print( doc, null )
watcher.waitForDone()
}
}
}
}
(untested)
edit
As an update to your workaround above, rather than:
def proc = command.execute()
proc.waitFor()
def returnCode = proc.exitValue()
def stdout = proc.in.text
def stderr = proc.err.text
You're probably better with:
def proc = command.execute()
def out = new StringWriter()
def err = new StringWriter()
ps.consumeProcessOutput( out, err )
ps.waitFor()
def returnCode = proc.exitValue()
def stdout = out.toString()
def stderr = err.toString()
As this won't block if the process writes a lot of information :-)
One of the issues could be related to the Document Structure Convention (DSC) comments. These comments provide metadata about the document contained in the file. A tool like ghostscript should be able to process the resulting concatenated file because it ignores DSC comments entirely and just processes the postscript. But tools that expect to work on DSC-conforming files will be confused when the first file ends (it's marked by an End comment) and there's more data in the file.
One thing that might work is to strip all comments from the files, so there's no misleading DSC information. (DSC comments will always be a full line starting with %%, so an RE substitution should do it. s/^%[^$]*$//g)
I am getting a wierd problem and i am stuck on it for atleast 4 hours now. Actually i had written my code in a controller for testing but when i have moved the code to service i am getting a strange behaviour that the methods in service are not returning or may be methods that are calling them in the service only are not receiving .
class FacebookService implements InitializingBean, GroovyInterceptable {
def getUserLikes(def at){
List<String> listOfUrls = []
String basicFbUrl = "https://graph.facebook.com/"
String likeUrl = basicFbUrl + "me/likes?access_token=${at}"
URL url = new URL(likeUrl)
String jsonResponse = getResponseFromUrl(url)
println "JSON RESPONSE IS ${jsonResponse}" // this is showing null
}
String getResponseFromUrl() {
String something
String resp = null;
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
try {
int respCode = conn.responseCode
if (respCode == 400) {
log.error("COULD NOT MAKE CONNECTION")
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
def jsonResp = JSON.parse(br.text)
} else {
resp = conn.getInputStream().getText()
}
} finally {
conn.disconnect()
}
println("RETURNIG RESPONSE ${resp}") // This returns me a map as expected
return resp;
}
Dont know where does resp goes ?? any suggestions please ??
OK i know the culprit , i am posting the code of invokeMethod
def invokeMethod(String name, args){
System.out.println("IN INVOKE METHOD NAME ${name}")
if(facebookPalsCache==null)
facebookPalsCache = new FacebookPalsCache(1000)
System.out.println("time before ${name} called: ${new Date()}")
//Get the method that was originally called.
def calledMethod = metaClass.getMetaMethod(name, args)
System.out.println("CALLED METHOD IS ${calledMethod}")
//The "?" operator first checks to see that the "calledMethod" is not
//null (i.e. it exists).
if(name.equals("getFriends")){
println "getFriends..."
def session = RequestContextHolder.currentRequestAttributes().getSession()
def friends = facebookPalsCache.get(session.facebook.uid)
if(!friends){
def getFriends = facebookGraphService.invokeMethod (name, args)
println "Saving FBFRIENDS in CACHE"
facebookPalsCache.put(session.facebook.uid, getFriends)
return getFriends
}
else return friends
}
else {
if(calledMethod){
System.out.println("IN IF AND INVOKING METHOD ${calledMethod}")
calledMethod.invoke(this, args)
}
else {
return facebookGraphService.invokeMethod(name, args)
}
}
System.out.println "RETURNING FROM INVOKE METHOD FOR NAME ${name}"
System.out.println("time after ${name} called: ${new Date()}\n")
}
OK SOMETHING IS WRONG ABOVE I DONT KNOW WHAT CAN ANYONE PLEASE HELP ??
The code for invokeMethod and the service don't seem to be the same unless there's a separate FacebookGraphService. Assuming that's the case, then the resp is being caught in the part of your invokeMethod that's inside the if (calledMethod) { block, but since it's not the last line of the method it's not being returned from the call to invokeMethod and therefore is being gobbled up.
Try adding a return to calledMethod.invoke(this, args):
if(calledMethod){
System.out.println("IN IF AND INVOKING METHOD ${calledMethod}")
return calledMethod.invoke(this, args)
}