1with 2 Ada.IO_Exceptions, 3 Ada.Strings.Fixed; 4package body CSV is 5 use Ada.Strings.Fixed; 6 7 ---------------- 8 -- Get_Bounds -- 9 ---------------- 10 11 function Get_Bounds (Item : String; Separator : Character := ',') return Fields_Bounds is 12 In_Quotes : Boolean := False; 13 begin 14 for I in Item'Range loop 15 if Item(I) = '"' then 16 In_Quotes := not In_Quotes; 17 elsif not In_Quotes and Item (I) = Separator then 18 return Bounds'(Item'First, I-1) & Get_Bounds (Item (I+1 .. Item'Last), Separator); 19 end if; 20 end loop; 21 22 return (1 => (Item'First, Item'Last)); 23 end Get_Bounds; 24 25 ------------- 26 -- Extract -- 27 ------------- 28 29 function Extract ( 30 Item : String; 31 Fields : Fields_Bounds; 32 Column : Positive; 33 Unquote: Boolean:= True 34 ) 35 return String 36 is 37 Extracted: constant String:= 38 Item( Fields(Column).Start .. Fields(Column).Stop ); 39 begin 40 if Unquote then 41 return CSV.Unquote(Extracted); 42 else 43 return Extracted; 44 end if; 45 end Extract; 46 47 ----------- 48 -- Quote -- 49 ----------- 50 51 function Quote (Item : String) return String is 52 Result : String (Item'First .. Item'Last + Count (Item, """") + 2); 53 Index : Positive; 54 begin 55 Index := Result'First; 56 Result (Index) := '"'; 57 58 for I in Item'Range loop 59 if Item (I) = '"' then 60 Index := Index + 1; 61 Result (Index) := '"'; 62 end if; 63 Index := Index + 1; 64 Result (Index) := Item (I); 65 end loop; 66 Result (Result'Last) := '"'; 67 68 return Result; 69 end Quote; 70 71 ------------- 72 -- Unquote -- 73 ------------- 74 75 function Unquote (Item : String) return String is 76 use Ada.IO_Exceptions; 77 78 Result : String(Item'Range); 79 Index_In : Positive; 80 Index_Out : Natural; 81 begin 82 if Item = "" or else Item (Item'First) /= '"' then 83 return Item; 84 end if; 85 86 Index_In := Item'First+1; 87 Index_Out := Result'First-1; 88 while Index_In <= Item'Last-1 loop 89 if Item (Index_In) = '"' then 90 Index_Out := Index_Out + 1; 91 Result (Index_Out) := '"'; 92 if Item (Index_In+1) ='"' then 93 Index_In := Index_In + 1; 94 end if; 95 else 96 Index_Out := Index_Out + 1; 97 Result (Index_Out) := Item (Index_In); 98 end if; 99 Index_In := Index_In + 1; 100 end loop; 101 102 if Item (Item'Last) /= '"' then 103 raise End_Error; 104 end if; 105 106 return Result (Result'First .. Index_Out); 107 end Unquote; 108 109 ------------- 110 -- Unquote -- 111 ------------- 112 113 function Unquote (Item : String; Slice : Bounds; Size : Natural := 0) return String is 114 use Ada.Strings; 115 Raw_Line : constant String := Unquote (Item (Slice.Start .. Slice.Stop)); 116 begin 117 if Size = 0 then 118 return Trim (Raw_Line, Both); 119 elsif Raw_Line'Length < Size then 120 return Raw_Line & (Size - Raw_Line'Length) * ' '; 121 else 122 return Raw_Line (Raw_Line'First .. Raw_Line'First + Size - 1); 123 end if; 124 end Unquote; 125 126end CSV; 127