Reading windows logs using jna - jna

I am getting an exception while reading windows logs using jna
Following is the program, I am using to read the logs. I took this program from another post.
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.Arrays;
import com.sun.jna.*;
import com.sun.jna.platform.win32.*;
import com.sun.jna.platform.win32.WinNT.*;
import com.sun.jna.ptr.IntByReference;
public class Test {
public static void main(String[] args) throws NumberFormatException, IOException {
HANDLE h = com.sun.jna.platform.win32.Advapi32.INSTANCE.OpenEventLog(null, "Application");
IntByReference pnBytesRead = new IntByReference();
IntByReference pnMinNumberOfBytesNeeded = new IntByReference();
IntByReference pOldestRecord = new IntByReference();
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetOldestEventLogRecord(h, pOldestRecord));
int dwRecord = pOldestRecord.getValue();
System.out.println("OLD: " + dwRecord);
IntByReference pRecordCount = new IntByReference();
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.GetNumberOfEventLogRecords(h, pRecordCount));
int dwRecordCnt = pRecordCount.getValue();
System.out.println("CNT: " + dwRecordCnt);
int bufSize = 0x7ffff; //(r.size()) * 2048;
Memory buffer = new Memory(bufSize);
int rc = 0;
int cnt = 0;
while(com.sun.jna.platform.win32.Advapi32.INSTANCE.ReadEventLog(h,
WinNT.EVENTLOG_SEEK_READ /*
| WinNT.EVENTLOG_SEQUENTIAL_READ */
| WinNT.EVENTLOG_FORWARDS_READ /*
| WinNT.EVENTLOG_BACKWARDS_READ*/
,
dwRecord, buffer,
bufSize,
pnBytesRead,
pnMinNumberOfBytesNeeded)) {
rc = Kernel32.INSTANCE.GetLastError();
if (rc == W32Errors.ERROR_INSUFFICIENT_BUFFER) {
break;
}
int dwRead = pnBytesRead.getValue();
Pointer pevlr = buffer;
while (dwRead > 0)
{
cnt++;
EVENTLOGRECORD record = new EVENTLOGRECORD(pevlr);
System.out.println("------------------------------------------------------------");
System.out.println(cnt+". " + dwRecord + " Event ID: " + record.EventID.shortValue() + " SID: " + record.UserSidLength);
dwRecord++;
// WCHAR SourceName[]
// WCHAR Computername[]
{
ByteBuffer names = pevlr.getByteBuffer(record.size(),
(record.UserSidLength.intValue() != 0 ? record.UserSidOffset.intValue() : record.StringOffset.intValue()) - record.size());
names.position(0);
CharBuffer namesBuf = names.asCharBuffer();
String[] splits = namesBuf.toString().split("\0");
System.out.println("SOURCE NAME: \n" + splits[0]);
System.out.println("COMPUTER NAME: \n" + splits[1]);
}
// SID UserSid
if (record.UserSidLength.intValue() != 0){
ByteBuffer sid = pevlr.getByteBuffer(record.UserSidOffset.intValue(), record.UserSidLength.intValue());
sid.position(0);
//CharBuffer sidBuf = sid.asCharBuffer();
byte[] dst = new byte[record.UserSidLength.intValue()];
sid.get(dst);
System.out.println("SID: \n" + Arrays.toString(dst));
}
else {
System.out.println("SID: \nN/A");
}
// WCHAR Strings[]
{
ByteBuffer strings = pevlr.getByteBuffer(record.StringOffset.intValue(), record.DataOffset.intValue() - record.StringOffset.intValue());
strings.position(0);
CharBuffer stringsBuf = strings.asCharBuffer();
System.out.println("STRINGS["+record.NumStrings.intValue()+"]: \n" + stringsBuf.toString());
}
// BYTE Data[]
{
ByteBuffer data = pevlr.getByteBuffer(record.DataOffset.intValue(), record.DataLength.intValue());
data.position(0);
CharBuffer dataBuf = data.asCharBuffer();
System.out.println("DATA: \n" + dataBuf.toString());
}
// CHAR Pad[]
// DWORD Length;
dwRead -= record.Length.intValue();
pevlr = pevlr.share(record.Length.intValue());
}
}
assertTrue(rc == W32Errors.ERROR_HANDLE_EOF);
assertTrue(com.sun.jna.platform.win32.Advapi32.INSTANCE.CloseEventLog(h));
}
private static void assertTrue(boolean getOldestEventLogRecord) {
}
}
The Exception is as follows :-
Exception in thread "main" java.lang.NoSuchMethodError: com.sun.jna.IntegerType.
<init>(IJZ)V
at com.sun.jna.platform.win32.WinDef$DWORD.<init>(WinDef.java:57)
at com.sun.jna.platform.win32.WinDef$DWORD.<init>(WinDef.java:53)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at com.sun.jna.NativeMappedConverter.defaultValue(NativeMappedConverter.java:47)
at com.sun.jna.NativeMappedConverter.<init>(NativeMappedConverter.java:41)
at com.sun.jna.NativeMappedConverter.getInstance(NativeMappedConverter.java:29)
at com.sun.jna.Structure.calculateSize(Structure.java:803)
at com.sun.jna.Structure.useMemory(Structure.java:254)
at com.sun.jna.Structure.useMemory(Structure.java:238)
at com.sun.jna.Structure.<init>(Structure.java:174)
at com.sun.jna.Structure.<init>(Structure.java:167)
at com.sun.jna.Structure.<init>(Structure.java:163)
at com.sun.jna.platform.win32.WinNT$EVENTLOGRECORD.<init>(WinNT.java:1789)
at Test.main(Test.java:54)
Please help me out from the trouble. Thanks a lot in advance. I am new to this great site so, please excuse me for bad explanation

You cannot use different versions of platform.jar and jna.jar. That is what is causing your error. Both are distributed together, so I don't understand why you're using one version of one with a different version of the other.

Related

trouble with pmi handle on windows 7

I am trying to set up performance monitorint interrupt on counter overflow to collect some information. For this I created driver. I skip some part of code that are irrelevant.
driver.c
extern VOID EnableReadPmc();
extern VOID PmiHandle();
extern VOID GetIdt(IDT_INFO *idt);
extern ULONG64 GetCs();
#pragma pack(2)
typedef struct {
USHORT Limit;
ULONG64 Base;
}IDT_INFO;
#pragma pack()
typedef struct _entry {
ULONG64 Low;
ULONG64 High;
} entry;
PHYSICAL_ADDRESS lvt_perf_count_reg = {0xfee00340, 0x00000000};
PVOID map_lvt_perf_count_reg = NULL;
PHYSICAL_ADDRESS eoi_register = {0xfee000b0, 0x00000000};
PVOID map_eoi_register = NULL;
NTSTATUS IoCtlDispatch(IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp) {
ULONG32 set_lvt_perf_count_reg = 0x000000ee;
//idt
IDT_INFO idtr;
entry *idt = NULL;
entry tmp_gate;
ULONG64 func;
ULONG64 seg;
ULONG64 int_setting;
//ovf status value
ULONG64 ovf_status;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_INTERRUPT_SETTING_UP:
//disable pmc and clear ovf
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
WriteMsr(IA32_FIXED_CTR_CTRL, 0x00);
ovf_status = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status);
//setting up lvt entry
map_lvt_perf_count_reg = MmMapIoSpace(lvt_perf_count_reg, 4, MmNonCached);
*(PULONG32)map_lvt_perf_count_reg = set_lvt_perf_count_reg;
map_eoi_register = MmMapIoSpace(eoi_register, 4, MmNonCached);
//setting up idt handler
idtr.Limit = 0;
idtr.Base = 0;
GetIdt(&idtr);
idt = idtr.Base;
tmp_gate.Low = 0;
tmp_gate.High = 0;
func = 0;
seg = 0;
int_setting = 0x8e00;
//p = 1 dpl = 0 type(interrupt gate) = 1110 ist = 0
seg = GetCs();
func = (ULONG64)PmiHandle;
tmp_gate.Low = func & 0x0ffff;
tmp_gate.Low = seg << 16 | tmp_gate.Low;
tmp_gate.Low = int_setting << 32 | tmp_gate.Low;
tmp_gate.Low = ((func & 0x0ffff0000) << 32) | tmp_gate.Low;
tmp_gate.High = (func & 0xffffffff00000000) >> 32;
idt[238] = tmp_gate;
MmUnmapIoSpace(map_lvt_perf_count_reg, 4);
map_lvt_perf_count_reg = NULL;
pIrp->IoStatus.Information = 0;
break;
default:
DbgPrint("Error in switch");
break;
}
status = pIrp->IoStatus.Status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
pmihandle.asm
public PmiHandle
extern Handle : proc
.code
PmiHandle:
call Handle
add rsp, 8
iretq
end
handle.c
#define IA32_PERF_GLOBAL_CTRL 0x38f
#define IA32_PERF_GLOBAL_STATUS 0x38e
#define IA32_PERF_GLOBAL_OVF_CTRL 0x390
extern ULONG64 ovf_status_handle;
extern PVOID map_eoi_register;
VOID Handle() {
WriteMsr(IA32_PERF_GLOBAL_CTRL, 0x00);
ovf_status_handle = ReadMsr(IA32_PERF_GLOBAL_STATUS);
WriteMsr(IA32_PERF_GLOBAL_OVF_CTRL, ovf_status_handle);
DbgPrint("INTERRUPT_INTERRUPT_INTERRUPT");
if (map_eoi_register != NULL)
*(PULONG32)map_eoi_register = 0x0;
else
DbgPrint("EOI failed");
}
main.c application with which I turn on counters
#include <stdio.h>
#include "include/msr_sampling.h"
#define FILE_DEVICE_MSR 0x8000
#define IOCTL_INTERRUPT_SETTING_UP CTL_CODE(FILE_DEVICE_MSR, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_FILE_TEST CTL_CODE(FILE_DEVICE_MSR, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
int main() {
SetProcForMsrCtr(); //set affinity mask for first proc
DriverOpen();
EnableReadPmc(); //enable __readpmc instruction
DWORD numberData = -1;
DeviceIoControl(hFile, IOCTL_INTERRUPT_SETTING_UP, NULL, 0, NULL, 0, &numberData, NULL);
ULONG64 value;
value = 0x000000000000000b;
WriteMsr(IA32_FIXED_CTR_CTRL, value);
value = 0xfffffffff000; //old value ffffffffc000
printf("%llu\n", __readpmc((1 << 30)));
WriteMsr(0x309, value);
printf("%llx\n", __readpmc((1 << 30)));
printf("=================================================\n");
ReadMsr(IA32_PERF_GLOBAL_CTRL, &value);
printf("%llX\n", value);
value = 0x0000000100000000;
WriteMsr(IA32_PERF_GLOBAL_CTRL, value);
printf("counter value: %llX\n", __readpmc((1 << 30)));
DriverClose();
system("pause");
return 0;
}
When I launch application my computer froze(does not respond to mouse movement and press key).
But if I generate interrupt with using assembly instuction INT it is OK.
I checked IDT and LVT entry via WinDbg they are correct.
What could be the problem?
Some informantion:
My processor is Intel Core i5-3210M. OS windows 7 x64. I do this on laptop.

Codename One - Can't read from socket on real device

I'm developing an iOS app, using Codename One. I extended the SocketConnection class, in order to receive data from a server.
class CustomSocketConnection extends SocketConnection {
private OutputStream os;
private InputStream is;
private InputStreamReader isr;
private String rawMessage;
public CustomSocketConnection(){
os = null;
is = null;
isr = null;
rawMessage = null;
}
public synchronized String getRawMessage(){
return rawMessage;
}
#Override
public void connectionError(int errorCode, String message) {
rawMessage = null;
ToastBar.showErrorMessage("Error Connecting. ErrorCode: " + errorCode + " Message: " + message);
System.out.println(">>>CustomSocketConnection, connectionError. Error Connecting. ErrorCode: " + errorCode + " Message: " + message);
}
#Override
public void connectionEstablished(InputStream is, OutputStream os) {
System.out.println(">>>CustomSocketConnection, connectionEstablished");
char termination = '\n';
int length = 1024;
char[] buffer = new char[length];
byte[] bufferByte = new byte[length];
StringBuilder stringBuilder = new StringBuilder();
System.out.println(">>>CustomSocketConnection, connectionEstablished, prima del while");
try {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
System.out.println(">>>CustomSocketConnection, connectionEstablished, prima della read");
while(true){
System.out.println(">>>CustomSocketConnection, loop di read, inizio");
int read = isr.read();
System.out.println(">>>CustomSocketConnection, loop di read, subito dopo la read");
char c = (char) read;
if (read == -1) rawMessage = null;
System.out.println(">>>CustomSocketConnection, loop di read, letto: " + c);
while(c != termination){
stringBuilder.append(c);
read = isr.read();
c = (char) read;
if (read == -1) rawMessage = null;
}
rawMessage = stringBuilder.toString();
if(rawMessage != null) doActions(rawMessage);
//System.out.println(">>>CustomSocketConnection, connectionEstablished, ho letto: " + rawMessage + "FINE");
}
}
catch (IOException ex) {
System.out.println(">>>CustomSocketConnection, connectionEstablished, errore: " + ex.getMessage());
}
System.out.println(">>>CustomSocketConnection, connectionEstablished, dopo il while");
}
private void doActions(String msg){
//do something
}
}
In the connectionEstablished method, I read data from server, using the read method of the InputStreamReader class.
If I run the app on the simulator, it works properly and it receives data from server. When I launch the app on real devices (iPad mini, 32-bit device, iOS version 8.1.1 12B435, more details here; iPhone 7s, 64-bit device, iOS version 11.2.5 15D60), the read method doesn't receive data from server. In fact, I can see the string printed by the println before the read method, but I can't see the string printed by the println after the read method.
The issue is not server-side, because I developed an Android app and it receive data from the same server. There aren't firewall restrictions or other network limitations: Android app and the Codename One simulator both receive data when connected on the same local network of the server or from another one.
What's wrong?
Solved using InputStream instead of InputStreamReader.
#Override
public void connectionEstablished(InputStream is, OutputStream os) {
System.out.println(">>>CustomSocketConnection, connectionEstablished");
char termination = '\n';
StringBuilder stringBuilder = new StringBuilder();
System.out.println(">>>CustomSocketConnection, connectionEstablished, prima del while");
try {
System.out.println(">>>CustomSocketConnection, connectionEstablished, prima della read");
while(true){
System.out.println(">>>CustomSocketConnection, loop di read, inizio");
int read = is.read();
System.out.println(">>>CustomSocketConnection, loop di read, subito dopo la read");
char c = (char) read;
if (read == -1) rawMessage = null;
System.out.println(">>>CustomSocketConnection, loop di read, letto: " + c);
while(c != termination){
stringBuilder.append(c);
read = is.read();
c = (char) read;
if (read == -1) rawMessage = null;
}
rawMessage = stringBuilder.toString();
if(rawMessage != null) doActions(rawMessage);
//System.out.println(">>>CustomSocketConnection, connectionEstablished, ho letto: " + rawMessage + "FINE");
}
}
catch (IOException ex) {
System.out.println(">>>CustomSocketConnection, connectionEstablished, errore: " + ex.getMessage());
}
System.out.println(">>>CustomSocketConnection, connectionEstablished, dopo il while");
}
Can anyone explain me why it's working with InputStream?

Passing va_list as function argument

I've created a simple SO example demonstrating various ways to pass va_list as function arg. The problem I'm trying to solve is passing the va_list in a callback from a shared object to the main module.
/*libcode.vala shared library (libvala-0.38)*/
namespace SOTestLib {
public const string TESTSTR = "my test string";
public const string EXPECTFORMATSTR = "expect test:%s";
public const string EXPECTFORMATSTR_VA_ARG0 = "1==1";
public delegate bool delegatefnExpect (bool expression, string format, va_list valist);
public delegatefnExpect delfnExpect;
public delegate bool delegatefnString (string mystring);
public delegatefnString delfnString;
public string gTestStr;
public string gExpectResultStr;
private void show_string(string mystring) {
stdout.printf("show_string mystring[%s] gTestStr[%s]\n", mystring, gTestStr);
assert (mystring == gTestStr);
assert (delfnString != null);
delfnString(mystring);
}
private bool expect(bool expression, string sformat, ...) {
assert (delfnExpect != null);
assert (sformat == EXPECTFORMATSTR);
va_list _valist = va_list ();
gExpectResultStr = sformat.vprintf (_valist);
stdout.printf("expect[%s]\n", gExpectResultStr);
return delfnExpect(expression, sformat , _valist);
}
private void my_printf (string format, ...) {
va_list va_list = va_list ();
string res = format.vprintf (va_list);
stdout.puts (res);
}
public int run_demo() {
//REFER:https://valadoc.org/glib-2.0/string.vprintf.html
// Output: ``Shut up, K-9!``
my_printf ("Shut %s, %c-%d!\n", "up", 'K', 9);
gTestStr = TESTSTR;
show_string(TESTSTR);
expect(1 == 1, EXPECTFORMATSTR, EXPECTFORMATSTR_VA_ARG0);
return 0;
}
}
/*main.vala linked with libcode.so shared library (libvala-0.38)*/
using SOTestLib;
public bool cbfnString(string test_str) {
stdout.printf("cbfnString test_str[%s] gTestStr[%s]\n", test_str, gTestStr);
assert (test_str == gTestStr);
return true;
}
public bool cbfnExpect(bool expression, string format, va_list args) {
stdout.printf("cbfnExpect format[%s] format.length[%d]\n",
format, format.length);
assert (format == EXPECTFORMATSTR);
string res = format.vprintf(args);
assert (res != null);
stdout.printf("cbfnExpect res[%s] gExpectResultStr[%s]\n", res, gExpectResultStr);
assert(res == gExpectResultStr);
return expression;
}
static int main(string[] args) {
delfnString = (delegatefnString)cbfnString;
delfnExpect = (delegatefnExpect)cbfnExpect;
return run_demo();
}
Here is the result of running the test...
===========================================================================
---Run main --
===========================================================================
./stackoverflow/libcallback_strings/lib/libcallback_strings.exe
Shut up, K-9!
show_string mystring[my test string] gTestStr[my test string]
cbfnString test_str[my test string] gTestStr[my test string]
expect[expect test:1==1]
cbfnExpect format[expect test:%s] format.length[14]
cbfnExpect res[expect test:(null)] gExpectResultStr[expect test:1==1]
**
ERROR:/media/george/SharedData/Projects/Vala/LanguageServer/stackoverflow/libcallback_strings/main.vala:15:cbfnExpect: assertion failed: (res == gExpectResultStr)
stackoverflow/so_examples.mk:252: recipe for target 'libcallback_strings' failed
make: *** [libcallback_strings] Aborted
The terminal process terminated with exit code: 2
For some reason in cbfnExpect, va_list args is no longer valid. It seems as if va_list address (or addresses within the struct) is only valid within the shared library. Is this not the correct/allowed usage of va_list?
In private bool expect, if I comment out setting gExpectResultStr as follows:
//gExpectResultStr = sformat.vprintf (_valist);
Then, in the first line of the static int main method, I added:
gExpectResultStr = "expect test:1==1";
The test passes. Since gExpectResultStr is the same every time the program is run, I just statically set it to the correct value when the program starts. Removing the call to vprintf in expect seems to be what fixes it.
My guess is that calling sformat.vprintf on the va_list, under the hood, in the C implementation, invalidates the va_list.
When diffing the generated C code for both the passing and failing code, here is what I came up with. Staring at the code for a while, the only potential part that might mess up the va_list is the call to g_strdup_vprintf(). I guess that function frees the va_list?
$ diff -Naur libcode-pass.c libcode-fails.c
--- libcode-pass.c 2018-01-20 09:19:24.455838766 -0800
+++ libcode-fails.c 2018-01-20 09:19:59.631260461 -0800
## -66,26 +66,32 ##
SOTestLibdelegatefnExpect _tmp0_;
const gchar* _tmp1_;
va_list _valist = {0};
- FILE* _tmp2_;
- const gchar* _tmp3_;
- SOTestLibdelegatefnExpect _tmp4_;
- gboolean _tmp5_;
- const gchar* _tmp6_;
+ const gchar* _tmp2_;
+ gchar* _tmp3_;
+ FILE* _tmp4_;
+ const gchar* _tmp5_;
+ SOTestLibdelegatefnExpect _tmp6_;
gboolean _tmp7_;
+ const gchar* _tmp8_;
+ gboolean _tmp9_;
g_return_val_if_fail (sformat != NULL, FALSE);
_tmp0_ = so_test_lib_delfnExpect;
_vala_assert (_tmp0_ != NULL, "delfnExpect != null");
_tmp1_ = sformat;
_vala_assert (g_strcmp0 (_tmp1_, SO_TEST_LIB_EXPECTFORMATSTR) == 0, "sformat == EXPECTFORMATSTR");
va_start (_valist, sformat);
- _tmp2_ = stdout;
- _tmp3_ = so_test_lib_gExpectResultStr;
- fprintf (_tmp2_, "expect[%s]\n", _tmp3_);
- _tmp4_ = so_test_lib_delfnExpect;
- _tmp5_ = expression;
- _tmp6_ = sformat;
- _tmp7_ = _tmp4_ (_tmp5_, _tmp6_, _valist);
- result = _tmp7_;
+ _tmp2_ = sformat;
+ _tmp3_ = g_strdup_vprintf (_tmp2_, _valist);
+ _g_free0 (so_test_lib_gExpectResultStr);
+ so_test_lib_gExpectResultStr = _tmp3_;
+ _tmp4_ = stdout;
+ _tmp5_ = so_test_lib_gExpectResultStr;
+ fprintf (_tmp4_, "expect[%s]\n", _tmp5_);
+ _tmp6_ = so_test_lib_delfnExpect;
+ _tmp7_ = expression;
+ _tmp8_ = sformat;
+ _tmp9_ = _tmp6_ (_tmp7_, _tmp8_, _valist);
+ result = _tmp9_;
va_end (_valist);
return result;
}

Data From Arduino Yun To Google Spreadsheet

I am working on a project where I am sending a timestamp from and Arduino Yun to a Google Spreadsheet. I have a PIR Sensor connected to the Yun. When motion is detected I am sending the value to the spreadsheet. Currently the value is going into one column.
This is not ideal because I want to create a chart from the data so I want the time and date to be in two different columns. Like the sample below.
Arduino Sketch
#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h"
#include <Process.h>
int pir_pin = 8;
Process date;
int hours, minutes, seconds;
int lastSecond = -1;
const String GOOGLE_CLIENT_ID = "";
const String GOOGLE_CLIENT_SECRET = "";
const String GOOGLE_REFRESH_TOKEN = "";
const String SPREADSHEET_TITLE = "";
int numRuns = 1;
int maxRuns = 100;
void setup() {
Serial.begin(9600);
delay(4000);
pinMode(pir_pin, INPUT);
while (!Serial);
Serial.println("Time Check");
if (!date.running()) {
date.begin("date");
date.addParameter("+%T %D");
date.run();
}
Serial.print("Initializing the bridge... ");
Bridge.begin();
Serial.println("Done!\n");
}
void loop()
{
if (digitalRead(pir_pin) == true) {
if (!date.running()) {
date.begin("date");
date.addParameter("+%T %D");
date.run();
}
while (date.available() > 0) {
String timeString = date.readString();
int firstColon = timeString.indexOf(":");
int secondColon = timeString.lastIndexOf(":");
String hourString = timeString.substring(0, firstColon);
String minString = timeString.substring(firstColon + 1, secondColon);
String secString = timeString.substring(secondColon + 1);
hours = hourString.toInt();
minutes = minString.toInt();
lastSecond = seconds;
seconds = secString.toInt();
if (numRuns <= maxRuns) {
Serial.println("Running AppendRow - Run #" + String(numRuns++));
unsigned long now = millis();
Serial.println("Getting sensor value...");
Serial.println("Appending value to spreadsheet...");
TembooChoreo AppendRowChoreo;
AppendRowChoreo.begin();
AppendRowChoreo.setAccountName(TEMBOO_ACCOUNT);
AppendRowChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
AppendRowChoreo.setAppKey(TEMBOO_APP_KEY);
AppendRowChoreo.setChoreo("/Library/Google/Spreadsheets/AppendRow");
AppendRowChoreo.addInput("ClientID", GOOGLE_CLIENT_ID);
AppendRowChoreo.addInput("ClientSecret", GOOGLE_CLIENT_SECRET);
AppendRowChoreo.addInput("RefreshToken", GOOGLE_REFRESH_TOKEN);
AppendRowChoreo.addInput("SpreadsheetTitle", SPREADSHEET_TITLE);
String rowData = timeString;
AppendRowChoreo.addInput("RowData", rowData);
unsigned int returnCode = AppendRowChoreo.run();
if (returnCode == 0) {
Serial.println("Success! Appended " + rowData);
Serial.println("");
} else {
while (AppendRowChoreo.available()) {
char c = AppendRowChoreo.read();
Serial.print(c);
}
}
AppendRowChoreo.close();
}
Serial.println("Waiting...");
delay(5000);
}
}
}
How would I alter the code to achieve the above.
I work for Temboo.
You can set multiple columns in the AppendRow Choreo by separating each value in rowData with a comma. For your case, you'd want your rowData to look like this: "19:35:26,4/22/2016". You could try something like timeString.replace(" ",",");.
Hopefully this helps. If you have any other questions, feel free to contact us at https://temboo.com/support

Memory Leak in C and C++ Code

I am trying to return a pointer from a function and use the return in a different function but I am getting memory leak.
The test code which I wrote and detected with memory leak by CPPCheck.
########################################################################
# include < stdio.h >
# include < malloc.h >
# include < string.h >
char* replace ( char* st, char* word, char *replaceWith );
int main ( void )
{
char str[] = "Hello how are ## and what are ## doing ?";
char word[]="##";
char replaceWith[]="you";
printf("%s",replace(str,word,replaceWith));
getchar();
return 0;
}
char* replace(char* st,char* word,char *replaceWith)
{
int i = 0;
char *sr,*s,*ret;
int oldlen;
int count = 0;
int newlen;
int stlen;
s=(char *)malloc(strlen(st) + 1);
strcpy(s, st);
oldlen=strlen(word);
newlen=strlen(replaceWith);
for (i = 0; s[i]! = '\0'; )
{
if( memcmp( &s[i], word, oldlen ) == 0)
{
count++;
i+=oldlen;
}
else
{
i++;
}
}
sr= (char *) malloc (i+1+count*(newlen-oldlen));
ret = (char *) malloc (i+1+count*(newlen-oldlen));
ret=sr;
while(*s)
{
if(memcmp( s, word, oldlen) == 0)
{
memcpy(sr, replaceWith, newlen);
s+ = oldlen;
sr+ = newlen;
}
else
{
*sr++ = *s++;
}
}
*sr = '\0';
return ret;
}
Try this
#include<stdio.h>
#include<malloc.h>
#include<string.h>
char* replace ( char* st, char* word, char *replaceWith );
int main ( void )
{
char str[] = "Hello how are ## and what are ## doing ?";
char word[]="##";
char replaceWith[]="you";
char * ret = replace(str,word,replaceWith);
printf("%s",ret);
free(ret); //freeing the allocated memory
getchar();
return 0;
}
char* replace(char* st,char* word,char *replaceWith)
{
int i = 0;
char *sr,*s,*ret, *temps;
int oldlen;
int count = 0;
int newlen;
int stlen;
s=(char *)malloc(strlen(st) + 1);
temps = s; // storing the address of s in a temp location
strcpy(s, st);
oldlen=strlen(word);
newlen=strlen(replaceWith);
for (i = 0; s[i]!= '\0';)
{
if( memcmp( &s[i], word, oldlen ) == 0)
{
count++;
i+=oldlen;
}
else
{
i++;
}
}
sr= (char *) malloc (i+1+count*(newlen-oldlen));
ret=sr;
while(*s)
{
if(memcmp( s, word, oldlen) == 0)
{
memcpy(sr, replaceWith, newlen);
s += oldlen;
sr += newlen;
}
else
{
*sr++ = *s++;
}
}
*sr = '\0';
free(temps); // freeing the memory allocated for s
return ret;
}
Always free same count with malloc.
free s, sr at end of replace,
use return value of replace instead of direct use on printf
and free return value (return of ret from replace) when not needed.
I have doing lots of experimenting with the memory leak and meanwhile I wrote the following code. Please comment about the pros and cons side of it.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
// Prototype declaration of replaceAll function
static char* replaceAll(char *pSource, char *pWord, char*pWith);
/////////////////////////////////////////////////////////////////////////////
//
// NAME : main
//
// DESCRIPTION : Implementation of main which invokes the replaceAll
// function and displays the output
//
// PARAMETERS : void
//
// RETURNED VALUE : int
//
/////////////////////////////////////////////////////////////////////////////
int main( void )
{
char *finalString = NULL; // To save the base returned address
char srcString[] = "Hello how r you"; // Actual String
char pWord[] = "r"; // Word to be replaced
char pWith[] = "are"; // Word to be replaced with
printf("\n Before Calling the replaceAll function:");
printf("%s",srcString);
printf("\n");
finalString = replaceAll(srcString, pWord, pWith); //calling the replaceAll function
printf("\n After Calling the replaceAll function:");
// Checking if NULL is returned
if( finalString != NULL )
{
//printing the string
printf("%s", finalString);
}
else
{
printf("\n Error: Blank String returned ");
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
//
// NAME : replaceAll
//
// DESCRIPTION : Implementation of replaceAll function which replaces
// a word in given string with another word
//
// PARAMETERS : char *
//
// RETURNED VALUE : char *
//
/////////////////////////////////////////////////////////////////////////////
static char* replaceAll(char *pSource, char *pWord, char*pWith)
{
char *pSt = NULL; // Pointer to the source String to avoid modifying the pSource
char *pTarget = NULL; // Target pointer to be malloced
char *pTg = NULL; // Pointer to the target string
int count; // Counter
int nWord = strlen (pWord); // length of the word which needs to be replaced
int nWith = strlen (pWith); // length of the word with which the word needs to be replaced
static const char nullP = '\0'; // null character
int szTarget = 0;
// Assigning the base address of the pSource to a temporary and iterate through
for ( pSt = pSource, count = 0; *pSt != nullP; pSt++ )
{
// Count number of occurances of the Word in the String to calculate the length of the final string
if( memcmp( pSt, pWord, nWord ) == 0)
{
count++;
pSt += nWord-1;
}
}
// Calculate the required target Size
szTarget = strlen (pSource) + count * (nWith - nWord) + sizeof (nullP);
// Allocate memory for the target string
pTarget = (char *)malloc(szTarget);
// Check if the malloc function returns sucessfully
if ( pTarget != NULL)
{
// Copying the string with replacement
for (pTg = pTarget, pSt = pSource; *pSt != nullP; )
{
if( memcmp (pSt, pWord, nWord) == 0)
{
memcpy (pTg,pWith,nWith);
pSt += nWord;
pTg += nWith;
}
else
{
*pTg++ = *pSt++;
}
}
// Assigning NULL Character to the target string after copying
*pTg = '\0';
}
return pTarget;
}

Resources