1 package body OWA_TEXT is
2
3 NL_CHAR constant varchar2(1) := '
4 ';
5
6 function new_multi return multi_line
7 is
8 new multi_line;
9 begin
10 new.num_rows := 0;
11 new.partial_row := FALSE;
12
13 return new;
14 end;
15
16 procedure new_multi(mline out multi_line)
17 is
18 begin
19 mline := new_multi;
20 end;
21
22 procedure stream2multi(stream in varchar2, mline out multi_line)
23 is
24 temp_multi multi_line;
25 begin
26 /* Initialize the structure */
27 temp_multi := new_multi;
28
29 if (stream is not null)
30 then
31 /* Add the new stream */
32 add2multi(stream, temp_multi, FALSE);
33 end if;
34
35 mline := temp_multi;
36 end;
37
38 procedure add2multi(stream in varchar2,
39 mline in out multi_line,
40 continue in boolean DEFAULT TRUE)
41 is
42 row_start integer;
43 row_end integer;
44
45 prev_partial boolean;
46 begin
47 /* Save the previous value of partial_row */
48 prev_partial := mline.partial_row;
49
50 /* Get the boundaries of the first row to add */
51 row_start := 1;
52 row_end := instr(stream, NL_CHAR, row_start);
53 mline.partial_row := (row_end = 0);
54
55 /* If the previous last row was incomplete, */
56 /* handle first new as a special case */
57 if ( (prev_partial = TRUE) AND (continue = TRUE) )
58 then
59 /* Check the length to avoid "PL/SQL numeric or value error" */
60 if ( (length(mline.rows(mline.num_rows)) + (row_end - row_start))
61 > 32767 ) -- MAX_VC_LEN
62 then
63 raise_application_error(-20000, 'Cannot create row larger than 32767 bytes');
64 end if;
65
66 /* Length is okay, so append it. */
67 if (mline.partial_row = TRUE)
68 then
69 mline.rows(mline.num_rows) := mline.rows(mline.num_rows) ||
70 substr(stream, row_start);
71 /* We're done, just exit */
72 return;
73 else
74 mline.rows(mline.num_rows) := mline.rows(mline.num_rows) ||
75 substr(stream, row_start, row_end - row_start);
76
77 /* Get the next chunk */
78 row_start := row_end + 1;
79 row_end := instr(stream, NL_CHAR, row_start);
80 if ( (row_end = 0) AND (row_start <= length(stream)) )
81 then
82 mline.partial_row := TRUE;
83 end if;
84 end if;
85 end if;
86
87 /* Loop through pulling out the lines */
88 while ( (row_end >= row_start) AND (mline.partial_row = FALSE) )
89 loop
90 mline.num_rows := mline.num_rows + 1;
91 mline.rows(mline.num_rows) := substr(stream, row_start,
92 row_end - row_start);
93 row_start := row_end + 1;
94 row_end := instr(stream, NL_CHAR, row_start);
95 if ( (row_end = 0) AND (row_start <= length(stream)) )
96 then
97 mline.partial_row := TRUE;
98 end if;
99 end loop;
100
101 /* Get the last line if it is partial */
102 if (mline.partial_row = TRUE)
103 then
104 mline.num_rows := mline.num_rows + 1;
105 mline.rows(mline.num_rows) := substr(stream, row_start);
106 end if;
107 end;
108
109 procedure print_multi(mline in multi_line)
110 is
111 begin
112 for i in 1..mline.num_rows
113 loop
114 htp.print(mline.rows(i));
115 end loop;
116 end;
117
118 function new_row_list return row_list
119 is
120 new row_list;
121 begin
122 new.num_rows := 0;
123 return new;
124 end;
125
126 procedure new_row_list(rlist out row_list)
127 is
128 begin
129 rlist := new_row_list;
130 end;
131
132 procedure print_row_list(rlist in row_list)
133 is
134 begin
135 for i in 1..rlist.num_rows
136 loop
137 htp.print(rlist.rows(i));
138 end loop;
139 end;
140
141 /* Just a debugging routine */
142 procedure print_debug(mline in multi_line)
143 is
144 begin
145 htp.print(mline.num_rows);
146 if mline.partial_row
147 then htp.print('PARTIAL ROW');
148 else htp.print('NO PARTIAL ROW');
149 end if;
150
151 for i in 1..mline.num_rows
152 loop
153 htp.print(mline.rows(i));
154 end loop;
155 end;
156 end;