list to record

These are two different routines to convert a list of strings into a record, where odd members of the list are the keys and even ones the values (eg, {“a”,“b”} → {a:“b”}).
The first one is the “official” way to do it.
The second one writes the record in raw form to a file, which is then “read as record”. There is a peculiarity: it can return several keys with the same identifier name (eg, {a:“b”, a:“c”, a:“d”}), though you can only access the first one.

OS version: Any

(*

These two handlers should return the same result. You provide them a list of strings and it returns a record where odd members are the key and even ones the value.

listToRecord is much faster than listToRecord2, which is kept as a funny exercice of assembling.

Wrong! listToRecord2 has a peculiarity. Using this handler, you can create a record where several keys have the same name/identifier. Eg:

listToRecord({"a","b","a","c"}) --> {a:"b"}
--> against
listToRecord2({"a","b","a","c"}) --> {a:"b", a:"c"}

Of course, when you access this kind of record, the only valid key is the first coincidence of such key:

a of listToRecord2({"a","b","a","c"}) --> "b"

Enjoy!

*)

--> SAMPLE USAGE:

listToRecord({"kaka", "pepe", "lois", "kent"}) --> {kaka:"pepe", lois:"kent"}

listToRecord2({"kaka", "pepe", "lois", "kent", "kaka", "poof"}) --> {kaka:"pepe", lois:"kent", kaka:"poof"}

to listToRecord(theList)
	script blank
		property x : theList
	end script
	set theRec to {"{"}
	repeat with i from 1 to (count theList) by 2
		set theRec's end to (blank's x's item i & ": \"" & blank's x's item (i + 1) & "\"" & ",")
	end repeat
	set theRec to text 1 thru -2 of (theRec as text) & "}"
	run script theRec
end listToRecord

to listToRecord2(theList)
	script blank
		property x : theList
		property head : "reco" & (ASCII character 0) & (ASCII character 0) & (ASCII character 0) & (ASCII character 1) & "usrflist"
		property tmp : "/tmp/f" as POSIX file
		property hexchars : "0123456789ABCDEF"
		
		to getASCII()
			set a to {}
			repeat with i from 0 to 255
				set a's end to ASCII character i
			end repeat
			a as text
		end getASCII
		
		on hextoString(theText)
			script blank
				property x : theText
				property ascii : getASCII()
				property hexStuff : "00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F  10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F  20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F  30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F  40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F  50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F  60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F  70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F  80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F  90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F  A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF  B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF  C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF  D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF  E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF  F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF  "
			end script
			set str to {}
			repeat with i from 1 to (count theText) by 2
				set z to ((offset of (text i thru (i + 1) of blank's x & "  ") in blank's hexStuff) + 3) / 4
				set str's end to blank's ascii's item z
			end repeat
			str as text
		end hextoString
		to DecToHex4Byte(n)
			set hexNumber to {}
			repeat
				set beginning of hexNumber to hexchars's item ((n mod 16) + 1)
				set n to n div 16
				if n = 0 then exit repeat
			end repeat
			return text -8 thru -1 of ("00000000" & hexNumber)
		end DecToHex4Byte
	end script
	
	set theRec to {blank's head}
	set end of theRec to blank's hextoString(blank's DecToHex4Byte(count theList)) --> suma de keys + values
	
	--> meter los datos
	repeat with i from 1 to (count theList) by 2
		set keyLength to count blank's x's item i
		
		set valueLength to count blank's x's item (i + 1)
		
		set theRec's end to "TEXT" --> marca de la key
		set theRec's end to blank's hextoString(blank's DecToHex4Byte(keyLength)) --> longitud de la key
		set theRec's end to blank's x's item i --> añadir la key
		if (keyLength mod 2) is not 0 then set end of theRec to ASCII character 0 --> añadir 1 ascii 0 (si acaso) para que sean bytes pares
		
		set theRec's end to "TEXT" --> marca del value
		set theRec's end to blank's hextoString(blank's DecToHex4Byte(valueLength)) --> longitud de la key
		set theRec's end to blank's x's item (i + 1) --> añadir la key
		if (valueLength mod 2) is not 0 then set end of theRec to ASCII character 0 --> añadir 1 ascii 0 (si acaso) para que sean bytes pares
	end repeat
	
	--> escribir los datos a fichero temporal
	try
		set k to open for access blank's tmp with write permission
		set eof of k to 0
		write (theRec as text) to k
		close access k
	on error msg
		try
			close access k
		end try
		error msg
	end try
	read blank's tmp as record
end listToRecord2

property |version| : 1.0
property author : "Pescados Software · PescadosWeb.com"
property |date| : date "martes, 8 junio 2004 16:26:35"
property license : "freeware, open-source"