{"id":2267,"date":"2011-08-31T21:01:53","date_gmt":"2011-09-01T01:01:53","guid":{"rendered":"http:\/\/www.gubatron.com\/blog\/?p=2267"},"modified":"2011-08-31T21:01:53","modified_gmt":"2011-09-01T01:01:53","slug":"nsis-strcontains-function-find-the-index-of-a-sub-string","status":"publish","type":"post","link":"https:\/\/www.gubatron.com\/blog\/nsis-strcontains-function-find-the-index-of-a-sub-string\/","title":{"rendered":"NSIS: StrContains function &#8211; Find the index of a sub string."},"content":{"rendered":"<p>Recently I was out of internet and I needed to implement a function that would search if a String was part of another String for an NSIS installer.<br \/>\nHere&#8217;s my rendition of such a function. Once I came back online I found out about <a href=\"http:\/\/nsis.sourceforge.net\/StrStr\">StrStr<\/a>, but here&#8217;s another option that gives you as output the starting index on the bigger string (aka Haystack) if the smaller string (aka Needle) is found. Otherwise, it returns -1.<\/p>\n<p>[code]<br \/>\n; &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br \/>\n; StrContains<br \/>\n; Returns starting index of where a string is contained inside another string (case sensitive)<br \/>\n; Usage: !insertmacro StrContains ${HayStack} ${Needle} ${Output}<br \/>\n;<br \/>\n; Parameters:<br \/>\n;   HayStack &#8211; The string that could contain the substring you&#8217;re looking for<br \/>\n;   Needle   &#8211; The string you are looking for<br \/>\n;   Output   &#8211; -1 if the needle is not in the haystack, or the offset where it exists.<\/p>\n<p>Var HaystackOffset ;current offset on haystack to copy NeedleLength characters into HayStackBuffer<br \/>\nVar HaystackLength ;size of the big string<br \/>\nVar MaxHaystackOffset ;maximum offset we can reach<br \/>\nVar NeedleLength ;length of string we&#8217;re looking for<br \/>\nVar HaystackBuffer ;substring we get on each iteration<\/p>\n<p>!macro StrContains Haystack Needle Output<br \/>\n  ;we&#8217;ll be repeating this operation until we&#8217;ve reached<br \/>\n  ;HayStackLength &#8211; NeedleLength<\/p>\n<p>  ;Get the lengths of the strings.<br \/>\n  StrLen $HaystackLength ${Haystack}<br \/>\n  StrLen $NeedleLength ${Needle}<br \/>\n  StrCpy $HaystackOffset 0<\/p>\n<p>  ;Determine what&#8217;s the maximum offset we can use to search for the substring<br \/>\n  IntOp $MaxHaystackOffset $HaystackLength &#8211; $NeedleLength<br \/>\n  IntOp $MaxHaystackOffset $MaxHaystackOffset &#8211; 1<\/p>\n<p>  ;Make sure needle is not bigger than haystack<br \/>\n  IntCmp $NeedleLength $HaystackLength LoopStart LoopStart DidNotFindIt<\/p>\n<p>  DidNotFindIt:<br \/>\n  StrCpy $HaystackOffset -1<br \/>\n  Goto Finish<\/p>\n<p>  ;Start of substring comparison loop<br \/>\n  LoopStart:<br \/>\n  ;copy the substring to a buffer<br \/>\n  StrCpy $HaystackBuffer ${Haystack} $NeedleLength $HaystackOffset<\/p>\n<p>  ;It&#8217;s pretty cool if you uncomment this.<br \/>\n  ;MessageBox MB_ICONINFORMATION|MB_OK &quot;[Loop] Buffer: [$HaystackBuffer] Offset: [$HaystackOffset]&quot;<\/p>\n<p>  ;If we&#8217;re done, we return the current haystackoffset<br \/>\n  StrCmpS $HaystackBuffer ${Needle} Finish FigureOutNextStep<\/p>\n<p>  ;Did we reach the end, or can we move a bit more<br \/>\n  FigureOutNextStep:<\/p>\n<p>  ;Move offset 1 character to the right and see if we can keep going<br \/>\n  IntOp $HaystackOffset $HaystackOffset + 1<br \/>\n  IntCmp $HaystackOffset $MaxHaystackOffset LoopStart LoopStart DidNotFindIt <\/p>\n<p>  Finish:<br \/>\n  StrCpy ${Output} $HaystackOffset<br \/>\n!macroend<br \/>\n[\/code] <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Recently I was out of internet and I needed to implement a function that would search if a String was part of another String for an NSIS installer. Here&#8217;s my rendition of such a function. Once I came back online I found out about StrStr, but here&#8217;s another option that gives you as output the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15],"tags":[],"class_list":["post-2267","post","type-post","status-publish","format-standard","hentry","category-code"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p5Unzf-Az","jetpack-related-posts":[{"id":2197,"url":"https:\/\/www.gubatron.com\/blog\/nsis-charat-function-macro\/","url_meta":{"origin":2267,"position":0},"title":"NSIS CharAt Macro","author":"gubatron","date":"March 21, 2011","format":false,"excerpt":"Lord knows why the NSIS folks didn't add a CharAt function to their API. In case you need it to parse a string, here's a Macro that makes StrCpy work like a CharAt function [bash] ;Get a character inside a string given an index. ;Usage: CharAt String Index Output !macro\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1269,"url":"https:\/\/www.gubatron.com\/blog\/how-to-make-a-quick-dirty-hexviewer-updated\/","url_meta":{"origin":2267,"position":1},"title":"How to make a Quick &#038; Dirty HexViewer &#8211; Updated","author":"gubatron","date":"April 20, 2009","format":false,"excerpt":"After I received comments from ispak on Flickr I made a few fixes. ispak pointed out that it was a bad idea reading one byte at the time, also I had a gay ass try\/catch that didn't catch any exception :p So now I read 16 byte chunks, and I\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"HexViewer - r2","src":"https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/farm4.static.flickr.com\/3486\/3458529439_31357e0afe_o.png?resize=525%2C300 1.5x"},"classes":[]},{"id":2792,"url":"https:\/\/www.gubatron.com\/blog\/java-have-a-jtables-column-preferred-width-adjusted-to-perfectly-to-the-size-of-the-longest-string-in-the-model\/","url_meta":{"origin":2267,"position":2},"title":"Java: Have a JTable&#8217;s column preferred width adjusted perfectly to the size of the longest string in the model","author":"gubatron","date":"October 30, 2012","format":false,"excerpt":"Here's a utility method I've coded for FrostWire's partial download dialog. With it I'm able to adjust a JTable's column by iterating over the table's column model data and calculating the exact dimensions required to render the longest string found. You can specify a maximum width (to avoid some really\u2026","rel":"","context":"In \"java\"","block_context":{"text":"java","link":"https:\/\/www.gubatron.com\/blog\/tag\/java\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":4000,"url":"https:\/\/www.gubatron.com\/blog\/what-is-the-rust-equivalent-to-javas-printwriter\/","url_meta":{"origin":2267,"position":3},"title":"What is the Rust equivalent to Java&#8217;s PrintWriter?","author":"gubatron","date":"December 21, 2022","format":false,"excerpt":"In Rust, the equivalent of Java's PrintWriter is the std::io::Write trait, which is implemented by a number of types that can be used to write data to an output stream, such as a file or a network socket. To use Write to write text to an output stream, you can\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2022\/12\/progress_image_100_7fdc7b72-6c19-42f5-affe-d055d02d6f8e.webp?fit=1024%2C1024&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2022\/12\/progress_image_100_7fdc7b72-6c19-42f5-affe-d055d02d6f8e.webp?fit=1024%2C1024&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2022\/12\/progress_image_100_7fdc7b72-6c19-42f5-affe-d055d02d6f8e.webp?fit=1024%2C1024&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.gubatron.com\/blog\/wp-content\/uploads\/2022\/12\/progress_image_100_7fdc7b72-6c19-42f5-affe-d055d02d6f8e.webp?fit=1024%2C1024&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":1114,"url":"https:\/\/www.gubatron.com\/blog\/using-a-linear-array-as-a-bidimensional-matrix\/","url_meta":{"origin":2267,"position":4},"title":"Using a linear array as a bidimensional matrix","author":"gubatron","date":"January 27, 2009","format":false,"excerpt":"Often times I find the need to use a list or linear array as if it was a table. Everytime I need to do so, I always end up coding functions to convert a (x,y) coordinate to the real index n in the array. Let me illustrate, with an example.\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":764,"url":"https:\/\/www.gubatron.com\/blog\/python-ip2num-num2ip-store-an-ip-string-as-a-4-byte-int\/","url_meta":{"origin":2267,"position":5},"title":"[Python] ip2num \/ num2ip &#8211; Store an IP string as a 4 byte int.","author":"gubatron","date":"March 27, 2008","format":false,"excerpt":"This is probably everywhere, maybe python also comes with it, but I wanted to have my own implementation, and I'll leave it here for future reference. Basically, sometimes you don't want to store IPs in Strings cause they take too much space, instead you want to be a good programmer\u2026","rel":"","context":"In &quot;Code&quot;","block_context":{"text":"Code","link":"https:\/\/www.gubatron.com\/blog\/category\/code\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/2267","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/comments?post=2267"}],"version-history":[{"count":0,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/posts\/2267\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/media?parent=2267"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/categories?post=2267"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gubatron.com\/blog\/wp-json\/wp\/v2\/tags?post=2267"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}