• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Snippet] HexString

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Nothing special, small snippet written as kind of supplement to Ascii.

Function HS2I may seem pointless since hex values e.g. 0x2000 are automaticaly converted to decimal integral value. Currently exists for the sake of completeness.

Credits to TheDamien for his hash formula designed for original Ascii.
JASS:
/*****************************************************************************
*
*    HexString v1.0.0.3
*       by Bannar aka Spinnaker
*
*    Performs conversions from hexadecimal numbers to strings and vice versa.
*    
*       Credits to TheDamien for hash formula from original Ascii project
*
******************************************************************************
*
*    private constant boolean ADD_PREFIX
*       whether to add or not the "0x" prefix; used only in I2HS function
*
*
*    function I2HS takes integer hex, boolean upper returns string
*       returns hexadecimal representation of hex as string
*
*    function HS2I takes string s returns integer
*       returns integral number retrieved from s representing number in hexadecimal convention
*
*****************************************************************************/
library HexString

globals
    /**
        Config
    */
    private constant boolean ADD_PREFIX = true
endglobals

globals
    private string array Id2CharMap // (16)
    private integer array Int2IdMap // (16)
endglobals

function I2HS takes integer hex, boolean upper returns string
    local string s = ""
    local integer div

    loop
        set div = hex/16
        set s = Id2CharMap[hex - div * 16] + s
        set hex = div
        exitwhen hex == 0
    endloop

    if ( upper ) then
        set s = StringCase(s, true)
    endif
    static if ( ADD_PREFIX ) then
        set s = "0x" + s
    endif
    return s
endfunction

function HS2I takes string s returns integer
    local integer size = StringLength(s)
    local integer hex = 0
    local integer it = 0
    local integer key
    local string char

    if ( SubString(s, 0, 2) == "0x" ) then
        set s = SubString(s, 2, size)
        set size = size - 2
    endif

    loop
        exitwhen it == size

        set char = SubString(s, it, it+1)
        set key = Int2IdMap[StringHash(char) / 0x1F0748 + 0x3EA]

        debug if (key == 0) then
            debug call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "DEBUG: Hex::HS2I Invalid string character.")
            debug return -1
        debug endif

        set hex = hex*16 + (key-1)
        set it = it+1
    endloop

    return hex
endfunction

private module HexInit
    private static method onInit takes nothing returns nothing
        set Id2CharMap[0] = "0"
        set Id2CharMap[1] = "1"
        set Id2CharMap[2] = "2"
        set Id2CharMap[3] = "3"
        set Id2CharMap[4] = "4"
        set Id2CharMap[5] = "5"
        set Id2CharMap[6] = "6"
        set Id2CharMap[7] = "7"
        set Id2CharMap[8] = "8"
        set Id2CharMap[9] = "9"

        set Id2CharMap[10] = "a"
        set Id2CharMap[11] = "b"
        set Id2CharMap[12] = "c"
        set Id2CharMap[13] = "d"
        set Id2CharMap[14] = "e"
        set Id2CharMap[15] = "f"

        set Int2IdMap[883]  = 1
        set Int2IdMap[1558] = 2
        set Int2IdMap[684]  = 3
        set Int2IdMap[582]  = 4
        set Int2IdMap[668]  = 5
        set Int2IdMap[538]  = 6
        set Int2IdMap[672]  = 7
        set Int2IdMap[1173] = 8
        set Int2IdMap[71]   = 9
        set Int2IdMap[277]  = 10

        set Int2IdMap[222]  = 11
        set Int2IdMap[178]  = 12
        set Int2IdMap[236]  = 13
        set Int2IdMap[184]  = 14
        set Int2IdMap[1295] = 15
        set Int2IdMap[1390] = 16
    endmethod
endmodule

private struct Hex extends array
    implement HexInit
endstruct

endlibrary
Demo:
JASS:
struct ascii_demo extends array
    private static method onInit takes nothing returns nothing
        local integer a = 0xFF
        local integer b = 0x2A

        local integer c = a + b
        call DisplayTimedTextFromPlayer(GetLocalPlayer(), 0, 0, 60, I2HS(a, true) + " + " + I2HS(b, true) + " = " + I2HS(c, true))

        call DisplayTimedTextFromPlayer(GetLocalPlayer(), 0, 0, 60, "(string) 0x0 as integral: " + I2S(HS2I("0x0")))
        call DisplayTimedTextFromPlayer(GetLocalPlayer(), 0, 0, 60, "(int) 0x1F0748 converted to string: " + I2HS(0x1F0748, true))
    endmethod
endstruct
 
Last edited:
Level 25
Joined
Jun 5, 2008
Messages
2,572
JASS:
private struct Hex extends array
    implement HexInit
endstruct

So a private struct implements a private module with a private method because?
Seems to me you are using it just because you can, since no one else will be able to implement that module due to it being private and yet it's only implemented on one place in the script so might as well write the onInit method inside the struct, as it is intended.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
JASS:
private struct Hex extends array
    implement HexInit
endstruct

So a private struct implements a private module with a private method because?
Seems to me you are using it just because you can, since no one else will be able to implement that module due to it being private and yet it's only implemented on one place in the script so might as well write the onInit method inside the struct, as it is intended.

Kingz, module initializers are a necessary hack unless you are using Cohadar's JassHelper, otherwise one can't be sure these values will be initialized properly when needed.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Cohadar went MIA without finishing what he has started. Why bother starting to update something if you know you're busy and do not have enough time to do that properly.

Honestly, there are multiple things that could get improved with lot of them being really simple: .name() not to generate prototypes; allow nested text macros; enable __FILE__, __LINE__ macros, operators +/-/+=/-= and suchs with function overloading as well. Granted last one may take a little more time. Of course list of things to be done is a bit longer..

Not to take anything from Cohadar, I recpect him and everything, yet truth has been told.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
At first, thanks for feedback. And then..

I won't resignate from module initializer and you TriggerHappy, are the person which clearly knows why. Unless you get me chart where its clearly shown that JNPG 2.0 is in charge instead of 0.5 (which we know is not true, popularity is heavily in favour of 0.5 version just because it was released so much earlier) this probably won't happen. The other thing is, if more ppl together with moderators agree to do it then I'm willing to follow the voice.

Hex is supposed to add functionality similar to Ascii thats why I've called this a "supplement". The only think which I'm elaborating is changing the name of library to e.g HexConv or smthing similar, in case "Hex" is a popular prefix for spells. Initialy, I had both libraries merged for my personal needs, yet Ascii is here for ages thus releasing such hybrid was not an option.

I can not believe that when once in such a long period of time I've used shorten names for struct members, suddenly ppl jump on it. You should know from my other resources that I'm not the person who likes nor enjoys uber short names. The last lib thats probably uploaded with such style is GetClosestWidget which was posted in times when Maggy/Nes and others were spreading the idea to short almost everything.

Ascii also uses S2A and A2S as names for its function members. You could even argue that its more intuitive in warcraft3 universe than more descriptive names since conversions in jass are performed via R2S, I2S and such. Honestly, "IntegerToHexString" would look like a stranger within X2Y family.

No offense tho, opinion is just an opinion.
 
I won't resignate from module initializer and you TriggerHappy, are the person which clearly knows why. Unless you get me chart where its clearly shown that JNPG 2.0 is in charge instead of 0.5 (which we know is not true, popularity is heavily in favour of 0.5 version just because it was released so much earlier) this probably won't happen. The other thing is, if more ppl together with moderators agree to do it then I'm willing to follow the voice.

Why does the JNGP version matter at all? You're abusing the language by deciding that your library should get initialization priority over others, and for what?

Not to mention JassHelper is what matters, not NewGen.

Hex is supposed to add functionality similar to Ascii thats why I've called this a "supplement". The only think which I'm elaborating is changing the name of library to e.g HexConv or smthing similar, in case "Hex" is a popular prefix for spells. Initialy, I had both libraries merged for my personal needs, yet Ascii is here for ages thus releasing such hybrid was not an option.

I didn't even notice the library name. That should almost definitely be more descriptive because like you said its likely to conflict with peoples personal libraries (or possibly variables).

As for the function names, like I said it may be just my personal preference but I think the API would benefit from being more descriptive.

JASS:
function Hex2String takes integer hex, boolean upper returns string
function String2Hex takes string s returns integer

// or
functopn I2HexString takes integer hex, boolean upper returns string
function ConvertHexString takes string s returns integer

// or 
function Int2HexString takes integer hex, boolean upper returns string
function HexString2Int takes string s returns integer

// or 
function GetHexString takes integer hex, boolean upper returns string
function ConvertHexString takes string s returns integer

I can not believe that when once in such a long period of time I've used shorten names for struct members, suddenly ppl jump on it. You should know from my other resources that I'm not the person who likes nor enjoys uber short names. The last lib thats probably uploaded with such style is GetClosestWidget which was posted in times when Maggy/Nes and others were spreading the idea to short almost everything.

I don't know what you're talking about considering this doesn't have any public struct members or methods. You also state you don't like uber short names yet this library is exactly that?

Sorry I'm just confused.

Ascii also uses S2A and A2S as names for its function members.

I personally don't like it there either.

You could even argue that its more intuitive in warcraft3 universe than more descriptive names since conversions in jass are performed via R2S, I2S and such. Honestly, "IntegerToHexString" would look like a stranger within X2Y family.

Except it's I2HS not I2H, or something. It looks awkward and it explains nothing.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
You are wierd TriggerHappy.
I don't know what you're talking about considering this doesn't have any public struct members or methods. You also state you don't like uber short names yet this library is exactly that?

Sorry I'm just confused.
Have you actually thought before actually posting? You're confused? Don't act like a kid pointing at everything. 2nd, y there are no struct members, yet you should get the point. Usually resources in Jass Resources section are written using features from object programing, and once again it was refering to idea of shorten names which you know I'm not following. Have you even seen other resources? You judge my workflow by looking at this small code with merely 2 functions?

Since when JassNewGenPack does not contain JassHelper? And btw, where have I stated that JassHelper == JNPG?

Even if Purge haven't noticed the problem with lib's name I would change it anyways. Don't worry about that.

I2S and S2I are already takes if you haven't noticed after all those years. HS refers to HexString, similar to A refering to Ascii in Ascii library.
 
Spinnaker said:
Have you actually thought before actually posting? You're confused? Don't act like a kid pointing at everything.

Yes I actually thought before actually posting, and yes I'm still confused.

So why am I "a kid pointing at everything"?

Spinnaker said:
2nd, y there are no struct members, yet you should get the point. Usually resources in Jass Resources section are written using features from object programing, and once again it was refering to idea of shorten names which you know I'm not following. Have you even seen other resources?

I understand there are no struct members, however you said you don't like shortened names yet this library does that. Unless you're saying you don't like short names for methods only?

You're legitimately being confusing/contradictory, don't get mad at me for trying to understand what you meant.

Spinnaker said:
You judge my workflow by looking at this small code with merely 2 functions?

Why are you taking this so offensively? I'm critiquing your code, you don't need to get upset lol. I clearly stated many times the names changes were my personal preference, yet you take it as me "judging your workflow"?

If you can't take criticism don't post resources.

and since when am I supposed to judge a resource based on a users other ones?

Spinnaker said:
Since when JassNewGenPack does not contain JassHelper? And btw, where have I stated that JassHelper == JNPG?

You stated the version of JNGP matters in relation to module initializing, when it doesn't.

For years I had 0.5d with an updated JassHelper, as do most people. You can update your JH separately from JNGP. NewGen is just a container of tools with injection features to the world editor.

spinnaker said:
Since when JassNewGenPack does not contain JassHelper?

I never said that.

spinnaker said:
I2S and S2I are already takes if you haven't noticed after all those years. HS refers to HexString, similar to A refering to Ascii in Ascii library.

Yes, you know what it refers to because you wrote it. Someone looking at the code won't.
 

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Updated to 1.0.0.1 - changed name of the library to HexString which seems to be intuitive and long enough not to cause any problems which Hex surely could cause.

I enjoy taking feeback, and you can see that alsmost always I add "thanks for feeback" within replies. Lastest replies regarding my resource from Purge, BPower and others are written in more "opinion-ish" way, when I read those, I dont feel like being forced to do anything. I go to my map, copy the script, write 2nd version, test them both and the results are fantastic, they fatisty both me and potential users. However, I've found you talking offensively, posting in a way to force a change, not to propose it. Meaby you don't, yet thats what I feel.

And to end this pointless argument: In this case it seems reasonable to use shorten names as Jass native conversions as well as Ascii also use such names.
 
However, I've found you talking offensively, posting in a way to force a change, not to propose it. Meaby you don't, yet thats what I feel.

That couldn't be farther from the truth.

Me said:
Also for the API I would prefer something more descriptive than I2HS, however that may be just me.

The only thing I proposed needed to be changed was module initialization, everything else (API) I clearly stated it was personal preference.

You didn't agree with it so you took it offensively, I was being completely passive.

The fact of the matter is you're abusing modules, and in my opinion it shouldn't be approved.

However that's not part of the rules (yet?), so obviously this won't be rejected because of that. I was simply letting you know since purge asked if anyone had anything to say before he approved it.
 
Then most of the resources should be also rejected >.>

It's not my fault Nestharus and Mag poisoned everyones minds these past couple years. I'm simply pointing out flaws I see.

I also wouldn't say most, but a good amount of resources could use this change. It's not hard for people to switch back to standard initialization, although they might not all be active anymore.

It's not a serious issue, but it is significant enough.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
It's not my fault Nestharus and Mag poisoned everyones minds these past couple years.

If anyone needs to initialize anything from a module in any resource, then the init priorities are out of whack. Cohadar's JassHelper amends this problem but introduces its own problems, too. I don't think it's good practice to initialize from a hacky method, but in JASS we need our weird stuff.
 
There is a valid reason why module initializers are used:

Bribe said:
However, systems that create things which might be used by the
the public during initialization (such as a hashtable) need to use
modules to initialize, just in case. Its API is horrendous but it is
reliable.

It is a valid concern for resources like Table, in cases where you want to create the object on initialization. Before module initializers were used, I actually faced this problem when I was coding Ardent Heroes. I circumvented it by using a timer to make sure my initialization was done after the other set-up, but that is horrible for the user's end. Of course, it all depends on your philosophy on the matter. There are two sides:

(1) You use a module initializer in your system, and as such all code that uses it doesn't have to worry about their own initializations. Drawback: you have some extra hassle for your code.
(2) You use a regular initializer, but you run the risk of other initializations not working (if they require your system for the init). This can lead to unexpected bugs (happened to me before a few times and took me a while to figure out), but you don't have to do weird coding practices.

It is a matter of interface and how reliable it is on the user end. IMO, that is pretty important, and it doesn't sacrifice much readability. Module initializers just seem like a necessity. I'm fine with people using regular struct allocation or using OOP vJASS but this makes a difference that isn't related to speed.

-----

As for the naming convention, I didn't notice it at first. I kinda agree with TriggerHappy that I2HS and HS2I isn't super clear, but now that the library is named HexString I'm fine with it. :) I'm going to go ahead and approve it.

EDIT: Bribe beat me to the post because he is Captain America. No fair.
 
So basically module initializers are used to prevent people who abuse them in the first place, from having errors?

I understand the importance for some scripts, but not this one.

Sorry if I misunderstood.

I don't quite remember. I would have to check. I think the issue was that the initializer order wasn't really "smart" unless you used module initializers. e.g.:
JASS:
library A
    struct First
        private static method onInit takes nothing returns nothing 
        endmethod
    endstruct
endlibrary

library B requires A
    struct Second
        private static method onInit takes nothing returns nothing 
        endmethod
    endstruct
endlibrary

Even though B requires A, there is no guarantee that First.onInit() is ran before Second.onInit(). I'm not 100% positive though, I'll have to check when I get home. Cohadar fixed that by making required inits take priority (and then there were some other priority changes), but his jh has other problems so it didn't become adopted.

I could be totally wrong though. Maybe it is just for module initializers. I'll have to check tomorrow when I get home. :thumbs_up:
 

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
why it returns -1 when I entered 0?
attachment.php

afaik 0 must also return 0

suggestion
maybe you need to do something like
JASS:
            debug if debugMsg != null then
                debug call BJDebugMsg(debugMsg)
            debug endif
so user can disable the debug message even if they are in debug mode.
 

Attachments

  • Untitled-1.jpg
    Untitled-1.jpg
    148.4 KB · Views: 265

Bannar

Code Reviewer
Level 26
Joined
Mar 19, 2008
Messages
3,140
Updated.

@Dalvengyr thank you for spotting this. Issue due to incorrect mapping of id2int. For Id2IntMap[883] key was equal to 0, and if we consider the fact that each row of array has value of 0 by default, we recieve results where hash of 883 is treated like an invalid character. This is no longer an issue after update.

Edit:
JASS:
    if ( SubString(s, 0, 2) == "0x" ) then
        set s = SubString(s, 2, size)
        set size = size - 2
    endif
Fixed another issue: HS2I is named HS2I for a reason.. what is passed string starts with "0x"? This simple if takes care of that.
Added demo code.
 
Last edited:
Top