Cannot find property setter for "Chars" - char

I am trying to do the following expression, but I keep running into this exception, "Cannot find property setter for 'chars'."
Here is the expression:
xstr, str : string;
for i := 1 to length(str) do
begin
if ((i mod 2)<>0) then
begin
xstr[i] := char(Ord(str[i]) xor $AA); <<<<------ Exception Raised
end
else
begin
xstr[i] := char(Ord(str[i]) xor $55); <<<<------ Exception Raised
end;
end;
The value of "str" is passed into the encryption method.
This is part of an encryption method. What is the best way to do this?

System.String is an immutable class, meaning you cannot modify instances of it. .NET requires modifying string operations to create new instances of a string. For your purpose, it’s probably easiest and most efficient to create a char array of the modified characters and then construct a string from that.
In general, the System.Text.StringBuilder class offers a mutable string instance.
In fact, even if it weren’t for the immutability of strings, your code would fail because you didn’t allocate a string, so assignment to xstr[i] would yield in a buffer overflow exception. You need to do that when using an array of char.

Related

How to use the method Sort of the class TList in Delphi

How does the method Sort of the class TList work? Does this method only sort in a way that the elements of the list only ascend/descend?
Please, have a look at the code below.
Type
PInteger = ^Integer;
Function Compare(Item1, Item2 : Pointer) : Integer;
Begin
if PInteger(Item1)^ > Pinteger(Item2)^ then Result:= 1
else if PInteger(Item1)^ < PInteger(Item2)^ then Result:= -1
else Result:= 0;
End;
{ And, for instance, somewhere we call the method }
List.Sort(Compare);
Now the thing is, after i compile the code, it works well, the list is sorted in a way that the elements ascend. But i don't understand the following line:
PInteger(item1)^ // What does this represent?
And what item1, item2 pointers point to? Do they not need to be initialized?
First what PInteger(item1)^ does/represent?
Item1 is a Pointer, the address of an item stored in the TPointerList.
PInteger is a typed pointer, this means that this pointer points to an address where it is expected to find an integer (four bytes).
^ the dereferencing symbol, you can use this with pointers to tell the compiler that you want to use the data stored in the address that the pointer is currently pointing to
PInteger(item1)^ you are performing a typecast. in other words you are telling the compiler to treat the pointer Item1 as if it was PInteger then you dereference it to use its data/value stored at the address Item1
Now back to your code. Your function expects two pointers to Items (Integers) from the list which then you compare the data stored in those address (by dereferencing). This means that the list is responsible for the pointers given to your function, in fact if the ItemCount is less than 1 your function will not be executed.
Note: you need to understand that this function will fail if the pointers are pointing to something other than integers (or give an undefined behavior).

Convert enum type to std_logic_vector VHDL

I want to know if it is possible to convert a enum type, like FSM states to std_logic_vector or integer. I'm doing a testbench with OSVVM for a FSM and I want to use the scoreboard package to automatically compare the expected state with the actual one.
Thanks!
To convert to integer, use:
IntVal := StateType'POS(State) ;
From there, it is easy to convert to std_logic_vector, but I prefer to work with integers when possible as they are smaller in storage than std_logic_vector. For verification, it will be easier if you start to think more about integers when the value is less than 32 bits.
If you need it as std_logic_vector, using only numeric_std you can:
Slv8Val := std_logic_vector(to_unsigned(IntVal, Slv8Val'length)) ;
For verification, I liberally use numeric_std_unsigned, so the conversion is a easier:
Slv8Val := to_slv(IntVal, Slv8Val'length) ;
In the event you have an integer and want to convert it back to a enumerated value, you can use 'VAL.
State := StateType'VAL(IntVal) ;
In OSVVM, we use records with resolved values to create a transaction interface. We have a resoled types for integers (osvvm.ResolutionPkg.integer_max). We transfer enumerated values through the record using 'POS (as we put it in) and 'VAL (as we get it out).
Note don't confuse 'VAL with 'VALUE. 'VALUE converts a string to a value - opposite to 'IMAGE.
You of course learn all of this in SynthWorks' OSVVM class :).
Maybe like this...
function my_func(inp : t_my_enum) return integer is
begin
case inp is
when stateA =>
return 1;
when stateB =>
return 2;
when others =>
return 0;
end case;
end function my_func;
... <= my_func(stateB);`

PL/SQL difference between DEFAULT and assignment operator

I'm newbie in PL/SQL and this question might seem to be 'childish' so I'm sorry in advance, but Google didn't help me at all...
Is there any difference between following procedures?
Procedure p1(a Number DEFAULT 0) Is
Begin
DBMS_OUTPUT.put_line(a);
End;
Procedure p2(a Number := 0) Is
Begin
DBMS_OUTPUT.put_line(a);
End;
I have checked them, so when I call both of them without args the output is 0, but I'm not sure if there are any side effects.
If you follow Oracle's documentation
You can use the keyword DEFAULT instead of the assignment operator to
initialize variables. You can also use DEFAULT to initialize
subprogram parameters, cursor parameters, and fields in a user-defined
record.
Use DEFAULT for variables that have a typical value. Use the
assignment operator for variables (such as counters and accumulators)
that have no typical value.
DECLARE
blood_type CHAR DEFAULT 'O'; -- Same as blood_type CHAR := 'O';
hours_worked INTEGER DEFAULT 40; -- Typical value
employee_count INTEGER := 0; -- No typical value
BEGIN
NULL;
END;
/
So I guess internally is the same.
Let's take a look to the documentation of the latest Oracle release (12c R1) at the moment of writing. You explicitly ask for subprogram parameters so let's take that first.
Default Values for IN Subprogram Parameters:
When you declare a formal IN parameter, you can specify a default value for it. A formal parameter with a default value is called an optional parameter, because its corresponding actual parameter is optional in a subprogram invocation. If the actual parameter is omitted, then the invocation assigns the default value to the formal parameter.
The documentation doesn't mention default keyword but it still works. Example (in 12c R1):
declare
function f1(a in number) return number is begin return a; end;
function f2(a in number := 2) return number is begin return a; end;
function f3(a in number default 3) return number is begin return a; end;
begin
dbms_output.put_line(f1(1));
dbms_output.put_line(f2);
dbms_output.put_line(f3);
end;
/
Prints 1, 2, 3 as expected.
However as it's not mentioned in the authorative documentation I discourage the use of default keyword in this context.
Other interesting context is Initial Values of Variables and Constants:
To specify the initial value, use either the assignment operator (:=) or the keyword DEFAULT, followed by an expression.
And that's the only time default keyword is mentioned. All documentation examples use assigment only.
Conclusion
Technically default keyword and assigment are the same and work in both contextes, but only assigment is promoted in the documentation. I think Oracle is effectively deprecating the default keyword in this context and thus I won't recommend the use of it in new PL/SQL code. Assigment operator makes the same job with zero fuss.

My sorting algorithm runtime errors

I developed the following sorting algorithm but there are some run time errors that I cant figure out. The program terminates when it comes to the part of filling the array. I'm still a beginner in ada so I couldn't figure out where the problem is...
With Ada.Text_IO;
With Ada.Integer_Text_IO;
Use Ada.Integer_Text_IO;
Use Ada.Text_IO;
Procedure sort is
n,i,x : Integer;
-- Max_Heapify Function...
Procedure Max_Heapify ( i, n : integer) is
j, Temp : Integer;
begin
Temp:=Int_Acc(i);
j:=2*i;
if Temp>Int_Acc(j) then
elsif Temp<=Int_Acc(j) then
Int_Acc(j/2):=Int_Acc(j);
j:=2*j;
end if;
end loop;
Int_Acc(j/2):=Temp;
end Max_Heapify;
begin
Get(n);
for i in MyArr'range loop
Put_Line("Enter Element " & Integer'Image(i));
Get(MyArr(i));
end loop;
end;
end sort;
Thanks in advance :)
Your Problem is that you are insisting on writing Ada code using c - Style programming paradigms.
Firstly:
The declarations:
Type Arr is array(1..20) of Integer;
Type int_access is access Arr;
MyArr : int_access;
Where you use Int_Acc : in out int_access as parameters to procedures are useless in Ada. You are trying to pass a pointer to an array in (which you are doing!), but you should just pass your Type Arr as in out - The Ada compiler knows to do this as a pointer!
Secondly:
I cannot see where you actually allocate any memory to MyArr. This is a possible source of your runtime error. (when you write to or index an array that does not exist, i would expect to have a problem!)
Thirdly:
You seem to be mixing fixed length arrays with variable length input. If N > 20, you will have a problem.
Fourthly:
Insulting the language is not the best way of getting help from those who like it.
NWS has nailed it : there is a pointer, but no array there.
But it's clear that you have learned C, which leaves you with a lot to learn about other languages including Ada. There really are better ways of doing many things, that aren't taught to C programmers because C doesn't allow them.
Allocating variable sized arrays without pointers, malloc and free for example...
Type Arr is array(positive range <>) of Integer; -- of any size
begin
Put_Line("Enter Number Of Elements Of Array");
Get(n);
declare -- now we know the size
My_Arr : Arr(1 .. n);
begin -- My_Arr is in scope until the end of this block
...
end;
end sort;
Using the type system better...
Bad programming :
for i in 1 .. n loop
Get(MyArr(i));
end loop;
HeapSort(MyArr,n);
for i in 1 .. n loop
Put_Line(Integer'Image(MyArr(i)));
end loop;
This is bad because it violates the DRY principle : loop bounds repeated, and something that hopefully represents the array size passed around as a separate parameter... a maintenance nightmare if you decide to rename n to something meaningful for example.
better programming : Use the type system. Recognise that merely declaring an array has declared a new subtype of integer, representing the index of the array. You can access it as My_Arr'range, and the high bound as My_Arr'last.
for i in My_Arr'range loop
Get(MyArr(i));
end loop;
HeapSort(MyArr);
for i in My_Arr'range loop
Put_Line(Integer'Image(MyArr(i)));
end loop;
And accidents such as redefining n after the array declaration can no longer generate buffer overflows.
NOTE: Heapsort now gets its range from the array. (Max_Heapify may still need a separate parameter to operate on subsets of the array)
Arguably best - if it makes the intent clearer - name the index datatype explicitly and use it...
declare -- now we know the size
subtype My_Range is positive range 1 .. n;
My_Arr : Arr(My_Range);
begin -- My_Arr is in scope until the end of this block
for i in My_Range loop ...
And lastly, which do you prefer; a Storage_Error exception immediately the bug occurs (writing to memory you forgot to allocate) or something odd happening much later because something scribbled across another variable?
EDIT
Having cleared up the major issues two more subtle ones remain...
If I compile the modified program (in Gnat 4.8) I get several warnings : one of them is important and tells you exactly what the problem is...
Most of the warnings stem from the fact that
for i in My_Arr'range loop
declares its own loop variable i which hides any existing in-scope declaration. So you can tidy up the code by removing the unnecessary declarations.
What remains is:
sort.adb:51:28: warning: loop range may be null
sort.adb:51:28: warning: bounds may be wrong way round
The for loop bounds are empty ranges, reversed...
1 .. 3 declares a subtype with 3 values
reverse 1 .. 3 declares the same subtype and iterates backwards over it.
But 3 .. 1 declares an EMPTY subtype (containing NO valid values) so iterating over it - either way round - does precisely nothing.
Hopefully that is the missing part of the puzzle. I'm not clear why one faulty loop gets this warning while the other (at line 38) doesn't...
if j<n **and then** Int_Acc(j+1)>Int_Acc(j) then
j:=j+1;
I think you want just 'and' instead of 'and then,' although I haven't looked at Ada code in years.
Did that compile?

Reversing encryption in delphi

It was not me who wrote this code, it was the previous programmer. However, I noticed he didn't provide a decryption algorithm, rendering the encryption useless.
How can I decrypt this?
function Encrypt(jstr: String): String;
var
I: Integer;
A: Real;
begin
if Length(jstr) = 0 Then begin
Result := '';
Exit;
end;
A := 0;
for I := 0 To Length(jstr) do
A := A + (Ord(jstr[I]) * Pos(jstr[I],jstr)) / 33;
Result := FormatFloat('0000000000.0000000000',A);
if Pos(',',Result) > 0 then begin
Insert('.',Result,Pos(',',Result));
Delete(Result,Pos(',',Result),1);
end;
end;
Thanks!
It looks like a one way hash and hence is not reversible. For example, is the string is very big the result is still a string representation of a float.
That function cannot be reversed. Since it takes input of arbitrary length and returns output of finite length, simple information theory tells you the futility of attempting to write a general inverse. Even for shorter input strings it seems to me that different input strings can result in the same encrypted string.
Even as a hash this function seems very brittle to me due to the bizarre use of floating point code. If I were you I would replace this function with something more fit for purpose.
Finally, I recommend that you undertake a review of all code produced by this developer. The low quality of this code and algorithm suggests to me that everything that this developer touched is liable to have defects.

Resources