home *** CD-ROM | disk | FTP | other *** search
/ Hackers Magazine 57 / CdHackersMagazineNr57.iso / Software / Networking / nmap-5.00-setup.exe / nselib / strbuf.lua < prev    next >
Text File  |  2009-07-06  |  5KB  |  138 lines

  1. --- String buffer facilities.
  2. --
  3. -- Lua's string operations are very flexible and offer an easy-to-use way to
  4. -- manipulate strings. Concatenation using the <code>..</code> operator is such
  5. -- an operation. The drawback of the built-in API however is the way it handles
  6. -- concatenation of many string values. Since strings in Lua are immutable
  7. -- values, each time you concatenate two strings both get copied into the
  8. -- result string.
  9. --
  10. -- The <code>strbuf</code> module offers a workaround for this problem, while
  11. -- maintaining the nice syntax. This is accomplished by overloading the
  12. -- concatenation operator (<code>..</code>), the equality operator (<code>==</code>) and the <code>tostring</code>
  13. -- operator. A string buffer is created by passing a string to
  14. -- <code>strbuf.new</code>. Afterwards you can append to the string buffer,
  15. -- or compare two string buffers for equality just as you would do with normal
  16. -- strings.
  17. --
  18. -- When looking at the details there are some more restrictions/oddities: The
  19. -- concatenation operator requires its left-hand value to be a string buffer.
  20. -- Therefore, if you want to prepend a string to a given string buffer you have
  21. -- to create a new string buffer out of the string you want to prepend. The
  22. -- string buffer's <code>tostring</code> operator concatenates the strings
  23. -- inside the buffer using newlines by default, since this appears to be the
  24. -- separator used most often.
  25. --
  26. -- Example usage:
  27. -- <code>
  28. -- local buf = strbuf.new()
  29. -- local buf2 = strbuf.new('hello')
  30. -- buf = buf .. 'string'
  31. -- buf = buf .. 'data'
  32. -- print(buf)                   -- default separator is a newline
  33. -- print(strbuf.dump(buf))      -- no separator
  34. -- print(strbuf.dump(buf, ' ')) -- separated by spaces
  35. -- strbuf.clear(buf)
  36. -- </code>
  37. -- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
  38.  
  39. -- DEPENDENCIES --
  40.  
  41. local getmetatable = getmetatable;
  42. local setmetatable = setmetatable;
  43. local type = type;
  44. local error = error;
  45. local ipairs = ipairs;
  46. local pairs = pairs;
  47. local concat = table.concat;
  48.  
  49.  
  50. module(... or "strbuf");
  51.  
  52. -- String buffer functions. Concatenation is not efficient in 
  53. -- lua as strings are immutable. If a large amount of '..' sequential
  54. -- operations are needed a string buffer should be used instead
  55. -- e.g. for i = 1, 10 do s = s..i end
  56.  
  57. --- Dumps the string buffer as a string.
  58. --
  59. -- The second parameter is used as a delimiter between the strings stored inside
  60. -- the string buffer.
  61. -- @name dump
  62. -- @class function
  63. -- @param sbuf String buffer to dump.
  64. -- @param delimiter String to separate the buffer's contents.
  65. -- @return Concatenated string result.
  66. dump = concat;
  67.  
  68. --- Appends a string to a string buffer.
  69. -- @param sbuf String buffer.
  70. -- @param s String to append.
  71. -- @return <code>sbuf</code>.
  72. function concatbuf(sbuf, s)
  73.   if type(s) == "string" then
  74.     sbuf[#sbuf+1] = s;
  75.   elseif getmetatable(s) == getmetatable(sbuf) then
  76.     for _,v in ipairs(s) do
  77.       sbuf[#sbuf+1] = v;
  78.     end
  79.   else
  80.     error("bad #2 operand to strbuf concat operation", 2);
  81.   end
  82.   return sbuf;
  83. end
  84.  
  85. --- Determines if the two string buffers are equal. Two buffers are equal
  86. -- if they are the same or if they have equivalent contents.
  87. -- @param sbuf1 String buffer one.
  88. -- @param sbuf2 String buffer two.
  89. -- @return True if equal, false otherwise.
  90. function eqbuf(sbuf1, sbuf2)
  91.   if getmetatable(sbuf1) ~= getmetatable(sbuf2) then
  92.     error("one or more operands is not a string buffer", 2);
  93.   elseif #sbuf1 ~= #sbuf2 then
  94.     return false;
  95.   else
  96.     for i = 1, #sbuf1 do
  97.       if sbuf1[i] ~= sbuf2[i] then
  98.         return false;
  99.       end
  100.     end
  101.     return true;
  102.   end
  103. end
  104.  
  105. --- Clears a string buffer.
  106. -- @param sbuf String buffer.
  107. function clear(sbuf)
  108.   for k in pairs(sbuf) do
  109.     sbuf[k] = nil;
  110.   end
  111. end
  112.  
  113. --- Returns the string buffer as a string. The delimiter used is a newline.
  114. -- @param sbuf String buffer.
  115. -- @return String made from concatenating the buffer.
  116. function tostring(sbuf)
  117.   return concat(sbuf, "\n");
  118. end
  119.  
  120. local mt = {
  121.   __concat = concatbuf,
  122.   __tostring = tostring,
  123.   __eq = eqbuf,
  124.   __index = _M,
  125. };
  126.  
  127. --- Create a new string buffer.
  128. --
  129. -- The optional arguments are added to the string buffer. The result of adding
  130. -- non-strings is undefined. The <code>equals</code> and <code>tostring</code>
  131. -- operators for string buffers are overloaded to be <code>eqbuf</code> and
  132. -- <code>tostring</code> respectively.
  133. -- @param ... Strings to add to the buffer initially.
  134. -- @return String buffer.
  135. function new(...)
  136.   return setmetatable({...}, mt);
  137. end
  138.