1 | /* |
2 | * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #include "precompiled.hpp" |
26 | #include "libadt/set.hpp" |
27 | #include "memory/allocation.inline.hpp" |
28 | |
29 | // Sets - An Abstract Data Type |
30 | |
31 | #include <stdio.h> |
32 | #include <assert.h> |
33 | #include <string.h> |
34 | #include <stdlib.h> |
35 | |
36 | //-------------------------Virtual Functions----------------------------------- |
37 | // These functions MUST be implemented by the inheriting class. |
38 | class VectorSet; |
39 | const VectorSet *Set::asVectorSet() const { assert(0); return NULL; } |
40 | |
41 | //------------------------------setstr----------------------------------------- |
42 | // Create a string with a printable representation of a set. |
43 | // The caller must deallocate the string. |
44 | char *Set::setstr() const |
45 | { |
46 | if( this == NULL ) return os::strdup("{no set}" ); |
47 | Set &set = clone(); // Virtually copy the basic set. |
48 | set.Sort(); // Sort elements for in-order retrieval |
49 | |
50 | uint len = 128; // Total string space |
51 | char *buf = NEW_C_HEAP_ARRAY(char,len, mtCompiler);// Some initial string space |
52 | |
53 | char *s = buf; // Current working string pointer |
54 | *s++ = '{'; |
55 | *s = '\0'; |
56 | |
57 | // For all elements of the Set |
58 | uint hi = (uint)-2, lo = (uint)-2; |
59 | for( SetI i(&set); i.test(); ++i ) { |
60 | if( hi+1 == i.elem ) { // Moving sequentially thru range? |
61 | hi = i.elem; // Yes, just update hi end of range |
62 | } else { // Else range ended |
63 | if( buf+len-s < 25 ) { // Generous trailing space for upcoming numbers |
64 | int offset = (int)(s-buf);// Not enuf space; compute offset into buffer |
65 | len <<= 1; // Double string size |
66 | buf = REALLOC_C_HEAP_ARRAY(char,buf,len, mtCompiler); // Reallocate doubled size |
67 | s = buf+offset; // Get working pointer into new bigger buffer |
68 | } |
69 | if( lo != (uint)-2 ) { // Startup? No! Then print previous range. |
70 | if( lo != hi ) sprintf(s,"%d-%d," ,lo,hi); |
71 | else sprintf(s,"%d," ,lo); |
72 | s += strlen(s); // Advance working string |
73 | } |
74 | hi = lo = i.elem; |
75 | } |
76 | } |
77 | if( lo != (uint)-2 ) { |
78 | if( buf+len-s < 25 ) { // Generous trailing space for upcoming numbers |
79 | int offset = (int)(s-buf);// Not enuf space; compute offset into buffer |
80 | len <<= 1; // Double string size |
81 | buf = (char*)ReallocateHeap(buf,len, mtCompiler); // Reallocate doubled size |
82 | s = buf+offset; // Get working pointer into new bigger buffer |
83 | } |
84 | if( lo != hi ) sprintf(s,"%d-%d}" ,lo,hi); |
85 | else sprintf(s,"%d}" ,lo); |
86 | } else strcat(s,"}" ); |
87 | // Don't delete the clone 'set' since it is allocated on Arena. |
88 | return buf; |
89 | } |
90 | |
91 | //------------------------------print------------------------------------------ |
92 | // Handier print routine |
93 | void Set::print() const |
94 | { |
95 | char *printable_set = setstr(); |
96 | tty->print_cr("%s" , printable_set); |
97 | FreeHeap(printable_set); |
98 | } |
99 | |
100 | //------------------------------parse------------------------------------------ |
101 | // Convert a textual representation of a Set, to a Set and union into "this" |
102 | // Set. Return the amount of text parsed in "len", or zero in "len". |
103 | int Set::parse(const char *s) |
104 | { |
105 | char c; // Parse character |
106 | const char *t = s; // Save the starting position of s. |
107 | do c = *s++; // Skip characters |
108 | while( c && (c <= ' ') ); // Till no more whitespace or EOS |
109 | if( c != '{' ) return 0; // Oops, not a Set openner |
110 | if( *s == '}' ) return 2; // The empty Set |
111 | |
112 | // Sets are filled with values of the form "xx," or "xx-yy," with the comma |
113 | // a "}" at the very end. |
114 | while( 1 ) { // While have elements in the Set |
115 | char *u; // Pointer to character ending parse |
116 | uint hi, i; // Needed for range handling below |
117 | uint elem = (uint)strtoul(s,&u,10);// Get element |
118 | if( u == s ) return 0; // Bogus crude |
119 | s = u; // Skip over the number |
120 | c = *s++; // Get the number seperator |
121 | switch ( c ) { // Different seperators |
122 | case '}': // Last simple element |
123 | case ',': // Simple element |
124 | (*this) <<= elem; // Insert the simple element into the Set |
125 | break; // Go get next element |
126 | case '-': // Range |
127 | hi = (uint)strtoul(s,&u,10); // Get element |
128 | if( u == s ) return 0; // Bogus crude |
129 | for( i=elem; i<=hi; i++ ) |
130 | (*this) <<= i; // Insert the entire range into the Set |
131 | s = u; // Skip over the number |
132 | c = *s++; // Get the number seperator |
133 | break; |
134 | } |
135 | if( c == '}' ) break; // End of the Set |
136 | if( c != ',' ) return 0; // Bogus garbage |
137 | } |
138 | return (int)(s-t); // Return length parsed |
139 | } |
140 | |
141 | //------------------------------Iterator--------------------------------------- |
142 | SetI_::~SetI_() |
143 | { |
144 | } |
145 | |