Error tcNull Golang HanadB - sql
It happens that I have a database connection called Hana (Hana DB) with the programming language Go (Golang). Using the Iris framework.
What happens is that Go has problems with null data. You have to use special data types in the struct as (using the sql library that comes by default when installing Go) sql.NullString
The question is, I have a GetEmployeeData () function called when connecting to a certain URL and returning a JSON. The problem is that it does not return anything, a CONNECTION error REJECTED appears and in the console it prints an error:
hdb.protocol 2018/07/13 16:31:06 option.go:120: type code tcNull not implemented exit status 1
The code was already tested in another SQL call in another function and it works, but this SQL I suppose that when returning 1 only Null or more it gives error.
The code is the following:
func GetEmployeeData(ctx iris.Context) {
const (
driverName = "hdb"
hdbDsn = "hdb://SYSTEM:manager#62.28.253.218:30015"
)
//db, err := sql.Open(driverName, hdbDsn)
//Crea una abstraccion de conexion a base de datos pero no conecta
//Si no que prepara todo para la conexion
db, err := sql.Open(driverName, hdbDsn)
if err != nil {
log.Fatal(err)
}
//Declaramos variable de QUERY
//var peticion = GetCompanyData()
//fmt.Println(peticion)
// var companyData = GetCompanyData()
var request = `Select
"U_idcodigo",
"U_idapenom",
"U_idnumint",
"U_ctestado",
"U_idemail",
"U_cttipfun",
"U_uocodcar",
TO_CHAR("U_uocarasi",'dd/mm/yyyy'),
"U_uocodfun",
TO_CHAR("U_uofunasi",'dd/mm/yyyy'),
"U_idestciv",
"U_idsexo",
"U_idnacion",
"U_codcat",
"U_codesp",
TO_CHAR("U_idfecnac",'dd/mm/yyyy'),
"U_idfotogr",
"U_dodirecc","
U_docodpai",
"U_doregion",
"U_doprovin",
"U_docomuna",
"U_docodpos",
"U_donummov",
"U_cttipcon",
TO_CHAR("U_ctfecing",'dd/mm/yyyy'),
"U_uolugpag",
"U_uolugtra",
"U_uocodger",
"U_uocoddep",
"U_uocodsec",
"U_rpforpag",
"U_rpcodban",
"U_rpctacte",
"U_rptipocta",
"U_rpunisal",
"U_rpmoneda",
TO_VARCHAR("U_rpsalar"),
"U_tijor",
TO_VARCHAR("U_hdia"),
TO_VARCHAR("U_cthorcon"),
"U_sindi",
"U_jubil",
"U_turno",
TO_CHAR("U_turnoasi",'dd/mm/yyyy'),
"U_comentar"
FROM SBODemoCL."#A1A_MAFU"
Where "U_idcodigo" = '7579684-6'`
rows, err := db.Query(request)
if err != nil {
log.Fatal(err)
fmt.Println("No funciono la peticion")
}
defer rows.Close()
defer db.Close()
fmt.Println("Funciono la peticion")
type Employee struct {
CodigoEmpleado sql.NullString `json:"CodigoEmpleado"` //CODIGO UNICO DE EMPLEADO
Nombres sql.NullString `json:"Nombres"` //APELLIDO Y NOMBRE
NroInterno sql.NullString `json:"NroInterno"` //NUMERO INTERNO EN EMPRESA
Estado sql.NullString `json:"Estado"`
Email sql.NullString `json:"Email"` //CORREO ELECTRONICO
TipoF sql.NullString `json:"TipoF"` //TIPO DE FUNCIONARIO
Cargo sql.NullString `json:"Cargo"` //EL CARGO QUE OCUPA EL EMPLEADO
FechaCargo sql.NullString `json:"FechaCargo"` //FECHA DE ASIGNACION DE CARGO
Funcion sql.NullString `json:"Funcion"` //QUE FUNCION CUMPLE
FechaFuncion sql.NullString `json:"FechaFuncion"` //CUANDO SE LE ASIGNO SU FUNCION
Civil sql.NullString `json:"Civil"` //ESTADO CIVIL
Sexo sql.NullString `json:"Sexo"` //SI ES MASCULINO O FEMENINO
Nacionalidad sql.NullString `json:"Nacionalidad"` //SU NACIONALIDAD
Categoría sql.NullString `json:"Categoría"` //SU CATEGORIA
Especialidad sql.NullString `json:"Especialidad"` //SU ESPECIALIDAD
Nacimiento sql.NullString `json:"Nacimiento"` //FECHA DE NACIMIENTO
Fotografia sql.NullString `json:"Fotografia"` //RUTA DE MAPA DE BITS DE IMAGEN SOBRE EL EMPLEADO
Direccion sql.NullString `json:"Direccion"` //DIRECCION DE CASA DEL EMPLEADO
Pais sql.NullString `json:"Pais"` //PAIS EN DONDE SE ENCUENTRA ACTUALMENTE
Region sql.NullString `json:"Region"` //REGION DONDE SE ENCUENTRA ACTUALMENTE
Provincia sql.NullString `json:"Provincia"` //PROVINCIA DONDE SE ENCUENTRA ACTUALMENTE
Comuna sql.NullString `json:"Comuna"` //COMUNA DONDE SE ENCUENTRA ACTUALMENTE
C_Postal sql.NullString `json:"C_Postal"` //SU CODIGO POSTAL
Celular sql.NullString `json:"Celular"` //NUMERO DE CELULAR
TipoContrato sql.NullString `json:"TipoContrato"` //TIPO DE CONTRATO
FechaIngreso sql.NullString `json:"FechaIngreso"` //FECHA DE INGRESO A LA COMPAÑIA
LugarPago sql.NullString `json:"LugarPago"` //LUGAR DONDE NORMALMENTE COBRA EL EMPLEADO
LugarTrabajo sql.NullString `json:"LugarTrabajo"` //LUGAR DONDE NORMALMENTE TRABAJA EL EMPLEADO
Gerencia sql.NullString `json:"Gerencia"` //¿Quien es su genente? No es claro
Departamento sql.NullString `json:"Departamento"` //¿Si tiene departamento? ¿O la ubicacion de su departamento? ¿O con departamento se refieren a su partido o barrio?
Seccion sql.NullString `json:"Seccion"` //¿? Tampoco me queda claro
FormaPago sql.NullString `json:"FormaPago"` //COMO SE LE PAGA NORMALMENTE AL EMPLEADO
Banco sql.NullString `json:"Banco"` //EL BANCO QUE SE UTILIZA PARA DEPOSITAR EL SALARIO DEL EMPLEADO
CuentaBanco sql.NullString `json:"CuentaBanco"` //CUENTA BANCARIO DONDE SE DEPOSITA EL SALARIO
UnidadSalarial sql.NullString `json:"UnidadSalarial"` //¿? Su unidad salarial
Moneda sql.NullString `json:"Moneda"` //CON QUE TIPO DE MONEDA SE DEPOSITA SU SUELDO (EUROS, DOLARES, PESOS, ETC...)
Sueldo sql.NullString `json:"Sueldo"` //SUELDO BASICO DEL EMPLEADO
TipoJornada sql.NullString `json:"TipoJornada"` //TIPO DE JORNADA DEL EMPLEADO (CANTIDAD DE HORAS QUE TRABAJA)
HorasDia sql.NullString `json:"HorasDia"` //HORAS DIARIAS QUE ESTIPULA EL CONTRATO
HorasMes sql.NullString `json:"HorasMes"` //HORAS MENSUALES QUE ESTIPULA EL CONTRATO
Sindicato sql.NullString `json:"Sindicato"` //SINDICATO AL QUE PERTENECE EL EMPLEADO
Jubilido sql.NullString `json:"Jubilido"` //¿? Puede ser si es que esta jubilado o no
Turno sql.NullString `json:"Turno"` //¿Turno de que?
FechaTurno sql.NullString `json:"FechaTurno"` //FECHA EN QUE SE LE ASIGNO EL TURNO
Comentarios sql.NullString `json:"Comentarios"` //Comentarios sobre el empleado
}
// numero := 0
//
// ac := accounting.Accounting{
// Symbol: "", //El símbolo
// Precision: 2, // ¿Cuántos "centavos" queremos? (también llamado precisión)
// Thousand: companyData["ISeparator"], //Separador de miles
// Decimal: companyData["FSeparator"], //Separador de decimales
// }
employ := new(Employee)
for rows.Next() {
err := rows.Scan(
&employ.CodigoEmpleado,
&employ.Nombres,
&employ.NroInterno,
&employ.Estado,
&employ.Email,
&employ.TipoF,
&employ.Cargo,
&employ.FechaCargo,
&employ.Funcion,
&employ.FechaFuncion,
&employ.Civil,
&employ.Sexo,
&employ.Nacionalidad,
&employ.Categoría,
&employ.Especialidad,
&employ.Nacimiento,
&employ.Fotografia,
&employ.Direccion,
&employ.Pais,
&employ.Region,
&employ.Provincia,
&employ.Comuna,
&employ.C_Postal,
&employ.Celular,
&employ.TipoContrato,
&employ.FechaIngreso,
&employ.LugarPago,
&employ.LugarTrabajo,
&employ.Gerencia,
&employ.Departamento,
&employ.Seccion,
&employ.FormaPago,
&employ.Banco,
&employ.CuentaBanco,
&employ.UnidadSalarial,
&employ.Moneda,
&employ.Sueldo,
&employ.TipoJornada,
&employ.HorasDia,
&employ.HorasMes,
&employ.Sindicato,
&employ.Jubilido,
&employ.Turno,
&employ.FechaTurno,
&employ.Comentarios,
)
if err != nil {
log.Fatal(err)
}
// f, err := strconv.ParseFloat(valor6, 64)
// salario := ac.FormatMoney(f)
}
err = rows.Err()
if err != nil {
log.Fatal(err)
fmt.Println("Ocurrio un error")
}
ctx.JSON(employ)
}
The libraries that are imported are the following:
import (
"database/sql"
"fmt"
"log"
"strconv"
"github.com/kataras/iris"
"github.com/leekchan/accounting"
// Register hdb driver.
_ "github.com/SAP/go-hdb/driver"
)
The error calls an option.go file. All the code of option go is the following:
/*
Copyright 2014 SAP SE
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package protocol
import (
"fmt"
"github.com/SAP/go-hdb/internal/bufio"
)
type booleanType bool
func (t booleanType) String() string {
return fmt.Sprintf("%t", t)
}
type intType int32
func (t intType) String() string {
return fmt.Sprintf("%d", t)
}
type bigintType int64
func (t bigintType) String() string {
return fmt.Sprintf("%d", t)
}
type doubleType float64
func (t doubleType) String() string {
return fmt.Sprintf("%g", t)
}
type stringType []byte
type binaryStringType []byte
func (t binaryStringType) String() string {
return fmt.Sprintf("%v", []byte(t))
}
//multi line options (number of lines in part header argumentCount)
type multiLineOptions []plainOptions
func (o multiLineOptions) size() int {
size := 0
for _, m := range o {
size += m.size()
}
return size
}
//pointer: append multiLineOptions itself
func (o *multiLineOptions) read(rd *bufio.Reader, lineCnt int) {
for i := 0; i < lineCnt; i++ {
m := plainOptions{}
cnt := rd.ReadInt16()
m.read(rd, int(cnt))
*o = append(*o, m)
}
}
func (o multiLineOptions) write(wr *bufio.Writer) {
for _, m := range o {
wr.WriteInt16(int16(len(m)))
m.write(wr)
}
}
type plainOptions map[int8]interface{}
func (o plainOptions) size() int {
size := 2 * len(o) //option + type
for _, v := range o {
switch v := v.(type) {
default:
outLogger.Fatalf("type %T not implemented", v)
case booleanType:
size++
case intType:
size += 4
case bigintType:
size += 8
case doubleType:
size += 8
case stringType:
size += (2 + len(v)) //length int16 + string length
case binaryStringType:
size += (2 + len(v)) //length int16 + string length
}
}
return size
}
func (o plainOptions) read(rd *bufio.Reader, cnt int) {
for i := 0; i < cnt; i++ {
k := rd.ReadInt8()
tc := rd.ReadB()
switch TypeCode(tc) {
default:
outLogger.Fatalf("type code %s not implemented", TypeCode(tc))
case tcBoolean:
o[k] = booleanType(rd.ReadBool())
case tcInteger:
o[k] = intType(rd.ReadInt32())
case tcBigint:
o[k] = bigintType(rd.ReadInt64())
case tcDouble:
o[k] = doubleType(rd.ReadFloat64())
case tcString:
size := rd.ReadInt16()
v := make([]byte, size)
rd.ReadFull(v)
o[k] = stringType(v)
case tcBstring:
size := rd.ReadInt16()
v := make([]byte, size)
rd.ReadFull(v)
o[k] = binaryStringType(v)
}
}
}
func (o plainOptions) write(wr *bufio.Writer) {
for k, v := range o {
wr.WriteInt8(k)
switch v := v.(type) {
default:
outLogger.Fatalf("type %T not implemented", v)
case booleanType:
wr.WriteInt8(int8(tcBoolean))
wr.WriteBool(bool(v))
case intType:
wr.WriteInt8(int8(tcInteger))
wr.WriteInt32(int32(v))
case bigintType:
wr.WriteInt8(int8(tcBigint))
wr.WriteInt64(int64(v))
case doubleType:
wr.WriteInt8(int8(tcDouble))
wr.WriteFloat64(float64(v))
case stringType:
wr.WriteInt8(int8(tcString))
wr.WriteInt16(int16(len(v)))
wr.Write(v)
case binaryStringType:
wr.WriteInt8(int8(tcBstring))
wr.WriteInt16(int16(len(v)))
wr.Write(v)
}
}
}
If someone wants to download the library in their Go folder this is the command:
go get github.com/SAP/go-hdb/driver
This is your Github link: https://github.com/SAP/go-hdb
Does anyone know how to fix the error?
Your error is complaining "I don't know how to read a null value."
The options.go file's read function has a switch statement at line 117 that implements the ways to read various database types. You will need to update this switch statement to be able to handle a null ("tcNull"?) type value.
Related
Formatting a CString in currency while typing in a edit box
I want to format a CString string in a currency while typing in a edit box using VISUAL C++ ... but I can't find a solution which works definitely... typing for instance the first digit (i.e. 5), in the edit box it must appear 5,00 , typing the second digit 50,00 (the cursor must always be before the comma)... typing 56234 it must be 56.234,00 , typing the , the cursor must go after the comma position and it mustn't appear twice or more times of course... and writing i.e 5,65 it must appear 5,65 This is my code, but it doesn't work perfectly: there's a variabile CString testo and a variable valuta which controls the edit box void CCampovalutaDlg::OnEnChangeEdit1() { // TODO: Se si tratta di un controllo RICHEDIT, il controllo non // invierà questa notifica a meno che non si esegua l'override della funzione CDialogEx::OnInitDialog() // e venga eseguita la chiamata a CRichEditCtrl().SetEventMask() // con il flag ENM_CHANGE introdotto dall'operatore OR nella maschera. // TODO: Aggiungere qui il codice del gestore di notifiche del controllo CString str = _T("0123456789"); CString comma = _T(","); UpdateData(); testo.Replace(_T("."), _T("")); if (testo.GetLength() > 3) testo.Insert(testo.GetLength() - 2, _T(".")); double cur = _wtof(testo); if (testo.GetLength() == 1) testo.Format(_T("%.2f"), cur); if (testo.FindOneOf(str) != -1) { for (int i = testo.GetLength() - 6; i > 0; i -= 3) { testo.Insert(i, _T(".")); } } UpdateData(FALSE); valuta.SetSel(testo.GetLength() - 3, testo.GetLength() - 3); } Thanks for solving my problem If I press the , it appears and the testo.Format doesn't make it appear a comma but a dot. And I can't type the decimal digits :-(
BCM2835 Raspberry Pi 4
I'm using the library bcm2835 1, it works, I can see on the terminal how plots 126 data information from a sensor but from that point on I recieve this: bcm2835_init: gpio mmap failed: Cannot allocate memory Does anyone know what is the problem or how to solve it?I think it's due to the library but not sure how to solve it. I'm using SPI for reciving the data #include <bcm2835.h> #include <stdio.h> char n = 0; void escriure_csv(char valor){ } int main() { FILE * fp; fp = fopen ("file.csv", "w+"); for(int i=0;i<130;i++){ bcm2835_init(); bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_1024); bcm2835_spi_chipSelect(BCM2835_SPI_CS0); bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); uint8_t send_data = 0xB3; //ens dona igual perque nomès ens interesa el que torna uint8_t read_data = bcm2835_spi_transfer(send_data); //printf("Read back from SPI: 0x%02X.\n", read_data); //transformem al que volem //els canvis seran mV per lo tant enlloc de *2.5 hi fem fer 2 uint8_t mV = (read_data*250)/1024; //en cas que tornes un 0 es perque el resultat es - o 0. printf("mV: %u\n", mV); n+=1; fprintf(fp,"%d",mV); fprintf(fp,"\n"); //escriure_csv(mV); } fclose(fp); return 0; }
As one of the comments said the problem here was that I was initializinf the SPI every iteration, I had to put it outside the for loop.
Change app language ios without restart Objective C
I am trying to change my app language without restarting the app. I have checked all the example and asked questions on the stack overflow. But i didn't find any link helpful. I am using the following code. - (void)languageChanger { MBProgressHUD * hudFirst = [MBProgressHUD showHUDAddedTo:self.view animated:YES]; hudFirst.delegate = self; hudFirst.labelText=NSLocalizedString(#"Please wait", #"Message"); hudFirst.center=self.view.center; hudFirst.dimBackground=YES; [hudFirst show:YES]; //[self localizedString:#"pl"]; NSString *Language=_select.titleLabel.text; if ([Language isEqualToString:[languageArray objectAtIndex:0]]|| Language == nil) { Language=#"en"; } else{ Language=#"pl"; } [self localizedString:Language]; NSString *uid = [[NSUserDefaults standardUserDefaults] objectForKey:#"userId"]; NSDictionary *inputDic=[NSDictionary dictionaryWithObjectsAndKeys:Language,#"lang",uid,#"id", nil]; NSString *urlString=[Globals urlCombileHash:kApiDominStage ClassUrl:#"ChangeLanguage/" apiKey:[Globals apiKey]]; [Globals PostApiURL:urlString data:inputDic success:^(id responseObject) { [self localizedString:Language]; [hudFirst hide:YES]; } failure:^(NSError *error) { [hudFirst hide:YES]; _errorView.hidden=NO; _lblMessage.text=NSLocalizedString(#"Sorry! Internal Server Error.", #"Message"); blurredView.hidden=NO; }]; } - (void) localizedString:(NSString *)key { NSString *langCode = key; NSArray *languages = nil; languages = [NSArray arrayWithObject:langCode]; [[NSUserDefaults standardUserDefaults] setObject:languages forKey:#"AppleLanguages"]; [[NSUserDefaults standardUserDefaults] synchronize]; }
You need to create .strings file for every language. For this, got to Project->localizations->create new file by pressing plus buttonenter image description here In this .strings file enter your keys like this-> I've done for spanish. /* French.strings EzEve Created by MOHIT MATHUR on 07/12/15. Copyright © 2015 CGT. All rights reserved. */ "Old_Password"="Introduzca su contraseña antigua"; "New_Password"="Introduzca su nueva contraseña"; "Confirm_Password"="Introduzca su nueva contraseña"; "Password_Length"="La contraseña debe tener al menos 6 caracteres"; "Password_Match"="Nueva contraseña y Confirmar contraseña no coinciden!"; "Camera_Support"="Este dispositivo no es compatible con la cámara"; "Country_Code"="Por favor, introduzca el código de país"; "Phone_Length"="Número de teléfono debe tener una antigüedad de 7 dígitos"; "Email_Validation"="Por favor, introduzca la dirección de correo electrónico válida (abc#example.com)"; "Email_Phone"="Número de teléfono debe ser por lo menos entrar en correo electrónico o número de teléfono"; "Fetch_Countries"="Imposible obtener países. Comprueba tu conexión a Internet y oprima REINT para volver a intentarlo o CANCELAR para abortar"; "Internet_Connection"="Conexión a Internet parece estar fuera de línea!"; "Profile_Change"="Perfil actualizado correctamente"; "Password_Change"="Contraseña cambiada con éxito"; "Name"="Nombre"; "Surname"="Apellido"; "UserName"="Nombre de usuario"; "Email"="Dirección de correo electrónico"; "Code"="1 (EE.UU.)"; "Phone"="Número de teléfono"; "Address"="Dirección"; "City"="Ciudad"; "State"="Estado"; "Zipcode"="Código postal"; "Country"="País"; "OldPassword"="Contraseña anterior"; "NewPassword"="Nueva contraseña"; "ConfirmPassword"="Confirmar contraseña"; "Change Password"="Cambiar la contraseña"; "Profile"="Configuración del perfil"; "Save"="Ahorrar"; "Avatar"="Seleccione Avatar"; "Male"="Masculino"; "Female"="Hembra"; "<20"="<20 años"; "20 and 30"="Entre el 20 y 30"; "30 and 39"="Entre 30 y 39"; "40 and 49"="Entre el 40 y el 49"; "50 and 59"="Entre el 50 y el 59 "; "60 and 69"="Entre el 60 y el 69"; ">70 Years"="> 70 años"; "Age"="Grupo de Edad"; "Done"="Hecho"; "Cancel"="Cancelar"; "AgeGroup"="Seleccione Grupo de Edad"; "Device"="Mi dispositivo"; "Facebook"="Tu Facebook"; "Twitter"="Tu Twitter"; Now, create a common method that can be accessible from all classes-> + (NSString*)setLanguage:(NSString *)key{ NSMutableDictionary *dict=[[NSMutableDictionary alloc]initWithDictionary:[[NSUserDefaults standardUserDefaults]objectForKey:KEY_USER_INFO]]; return NSLocalizedStringFromTable(key, [dict objectForKey:KEY_LANGUAGE], #""); } Now, call this method wherever you need to set the text-> [CommonFunctions setLanguage:#"Facebook"];
How to rewrite token stream more than once using ANTLR4
I implement simple preprocessor using the great ANTLR4 library. The program itself runs in several iterations - in each iteration the future output is modified slightly. Currently I use TokenStreamRewriter and its methods delete, insertAfter, replace and getText. Unfortunately I can't manage to rewrite tokens that was rewritten before (got IllegalArgumentException). This is not a bug but according to the source code multiple replacement can't be achieved in any way. I suppose that a proper solution exists as this appears to be a common problem. Could anyone please hint me? I'd rather use some existing and tested solution than reimplement the rewriter itself. Maybe the rewriter isn't the right tool to use. Thanks for help
Good evening Now a dynamic code for the same problem. First you must have made visible in your listener class the Token stream and the rewriter Here is the code of the constructor of my VB6Mylistener class class VB6MYListener : public VB6ParserListener { public: string FicName; int numero ; // numero de la regle wstring BaseFile; CommonTokenStream* TOK ; TokenStreamRewriter* Rewriter ; // Fonctions pour la traduction avec le listener void functions created by ANTLR4 ( contextes ) VB6MYListener( CommonTokenStream* tok , wstring baseFile, TokenStreamRewriter* rewriter , string Name) { TOK = tok; // Flux de tokens BaseFile = baseFile; // Fichier entree en VB6 Rewriter = rewriter; FicName = Name; // Nom du fichier courant pour suivi } Here in a context i cross with the listener. The Tokenstream is TOK visible by all the functions void std::string retourchaine; std::vector<std::string> TAB{}; for (int i = ctx->start->getTokenIndex(); i <= ctx->stop>getTokenIndex(); i++) { TAB.push_back(TOK->get(i)->getText()); // HERE TOK } for (auto element : TAB) { if (element == "=") { element = ":="; } if (element != "As" && element != "Private" && element != "Public") { std::cout << element << std::endl; retourchaine += element ; // retour de la chaine au contexte } } retourchaine = retourchaine + " ;"; Rewriter->replace(ctx->start, ctx->stop, retourchaine ); `
A workaround I am using because I need to make a replacement in the token and the Tokenrewriter does not make the job correctly when you have multiple replacements in one context. In each context I can make the stream of tokens visible and I use an array to copy all the tokens in the context and create a string with the replacement and after that, I use Rewriter->replace( ctx->start , ctx->stop , tokentext ) ; Some code here for a context: string TAB[265]; string tokentext = ""; for (int i = ctx->start->getTokenIndex(); i <= ctx->stop->getTokenIndex(); i++) { TAB[i] = TOK->get(i)->getText(); // if (TOK->get(i)->getText() != "As" && TOK->get(i)->getText() != "Private" && TOK->get(i)->getText() != "Public") //if (TOK->get(i)->getText() == "=") //{ if (TAB[i] == "=") { TAB[i] = ":="; } // if (TAB[i] == "=") { TAB[i] = "="; } // autres changements if (TAB[i] != "As" && TAB[i] != "Private" && TAB[i] != "Public") { tokentext += TAB[i]; } cout << "nombre de tokens du contexte" << endl; cout << i << endl; } tokentext = tokentext + " ;"; cout << tokentext << endl; Rewriter->replace(ctx->start, ctx->stop, tokentext); It's a a basic code I use to make the job robust. Hope this will be useful.
i think that rewriting the token stream is not a good idea, because you can't treat the general case of a tree. The TokenStreamRewriter tool of ANTLR is usefulness. If you use a listener , you can't change the AST tree and the contexts created by ANTLR. you must use a Bufferedwriter to do the job for rewriting the context you change locally in the final file of your translation. Thanks to Ewa Hechsman and her program on github on a transpiler from Pascal to Python. I think it'a real solution for a professional project. So i agree with Ira Baxter. we need a rewriting tree
Canon EDSDK Device Busy when changing property
I have a little problem with EDSDK. I tried to make a function that can switch from liveview to movie record. Everything is fine with liveview, I can take picture. But when I want to start movie record, I have a ERR_DEVICE_BUSY everytime I want to change a property (save to camera instead of PC). I try everything, make a loop, nothing. And it's the only place where I get this error. Here's my code : EdsDataType dataType; EdsUInt32 dataSize; EdsUInt32 enregistrement; err = EdsGetPropertySize(camera, kEdsPropID_SaveTo, 0, &dataType, &dataSize); err = EdsGetPropertyData(camera, kEdsPropID_SaveTo, 0, dataSize, &enregistrement); EdsUInt32 saveTo = kEdsSaveTo_Camera; if(enregistrement != kEdsSaveTo_Camera){ err = EdsSetPropertyData(camera, kEdsPropID_SaveTo, 0, sizeof(saveTo), &saveTo); if(err != EDS_ERR_OK){ printf("Erreur de changement d'emplacement de sauvegarde, arret de l'enregistrement\n"); printf("err : 0x%X\n", err); return err; } } //Changement du mode de prise de vu EdsUInt32 mode = 20; //Le monde 20 correspont à l'enregistrement vidéo EdsSetPropertyData(camera, kEdsPropID_AEMode, 0, sizeof(mode), &mode); //Variable pour la mise en route et l'arrêt de l'enregistrement EdsUInt32 debutEnregistrement = 4; EdsUInt32 finEnregistrement = 0; err = EdsSetPropertyData(camera, kEdsPropID_Record, 0, sizeof(debutEnregistrement), &debutEnregistrement); if(err != EDS_ERR_OK){ printf("Erreur lors du lancement de l'enregistrement"); return err; } //Wait for stop record err = EdsSetPropertyData(camera, kEdsPropID_Record, 0, sizeof(finEnregistrement), &finEnregistrement); if(err != EDS_ERR_OK) printf("Erreur lors de l'arret de l'enregistrement"); //L'enregistrement est fini, vérification des evenement EdsGetEvent(); If you have solution, I take, thanks.
Regardless of what the docs say, the EDSDK sometimes returns EDS_ERR_DEVICE_BUSY for EdsSetPropertyData() when the actual error is a bad input parameter. For example, try setting kEdsPropID_Av with a value of decimal 50 (0x32) which is not in the table given in the documentation. On my EOS 5Ds, this returns EDS_ERR_DEVICE_BUSY no matter how many retries are attempted. Passing a legal value, e.g. 0x33 (for f/6.3) succeeds first time. The bug is 100% reproducible here. So, if you get this "device busy" error when setting properties, check the input values you are passing with a fine-toothed comb.
You can try this I don't know if you already but it should work it has for me so far on all my property changes. Just after you opened the session use the EdsSetPropertyEventHandler function Begin by stopping you LiveView by putting kEdsEvfOutputDevice at TFT if I recall good. (the parameter that is not PC). In the call back of the property event handler you make a switch on the event and when it is for the property kEdsEvfOutputDevice, then you throw your function to go to movie mode. the callback function will be called when the property changed will be made so you won't have any device busy or notready. But becareful you have to set your callback function to static so that it works. So you wont be able to call anyother functions that the one that are static, the same for the variables. If you didn't understand I can explain it to you in french, far more easy for me ^^